diff --git a/Changelog.md b/Changelog.md index 05cf2744..950ad30d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ - Added: Filter function to Iterators/Iterables (Iterable implements it by default) - Changed: Cleanup of some variables/mappers - Added/Fixed: AVL/RBTreeMap got reworked and SubMaps work more properly now. Also forEach support got improved a lot +- Added/Fixed: TreeSubSets (RB/AVL) got their functional implementations improved too. ### Version 0.3.6 - Fixed: addAll non Type Specific Lists was causing crashes. diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template index 1bc07182..6def463a 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template @@ -747,6 +747,9 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE return new DescendingSubSetBRACES(set, fromStart, start, loInclusive, false, fromElement, inclusive); } + protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.previous(); } + protected Entry KEY_GENERIC_TYPE start() { return findHighest(); } + @Override public KEY_TYPE FIRST_KEY() { return super.LAST_KEY(); } @@ -852,6 +855,8 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE boolean inRange(KEY_TYPE key) { return !tooLow(key) && !tooHigh(key); } boolean inClosedRange(KEY_TYPE key) { return (fromStart || set.compare(key, start) >= 0) && (toEnd || set.compare(end, key) >= 0); } boolean inRange(KEY_TYPE key, boolean inclusive) { return inclusive ? inRange(key) : inClosedRange(key); } + protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.next(); } + protected Entry KEY_GENERIC_TYPE start() { return findLowest(); } @Override public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } @@ -994,6 +999,57 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE return fromStart && toEnd ? set.size() : iterator().skip(Integer.MAX_VALUE); } + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + action.accept(entry.key); + } + } + + @Override + public void forEach(E input, BI_OBJECT_CONSUMER KKS_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) + action.accept(entry.key, input); + } + + @Override + public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return true; + } + return false; + } + + @Override + public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return false; + } + return true; + } + + @Override + public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(!filter.TEST_VALUE(entry.key)) return false; + } + return true; + } + + @Override + public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return entry.key; + } + return EMPTY_VALUE; + } + class SubSetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE previous; diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template index 9fd8819f..315e742b 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template @@ -808,6 +808,9 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE return new DescendingSubSetBRACES(set, fromStart, start, loInclusive, false, fromElement, inclusive); } + protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.previous(); } + protected Entry KEY_GENERIC_TYPE start() { return findHighest(); } + @Override public KEY_TYPE FIRST_KEY() { return super.LAST_KEY(); } @@ -913,6 +916,8 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE boolean inRange(KEY_TYPE key) { return !tooLow(key) && !tooHigh(key); } boolean inClosedRange(KEY_TYPE key) { return (fromStart || set.compare(key, start) >= 0) && (toEnd || set.compare(end, key) >= 0); } boolean inRange(KEY_TYPE key, boolean inclusive) { return inclusive ? inRange(key) : inClosedRange(key); } + protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.next(); } + protected Entry KEY_GENERIC_TYPE start() { return findLowest(); } @Override public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } @@ -1055,6 +1060,57 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE return fromStart && toEnd ? set.size() : iterator().skip(Integer.MAX_VALUE); } + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + action.accept(entry.key); + } + } + + @Override + public void forEach(E input, BI_OBJECT_CONSUMER KKS_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) + action.accept(entry.key, input); + } + + @Override + public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return true; + } + return false; + } + + @Override + public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return false; + } + return true; + } + + @Override + public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(!filter.TEST_VALUE(entry.key)) return false; + } + return true; + } + + @Override + public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { + Objects.requireNonNull(filter); + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + if(filter.TEST_VALUE(entry.key)) return entry.key; + } + return EMPTY_VALUE; + } + class SubSetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE previous;