From a26106cc89ff569e3a69ba14f293e8db9a2240ee Mon Sep 17 00:00:00 2001 From: Speiger Date: Sun, 10 May 2026 22:00:55 +0200 Subject: [PATCH] Fixed a bunch of Iterator code and implemented Reverse Map/Set Tests --- .classpath | 2 +- .../maps/abstracts/AbstractMap.template | 10 ++- .../LinkedOpenCustomHashMap.template | 33 +++++--- .../maps/impl/hash/LinkedOpenHashMap.template | 32 +++++--- .../immutable/ImmutableOpenHashMap.template | 32 +++++--- .../maps/impl/misc/ArrayMap.template | 51 ++++++++---- .../templates/sets/ArraySet.template | 50 ++++++++---- .../sets/ImmutableOpenHashSet.template | 59 ++++++++++---- .../sets/LinkedOpenCustomHashSet.template | 59 ++++++++++---- .../templates/sets/LinkedOpenHashSet.template | 59 ++++++++++---- .../OrderedSetTestSuiteBuilder.template | 77 +++++++++++++++++++ .../builder/maps/MapTestSuiteBuilder.template | 75 ++++++++---------- .../maps/OrderedMapTestSuiteBuilder.template | 10 +-- .../impl/maps/DerivedMapGenerators.template | 22 ++---- .../src/testers/utils/SpecialFeature.java | 1 + 15 files changed, 392 insertions(+), 180 deletions(-) diff --git a/.classpath b/.classpath index 6eb9ad0..8d2daaf 100644 --- a/.classpath +++ b/.classpath @@ -32,7 +32,7 @@ - + diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template index 32aab8d..91fb553 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template @@ -51,7 +51,7 @@ import speiger.src.collections.utils.SanityChecks; */ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap implements MAP KEY_VALUE_GENERIC_TYPE { - protected VALUE_TYPE defaultReturnValue = EMPTY_VALUE; + protected VALUE_TYPE defaultReturnValue = INVALID_VALUE; @Override public VALUE_TYPE getDefaultReturnValue() { @@ -558,7 +558,13 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap reverseIterator() { - return new ReverseBiIterator<>(new EntryIterator(false)); + return new EntryIterator(false); } @Override @@ -1023,7 +1023,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new KeyIterator(false)); + return new KeyIterator(false); } @Override @@ -1224,7 +1224,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M @Override public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() { - return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); + return new ValueIterator(false); } @Override public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } @@ -1490,17 +1490,20 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M } private class MapIterator { + boolean forward; int previous = -1; int next = -1; int current = -1; int index = 0; MapIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } MapIterator(KEY_TYPE from) { + this.forward = true; if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(containsNull) { next = (int) links[nullIndex]; @@ -1528,11 +1531,11 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M } public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } public int nextIndex() { @@ -1592,20 +1595,30 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M public int previousEntry() { if(!hasPrevious()) throw new NoSuchElementException(); - current = previous; - previous = (int)(links[current] >> 32); - next = current; + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return current; } public int nextEntry() { if(!hasNext()) throw new NoSuchElementException(); + if(forward) moveForwards(); + else moveBackwards(); + if(index >= 0) index++; + return current; + } + + private void moveBackwards() { + current = previous; + previous = (int)(links[current] >> 32); + next = current; + } + + private void moveForwards() { current = next; next = (int)(links[current]); previous = current; - if(index >= 0) index++; - return current; } private void ensureIndexKnown() { diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/LinkedOpenHashMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/LinkedOpenHashMap.template index 993a1e3..3ac8a24 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/LinkedOpenHashMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/LinkedOpenHashMap.template @@ -758,7 +758,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G @Override public ObjectBidirectionalIterator reverseIterator() { - return new ReverseBiIterator<>(new EntryIterator(false)); + return new EntryIterator(false); } @Override @@ -1022,7 +1022,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new KeyIterator(false)); + return new KeyIterator(false); } @Override @@ -1225,7 +1225,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G @Override public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() { - return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); + return new ValueIterator(false); } @Override public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } @@ -1490,12 +1490,14 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G } private class MapIterator { + boolean forward; int previous = -1; int next = -1; int current = -1; int index = 0; MapIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } @@ -1528,11 +1530,11 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G } public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } public int nextIndex() { @@ -1592,20 +1594,30 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G public int previousEntry() { if(!hasPrevious()) throw new NoSuchElementException(); - current = previous; - previous = (int)(links[current] >> 32); - next = current; + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return current; } public int nextEntry() { if(!hasNext()) throw new NoSuchElementException(); + if(forward) moveForwards(); + else moveBackwards(); + if(index >= 0) index++; + return current; + } + + private void moveBackwards() { + current = previous; + previous = (int)(links[current] >> 32); + next = current; + } + + private void moveForwards() { current = next; next = (int)(links[current]); previous = current; - if(index >= 0) index++; - return current; } private void ensureIndexKnown() { diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/immutable/ImmutableOpenHashMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/immutable/ImmutableOpenHashMap.template index b2aef2c..3434913 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/immutable/ImmutableOpenHashMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/immutable/ImmutableOpenHashMap.template @@ -664,7 +664,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ @Override public ObjectBidirectionalIterator reverseIterator() { - return new ReverseBiIterator<>(new EntryIterator(false)); + return new EntryIterator(false); } @Override @@ -906,7 +906,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new KeyIterator(false)); + return new KeyIterator(false); } @Override @@ -1103,7 +1103,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ @Override public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() { - return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); + return new ValueIterator(false); } @Override public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } @@ -1356,12 +1356,14 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ } private class MapIterator { + boolean forward; int previous = -1; int next = -1; int current = -1; int index = 0; MapIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } @@ -1394,11 +1396,11 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ } public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } public int nextIndex() { @@ -1415,20 +1417,30 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_ public int previousEntry() { if(!hasPrevious()) throw new NoSuchElementException(); - current = previous; - previous = (int)(links[current] >> 32); - next = current; + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return current; } public int nextEntry() { if(!hasNext()) throw new NoSuchElementException(); + if(forward) moveForwards(); + else moveBackwards(); + if(index >= 0) index++; + return current; + } + + private void moveBackwards() { + current = previous; + previous = (int)(links[current] >> 32); + next = current; + } + + private void moveForwards() { current = next; next = (int)(links[current]); previous = current; - if(index >= 0) index++; - return current; } private void ensureIndexKnown() { diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/ArrayMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/ArrayMap.template index f340cbe..6a678b4 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/ArrayMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/ArrayMap.template @@ -907,7 +907,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN @Override public ObjectBidirectionalIterator reverseIterator() { - return new ReverseBiIterator<>(new EntryIterator(false)); + return new EntryIterator(false); } @Override @@ -1129,7 +1129,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN @Override public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { return new KeyIterator(true); } @Override - public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { return new ReverseBiIteratorBRACES(new KeyIterator(false)); } + public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { return new KeyIterator(false); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); } @Override @@ -1274,7 +1274,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN @Override public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() { - return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); + return new ValueIterator(false); } @Override public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } @@ -1491,32 +1491,37 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN } private class MapIterator { + boolean forward; int index; int lastReturned = -1; MapIterator(boolean start) { + this.forward = start; this.index = start ? 0 : size; } MapIterator(KEY_TYPE element) { + this.forward = true; index = findIndex(element); if(index == -1) throw new NoSuchElementException(); } public boolean hasNext() { - return index < size; + return forward ? index < size : index > 0; } public boolean hasPrevious() { - return index > 0; + return forward ? index > 0 : index < size; } public int nextIndex() { - return index; + if(forward) return index; + return size - index; } public int previousIndex() { - return index-1; + if(forward) return index-1; + return (size - index)-1; } public void remove() { @@ -1529,26 +1534,42 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN public int previousEntry() { if(!hasPrevious()) throw new NoSuchElementException(); - index--; - return (lastReturned = index); - } - - public int nextEntry() { - if(!hasNext()) throw new NoSuchElementException(); + if(forward) { + index--; + return (lastReturned = index); + } lastReturned = index; return index++; } + public int nextEntry() { + if(!hasNext()) throw new NoSuchElementException(); + if(forward) { + lastReturned = index; + return index++; + } + index--; + return (lastReturned = index); + } + public int skip(int amount) { if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + return forward ? moveForward(amount) : moveBackwards(amount); + } + + public int back(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + return forward ? moveBackwards(amount) : moveForward(amount); + } + + private int moveForward(int amount) { int steps = Math.min(amount, size() - index); index += steps; if(steps > 0) lastReturned = Math.min(index-1, size()-1); return steps; } - public int back(int amount) { - if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + private int moveBackwards(int amount) { int steps = Math.min(amount, index); index -= steps; if(steps > 0) lastReturned = Math.min(index, size()-1); diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/ArraySet.template b/src/builder/resources/speiger/assets/collections/templates/sets/ArraySet.template index eab53f1..bcffc7f 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/ArraySet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/ArraySet.template @@ -511,18 +511,18 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator() { - return new SetIterator(0); + return new SetIterator(true, 0); } @Override public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new SetIterator(size)); + return new SetIterator(false, size); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { int index = findIndex(fromElement); - if(index != -1) return new SetIterator(index); + if(index != -1) return new SetIterator(true, index); throw new NoSuchElementException(); } @@ -575,45 +575,57 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im } private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + boolean forward; int index; int lastReturned = -1; - public SetIterator(int index) { + public SetIterator(boolean forward, int index) { + this.forward = forward; this.index = index; } @Override public boolean hasNext() { - return index < size(); + return forward ? index < size() : index > 0; } @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); - lastReturned = index; - return data[index++]; + if(forward) { + lastReturned = index; + return data[index++]; + } + index--; + return data[(lastReturned = index)]; } @Override public boolean hasPrevious() { - return index > 0; + return forward ? index > 0 : index < size(); } @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); - --index; - return data[(lastReturned = index)]; + if(forward) { + index--; + return data[(lastReturned = index)]; + } + lastReturned = index; + return data[index++]; } @Override public int nextIndex() { - return index; + if(forward) return index; + return size - index; } @Override public int previousIndex() { - return index-1; + if(forward) return index-1; + return (size - index)-1; } @Override @@ -642,15 +654,23 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im @Override public int skip(int amount) { if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + return forward ? moveForward(amount) : moveBackwards(amount); + } + + @Override + public int back(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + return forward ? moveBackwards(amount) : moveForward(amount); + } + + private int moveForward(int amount) { int steps = Math.min(amount, size() - index); index += steps; if(steps > 0) lastReturned = Math.min(index-1, size()-1); return steps; } - @Override - public int back(int amount) { - if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + private int moveBackwards(int amount) { int steps = Math.min(amount, index); index -= steps; if(steps > 0) lastReturned = Math.min(index, size()-1); diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/ImmutableOpenHashSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/ImmutableOpenHashSet.template index 7ccc55f..73f00a8 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/ImmutableOpenHashSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/ImmutableOpenHashSet.template @@ -460,7 +460,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new SetIterator(false)); + return new SetIterator(false); } @Override @@ -526,17 +526,20 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI } private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + boolean forward; int previous = -1; int next = -1; int current = -1; - int index = 0; + int index = -1; SetIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } SetIterator(KEY_TYPE from) { + this.forward = true; if(KEY_EQUALS_NULL(from)) { if(containsNull) { next = (int) links[nullIndex]; @@ -565,48 +568,60 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI @Override public int skip(int amount) { - int result = 0; - while(next != -1 && result != amount) { - current = previous = next; - next = (int)(links[current]); - result++; - } + int result = forward ? moveForward(amount) : moveBackwards(amount); if(index >= 0) index+=result; return result; } @Override public int back(int amount) { + int result = forward ? moveBackwards(amount) : moveForward(amount); + if(index >= 0) index-=result; + return result; + } + + private int moveForward(int amount) { + int result = 0; + while(next != -1 && result != amount) { + current = previous = next; + next = (int)(links[current]); + result++; + } + return result; + } + + private int moveBackwards(int amount) { int result = 0; while(previous != -1 && result != amount) { current = next = previous; previous = (int)(links[current] >> 32); result++; } - if(index >= 0) index-=result; return result; } @Override public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } @Override public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } @Override public int nextIndex() { ensureIndexKnown(); - return index; + if(forward) return index; + return size - index; } @Override public int previousIndex() { ensureIndexKnown(); - return index - 1; + if(forward) return index-1; + return (size - index)-1; } @Override @@ -615,8 +630,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); - current = next = previous; - previous = (int)(links[current] >> 32); + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return keys[current]; } @@ -624,12 +639,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); - current = previous = next; - next = (int)(links[current]); + if(forward) moveForwards(); + else moveBackwards(); if(index >= 0) index++; return keys[current]; } + private void moveBackwards() { + current = next = previous; + previous = (int)(links[current] >> 32); + } + + private void moveForwards() { + current = previous = next; + next = (int)(links[current]); + } + private void ensureIndexKnown() { if(index == -1) { if(previous == -1) { diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenCustomHashSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenCustomHashSet.template index 2d32083..90876dd 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenCustomHashSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenCustomHashSet.template @@ -702,7 +702,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new SetIterator(false)); + return new SetIterator(false); } @Override @@ -727,17 +727,20 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY } private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + boolean forward; int previous = -1; int next = -1; int current = -1; - int index = 0; + int index = -1; SetIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } SetIterator(KEY_TYPE from) { + this.forward = true; if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(containsNull) { next = (int) links[nullIndex]; @@ -766,48 +769,60 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY @Override public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } @Override public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } @Override public int skip(int amount) { - int result = 0; - while(next != -1 && result != amount) { - current = previous = next; - next = (int)(links[current]); - result++; - } + int result = forward ? moveForward(amount) : moveBackwards(amount); if(index >= 0) index+=result; return result; } @Override public int back(int amount) { + int result = forward ? moveBackwards(amount) : moveForward(amount); + if(index >= 0) index-=result; + return result; + } + + private int moveForward(int amount) { + int result = 0; + while(next != -1 && result != amount) { + current = previous = next; + next = (int)(links[current]); + result++; + } + return result; + } + + private int moveBackwards(int amount) { int result = 0; while(previous != -1 && result != amount) { current = next = previous; previous = (int)(links[current] >> 32); result++; } - if(index >= 0) index-=result; return result; } @Override public int nextIndex() { ensureIndexKnown(); - return index; + if(forward) return index; + return size - index; } @Override public int previousIndex() { ensureIndexKnown(); - return index - 1; + if(forward) return index-1; + return (size - index)-1; } @Override @@ -856,8 +871,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); - current = next = previous; - previous = (int)(links[current] >> 32); + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return keys[current]; } @@ -865,12 +880,22 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); - current = previous = next; - next = (int)(links[current]); + if(forward) moveForwards(); + else moveBackwards(); if(index >= 0) index++; return keys[current]; } + private void moveBackwards() { + current = next = previous; + previous = (int)(links[current] >> 32); + } + + private void moveForwards() { + current = previous = next; + next = (int)(links[current]); + } + private void ensureIndexKnown() { if(index == -1) { if(previous == -1) { diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenHashSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenHashSet.template index 0cfb36f..ff8c356 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenHashSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/LinkedOpenHashSet.template @@ -673,7 +673,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE @Override public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { - return new ReverseBiIteratorBRACES(new SetIterator(false)); + return new SetIterator(false); } @Override @@ -698,17 +698,20 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE } private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + boolean forward; int previous = -1; int next = -1; int current = -1; - int index = 0; + int index = -1; SetIterator(boolean start) { + this.forward = start; if(start) next = firstIndex; else previous = lastIndex; } SetIterator(KEY_TYPE from) { + this.forward = true; if(KEY_EQUALS_NULL(from)) { if(containsNull) { next = (int) links[nullIndex]; @@ -737,48 +740,60 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE @Override public int skip(int amount) { - int result = 0; - while(next != -1 && result != amount) { - current = previous = next; - next = (int)(links[current]); - result++; - } + int result = forward ? moveForward(amount) : moveBackwards(amount); if(index >= 0) index+=result; return result; } @Override public int back(int amount) { + int result = forward ? moveBackwards(amount) : moveForward(amount); + if(index >= 0) index-=result; + return result; + } + + private int moveForward(int amount) { + int result = 0; + while(next != -1 && result != amount) { + current = previous = next; + next = (int)(links[current]); + result++; + } + return result; + } + + private int moveBackwards(int amount) { int result = 0; while(previous != -1 && result != amount) { current = next = previous; previous = (int)(links[current] >> 32); result++; } - if(index >= 0) index-=result; return result; } @Override public boolean hasNext() { - return next != -1; + return (forward ? next : previous) != -1; } @Override public boolean hasPrevious() { - return previous != -1; + return (forward ? previous : next) != -1; } @Override public int nextIndex() { ensureIndexKnown(); - return index; + if(forward) return index; + return size - index; } @Override public int previousIndex() { ensureIndexKnown(); - return index - 1; + if(forward) return index-1; + return (size - index)-1; } @Override @@ -827,8 +842,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); - current = next = previous; - previous = (int)(links[current] >> 32); + if(forward) moveBackwards(); + else moveForwards(); if(index >= 0) index--; return keys[current]; } @@ -836,12 +851,22 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); - current = previous = next; - next = (int)(links[current]); + if(forward) moveForwards(); + else moveBackwards(); if(index >= 0) index++; return keys[current]; } + private void moveBackwards() { + current = next = previous; + previous = (int)(links[current] >> 32); + } + + private void moveForwards() { + current = previous = next; + next = (int)(links[current]); + } + private void ensureIndexKnown() { if(index == -1) { if(previous == -1) { diff --git a/src/builder/resources/speiger/assets/testers/templates/builder/OrderedSetTestSuiteBuilder.template b/src/builder/resources/speiger/assets/testers/templates/builder/OrderedSetTestSuiteBuilder.template index 247eba5..d2bbdfd 100644 --- a/src/builder/resources/speiger/assets/testers/templates/builder/OrderedSetTestSuiteBuilder.template +++ b/src/builder/resources/speiger/assets/testers/templates/builder/OrderedSetTestSuiteBuilder.template @@ -1,16 +1,29 @@ package speiger.src.testers.PACKAGE.builder; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import com.google.common.collect.testing.AbstractTester; +import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder; import com.google.common.collect.testing.Helpers; +import com.google.common.collect.testing.OneSizeTestContainerGenerator; +import com.google.common.collect.testing.SampleElements; import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.Feature; import junit.framework.TestSuite; +import speiger.src.collections.PACKAGE.collections.ITERABLE; +import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; +import speiger.src.collections.PACKAGE.lists.LIST; +import speiger.src.collections.PACKAGE.sets.ORDERED_SET; +import speiger.src.collections.PACKAGE.utils.LISTS; import speiger.src.testers.PACKAGE.generators.TEST_ORDERED_SET_GENERATOR; import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetMoveTester; import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetIterationTester; import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetNavigationTester; +import speiger.src.testers.PACKAGE.utils.SAMPLE_ELEMENTS; +import speiger.src.testers.utils.SpecialFeature; @SuppressWarnings("javadoc") public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER KEY_GENERIC_TYPE { @@ -35,4 +48,68 @@ public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER #endignore return super.createTestSuite(); } + + @Override + protected List createDerivedSuites( + FeatureSpecificTestSuiteBuilder, CLASS_TYPE>> parentBuilder) { + List derivedSuites = super.createDerivedSuites(parentBuilder); + + if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) { + derivedSuites.add(createReverseSuite(parentBuilder)); + } + + return derivedSuites; + } + + private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder, CLASS_TYPE>> parentBuilder) { + TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE delegate = (TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator(); + + List> features = new ArrayList<>(); + features.add(SpecialFeature.REVERSE); + features.addAll(parentBuilder.getFeatures()); + features.remove(SpecialFeature.COPYING); + features.remove(SpecialFeature.CHILDREN_COPY); + + return ORDERED_SET_TEST_BUILDER.using(new TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE() { + @Override + public SampleElements samples() { + return delegate.samples(); + } + + @Override + public SAMPLE_ELEMENTS KEY_GENERIC_TYPE getSamples() { + return delegate.getSamples(); + } + + @Override + public ITERABLE KEY_GENERIC_TYPE order(LIST KEY_GENERIC_TYPE insertionOrder) { + return insertionOrder; + } + + @Override + public Iterable order(List insertionOrder) { + return insertionOrder; + } + +#if !TYPE_OBJECT + @Override + public ORDERED_SET KEY_GENERIC_TYPE create(KEY_TYPE... elements) { + LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(elements); + LISTS.reverse(list); + return delegate.create(list.TO_ARRAY()).reversed(); + } + +#endif + @Override + public ORDERED_SET KEY_GENERIC_TYPE create(Object... elements) { + LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + for (Object e : elements) { + list.add(CLASS_TO_KEY(e)); + } + LISTS.reverse(list); + return delegate.create(list.toArray()).reversed(); + } + }).named(parentBuilder.getName() + " reversing").withFeatures(features) + .suppressing(parentBuilder.getSuppressedTests()).createTestSuite(); + } } diff --git a/src/builder/resources/speiger/assets/testers/templates/builder/maps/MapTestSuiteBuilder.template b/src/builder/resources/speiger/assets/testers/templates/builder/maps/MapTestSuiteBuilder.template index 74ea9fb..9b6bcec 100644 --- a/src/builder/resources/speiger/assets/testers/templates/builder/maps/MapTestSuiteBuilder.template +++ b/src/builder/resources/speiger/assets/testers/templates/builder/maps/MapTestSuiteBuilder.template @@ -238,21 +238,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder private static Set> computeEntrySetFeatures(Set> mapFeatures) { Set> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); #ignore - if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) { - entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); - } - if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) { - entrySetFeatures.add(SpecialFeature.COPYING); - } - else { - entrySetFeatures.remove(SpecialFeature.COPYING); - } - if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) { - entrySetFeatures.add(SpecialFeature.MODIFIABLE); - } - else { - entrySetFeatures.remove(SpecialFeature.MODIFIABLE); - } + if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); + + if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) entrySetFeatures.add(SpecialFeature.COPYING); + else entrySetFeatures.remove(SpecialFeature.COPYING); + + if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) entrySetFeatures.add(SpecialFeature.MODIFIABLE); + else entrySetFeatures.remove(SpecialFeature.MODIFIABLE); + + if(mapFeatures.contains(SpecialFeature.REVERSE)) entrySetFeatures.add(SpecialFeature.REVERSE); + else entrySetFeatures.remove(SpecialFeature.REVERSE); + entrySetFeatures.add(SpecialFeature.MAP_ENTRY); #endignore return entrySetFeatures; @@ -262,23 +258,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder Set> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); #ignore keySetFeatures.add(CollectionFeature.SUBSET_VIEW); - if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) { - keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); - } else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) { - keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); - } - if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) { - keySetFeatures.add(SpecialFeature.COPYING); - } - else { - keySetFeatures.remove(SpecialFeature.COPYING); - } - if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) { - keySetFeatures.add(SpecialFeature.MODIFIABLE); - } - else { - keySetFeatures.remove(SpecialFeature.MODIFIABLE); - } + if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); + else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); + + if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) keySetFeatures.add(SpecialFeature.COPYING); + else keySetFeatures.remove(SpecialFeature.COPYING); + + if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) keySetFeatures.add(SpecialFeature.MODIFIABLE); + else keySetFeatures.remove(SpecialFeature.MODIFIABLE); + + if(mapFeatures.contains(SpecialFeature.REVERSE)) keySetFeatures.add(SpecialFeature.REVERSE); + else keySetFeatures.remove(SpecialFeature.REVERSE); #endignore return keySetFeatures; } @@ -287,18 +277,15 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder private static Set> computeValuesCollectionFeatures(Set> mapFeatures) { Set> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); #ignore - if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) { - valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); - } - if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) { - valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); - } - if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) { - valuesCollectionFeatures.add(SpecialFeature.COPYING); - } - else { - valuesCollectionFeatures.remove(SpecialFeature.COPYING); - } + if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES); + + if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); + + if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) valuesCollectionFeatures.add(SpecialFeature.COPYING); + else valuesCollectionFeatures.remove(SpecialFeature.COPYING); + + if(mapFeatures.contains(SpecialFeature.REVERSE)) valuesCollectionFeatures.add(SpecialFeature.REVERSE); + else valuesCollectionFeatures.remove(SpecialFeature.REVERSE); #endignore return valuesCollectionFeatures; } diff --git a/src/builder/resources/speiger/assets/testers/templates/builder/maps/OrderedMapTestSuiteBuilder.template b/src/builder/resources/speiger/assets/testers/templates/builder/maps/OrderedMapTestSuiteBuilder.template index 9b052ca..5568ad5 100644 --- a/src/builder/resources/speiger/assets/testers/templates/builder/maps/OrderedMapTestSuiteBuilder.template +++ b/src/builder/resources/speiger/assets/testers/templates/builder/maps/OrderedMapTestSuiteBuilder.template @@ -55,8 +55,8 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU @Override protected List createDerivedSuites(FeatureSpecificTestSuiteBuilder, Map.Entry>> parentBuilder) { List derivedSuites = super.createDerivedSuites(parentBuilder); - if (!parentBuilder.getFeatures().contains(SpecialFeature.DESCENDING)) { - derivedSuites.add(createDescendingSuite(parentBuilder)); + if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) { + derivedSuites.add(createReverseSuite(parentBuilder)); } return derivedSuites; } @@ -69,15 +69,15 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU return ORDERED_SET_TEST_BUILDER.using((TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE)generator); } - private TestSuite createDescendingSuite(FeatureSpecificTestSuiteBuilder, Map.Entry>> parentBuilder) { + private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder, Map.Entry>> parentBuilder) { TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE delegate = (TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator(); List> features = new ArrayList<>(); - features.add(SpecialFeature.DESCENDING); + features.add(SpecialFeature.REVERSE); features.addAll(parentBuilder.getFeatures()); features.remove(SpecialFeature.COPYING); features.remove(SpecialFeature.CHILDREN_COPY); - return ORDERED_MAP_TEST_BUILDER.using(new DERIVED_MAP_GENERATORS.DescendingTestOrderedMapGeneratorKV_BRACES(delegate)) + return ORDERED_MAP_TEST_BUILDER.using(new DERIVED_MAP_GENERATORS.ReverseTestOrderedMapGenerator(delegate)) .named(parentBuilder.getName() + " reversed").withFeatures(features) .suppressing(parentBuilder.getSuppressedTests()).createTestSuite(); } diff --git a/src/builder/resources/speiger/assets/testers/templates/impl/maps/DerivedMapGenerators.template b/src/builder/resources/speiger/assets/testers/templates/impl/maps/DerivedMapGenerators.template index bee25b4..505d96e 100644 --- a/src/builder/resources/speiger/assets/testers/templates/impl/maps/DerivedMapGenerators.template +++ b/src/builder/resources/speiger/assets/testers/templates/impl/maps/DerivedMapGenerators.template @@ -207,31 +207,19 @@ public class DERIVED_MAP_GENERATORS { } } - public static class DescendingTestOrderedMapGenerator KEY_VALUE_GENERIC_TYPE extends MapGenerator KEY_VALUE_GENERIC_TYPE implements TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE { + public static class ReverseTestOrderedMapGenerator KEY_VALUE_GENERIC_TYPE extends MapGenerator KEY_VALUE_GENERIC_TYPE implements TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE { TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent; - public DescendingTestOrderedMapGenerator(TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent) { + public ReverseTestOrderedMapGenerator(TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent) { super(parent); this.parent = parent; } @Override public ORDERED_MAP KEY_VALUE_GENERIC_TYPE create(Entry KEY_VALUE_GENERIC_TYPE... elements) { - return ((ORDERED_MAP KEY_VALUE_GENERIC_TYPE)parent.create(elements)).reversed(); - } - - @Override - public Iterable> order(List> insertionOrder) { - ObjectList> values = ObjectIterators.pour(ObjectIterators.wrap(parent.order(insertionOrder).iterator())); - ObjectLists.reverse(values); - return values; - } - - @Override - public ObjectIterable order(ObjectList insertionOrder) { - ObjectList values = parent.order(insertionOrder).pourAsList(); - ObjectLists.reverse(values); - return values; + ObjectList entries = new ObjectArrayList(elements); + ObjectLists.reverse(entries); + return ((ORDERED_MAP KEY_VALUE_GENERIC_TYPE)parent.create(entries.toArray(Entry[]::new))).reversed(); } } diff --git a/src/test/java/speiger/src/testers/utils/SpecialFeature.java b/src/test/java/speiger/src/testers/utils/SpecialFeature.java index 22a39b6..bd23acf 100644 --- a/src/test/java/speiger/src/testers/utils/SpecialFeature.java +++ b/src/test/java/speiger/src/testers/utils/SpecialFeature.java @@ -18,6 +18,7 @@ public enum SpecialFeature implements Feature { ITERATOR_MODIFIABLE, MAP_ENTRY, DESCENDING, + REVERSE, SUBMAP; private final Set> implied;