Fixed a bunch of Iterator code and implemented Reverse Map/Set Tests

This commit is contained in:
Speiger 2026-05-10 22:00:55 +02:00
parent d002f0094f
commit a26106cc89
15 changed files with 392 additions and 180 deletions

View File

@ -32,7 +32,7 @@
<attribute name="gradle_used_by_scope" value="builder"/> <attribute name="gradle_used_by_scope" value="builder"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/> <classpathentry kind="output" path="bin/default"/>
</classpath> </classpath>

View File

@ -51,7 +51,7 @@ import speiger.src.collections.utils.SanityChecks;
*/ */
public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CLASS_TYPE, CLASS_VALUE_TYPE> implements MAP KEY_VALUE_GENERIC_TYPE public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CLASS_TYPE, CLASS_VALUE_TYPE> implements MAP KEY_VALUE_GENERIC_TYPE
{ {
protected VALUE_TYPE defaultReturnValue = EMPTY_VALUE; protected VALUE_TYPE defaultReturnValue = INVALID_VALUE;
@Override @Override
public VALUE_TYPE getDefaultReturnValue() { public VALUE_TYPE getDefaultReturnValue() {
@ -558,7 +558,13 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
public REVERSED_ORDERED_MAP(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map) { public REVERSED_ORDERED_MAP(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map) {
this.map = map; this.map = map;
} }
@Override
public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) {
map.setDefaultReturnValue(v);
return this;
}
@Override
public VALUE_TYPE getDefaultReturnValue() { return map.getDefaultReturnValue(); }
@Override @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
@Override @Override

View File

@ -754,7 +754,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new ReverseBiIterator<>(new EntryIterator(false)); return new EntryIterator(false);
} }
@Override @Override
@ -1023,7 +1023,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new KeyIterator(false)); return new KeyIterator(false);
} }
@Override @Override
@ -1224,7 +1224,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } 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() { private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); return new ValueIterator(false);
} }
@Override @Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } 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 { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator(boolean start) { MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; else previous = lastIndex;
} }
MapIterator(KEY_TYPE from) { MapIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; 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() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { public int nextIndex() {
@ -1592,20 +1595,30 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {

View File

@ -758,7 +758,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new ReverseBiIterator<>(new EntryIterator(false)); return new EntryIterator(false);
} }
@Override @Override
@ -1022,7 +1022,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new KeyIterator(false)); return new KeyIterator(false);
} }
@Override @Override
@ -1225,7 +1225,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } 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() { private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); return new ValueIterator(false);
} }
@Override @Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } 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 { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator(boolean start) { MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; 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() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { 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() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {

View File

@ -664,7 +664,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new ReverseBiIterator<>(new EntryIterator(false)); return new EntryIterator(false);
} }
@Override @Override
@ -906,7 +906,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new KeyIterator(false)); return new KeyIterator(false);
} }
@Override @Override
@ -1103,7 +1103,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } 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() { private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); return new ValueIterator(false);
} }
@Override @Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } 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 { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator(boolean start) { MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; else previous = lastIndex;
} }
@ -1394,11 +1396,11 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { public int nextIndex() {
@ -1415,20 +1417,30 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {

View File

@ -907,7 +907,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new ReverseBiIterator<>(new EntryIterator(false)); return new EntryIterator(false);
} }
@Override @Override
@ -1129,7 +1129,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { return new KeyIterator(true); } public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { return new KeyIterator(true); }
@Override @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 @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); } public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); }
@Override @Override
@ -1274,7 +1274,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); } 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() { private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new VALUE_ABSTRACT_COLLECTION.ReverseBiIteratorVALUE_BRACES(new ValueIterator(false)); return new ValueIterator(false);
} }
@Override @Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); } 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 { private class MapIterator {
boolean forward;
int index; int index;
int lastReturned = -1; int lastReturned = -1;
MapIterator(boolean start) { MapIterator(boolean start) {
this.forward = start;
this.index = start ? 0 : size; this.index = start ? 0 : size;
} }
MapIterator(KEY_TYPE element) { MapIterator(KEY_TYPE element) {
this.forward = true;
index = findIndex(element); index = findIndex(element);
if(index == -1) throw new NoSuchElementException(); if(index == -1) throw new NoSuchElementException();
} }
public boolean hasNext() { public boolean hasNext() {
return index < size; return forward ? index < size : index > 0;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return index > 0; return forward ? index > 0 : index < size;
} }
public int nextIndex() { public int nextIndex() {
return index; if(forward) return index;
return size - index;
} }
public int previousIndex() { public int previousIndex() {
return index-1; if(forward) return index-1;
return (size - index)-1;
} }
public void remove() { public void remove() {
@ -1529,26 +1534,42 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
index--; if(forward) {
return (lastReturned = index); index--;
} return (lastReturned = index);
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index; lastReturned = index;
return 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) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); 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); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1); if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
public int back(int amount) { private int moveBackwards(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1); if(steps > 0) lastReturned = Math.min(index, size()-1);

View File

@ -511,18 +511,18 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator(0); return new SetIterator(true, 0);
} }
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new SetIterator(size)); return new SetIterator(false, size);
} }
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
int index = findIndex(fromElement); int index = findIndex(fromElement);
if(index != -1) return new SetIterator(index); if(index != -1) return new SetIterator(true, index);
throw new NoSuchElementException(); 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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int index; int index;
int lastReturned = -1; int lastReturned = -1;
public SetIterator(int index) { public SetIterator(boolean forward, int index) {
this.forward = forward;
this.index = index; this.index = index;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return index < size(); return forward ? index < size() : index > 0;
} }
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = index; if(forward) {
return data[index++]; lastReturned = index;
return data[index++];
}
index--;
return data[(lastReturned = index)];
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return index > 0; return forward ? index > 0 : index < size();
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
--index; if(forward) {
return data[(lastReturned = index)]; index--;
return data[(lastReturned = index)];
}
lastReturned = index;
return data[index++];
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
return index-1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@ -642,15 +654,23 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); 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); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1); if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@Override private int moveBackwards(int amount) {
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1); if(steps > 0) lastReturned = Math.min(index, size()-1);

View File

@ -460,7 +460,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new SetIterator(false)); return new SetIterator(false);
} }
@Override @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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator(boolean start) { SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) { if(KEY_EQUALS_NULL(from)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@ -565,48 +568,60 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@ -615,8 +630,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@ -624,12 +639,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {

View File

@ -702,7 +702,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new SetIterator(false)); return new SetIterator(false);
} }
@Override @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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator(boolean start) { SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@ -766,48 +769,60 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@ -856,8 +871,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@ -865,12 +880,22 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {

View File

@ -673,7 +673,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new ReverseBiIteratorBRACES(new SetIterator(false)); return new SetIterator(false);
} }
@Override @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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator(boolean start) { SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex; if(start) next = firstIndex;
else previous = lastIndex; else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) { if(KEY_EQUALS_NULL(from)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@ -737,48 +740,60 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@ -827,8 +842,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@ -836,12 +851,22 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {

View File

@ -1,16 +1,29 @@
package speiger.src.testers.PACKAGE.builder; package speiger.src.testers.PACKAGE.builder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import com.google.common.collect.testing.AbstractTester; 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.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.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import junit.framework.TestSuite; 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.generators.TEST_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetMoveTester; 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_TYPEOrderedSetIterationTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetNavigationTester; 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") @SuppressWarnings("javadoc")
public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER KEY_GENERIC_TYPE { 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 #endignore
return super.createTestSuite(); return super.createTestSuite();
} }
@Override
protected List<TestSuite> createDerivedSuites(
FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) {
derivedSuites.add(createReverseSuite(parentBuilder));
}
return derivedSuites;
}
private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE delegate = (TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator();
List<Feature<?>> 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<CLASS_TYPE> 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<CLASS_TYPE> order(List<CLASS_TYPE> 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();
}
} }

View File

@ -238,21 +238,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> mapFeatures) { private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) entrySetFeatures.add(SpecialFeature.COPYING);
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) { else entrySetFeatures.remove(SpecialFeature.COPYING);
entrySetFeatures.add(SpecialFeature.COPYING);
} if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) entrySetFeatures.add(SpecialFeature.MODIFIABLE);
else { else entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
entrySetFeatures.remove(SpecialFeature.COPYING);
} if(mapFeatures.contains(SpecialFeature.REVERSE)) entrySetFeatures.add(SpecialFeature.REVERSE);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) { else entrySetFeatures.remove(SpecialFeature.REVERSE);
entrySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
entrySetFeatures.add(SpecialFeature.MAP_ENTRY); entrySetFeatures.add(SpecialFeature.MAP_ENTRY);
#endignore #endignore
return entrySetFeatures; return entrySetFeatures;
@ -262,23 +258,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
Set<Feature<?>> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
keySetFeatures.add(CollectionFeature.SUBSET_VIEW); keySetFeatures.add(CollectionFeature.SUBSET_VIEW);
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} 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.CHILDREN_COPY)) {
keySetFeatures.add(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) keySetFeatures.add(SpecialFeature.MODIFIABLE);
} else keySetFeatures.remove(SpecialFeature.MODIFIABLE);
else {
keySetFeatures.remove(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.REVERSE)) keySetFeatures.add(SpecialFeature.REVERSE);
} else keySetFeatures.remove(SpecialFeature.REVERSE);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) {
keySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
keySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
#endignore #endignore
return keySetFeatures; return keySetFeatures;
} }
@ -287,18 +277,15 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeValuesCollectionFeatures(Set<Feature<?>> mapFeatures) { private static Set<Feature<?>> computeValuesCollectionFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
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.CHILDREN_COPY)) {
valuesCollectionFeatures.add(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.REVERSE)) valuesCollectionFeatures.add(SpecialFeature.REVERSE);
} else valuesCollectionFeatures.remove(SpecialFeature.REVERSE);
else {
valuesCollectionFeatures.remove(SpecialFeature.COPYING);
}
#endignore #endignore
return valuesCollectionFeatures; return valuesCollectionFeatures;
} }

View File

@ -55,8 +55,8 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU
@Override @Override
protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) { protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) {
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder); List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
if (!parentBuilder.getFeatures().contains(SpecialFeature.DESCENDING)) { if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) {
derivedSuites.add(createDescendingSuite(parentBuilder)); derivedSuites.add(createReverseSuite(parentBuilder));
} }
return derivedSuites; 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); return ORDERED_SET_TEST_BUILDER.using((TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE)generator);
} }
private TestSuite createDescendingSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) { private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) {
TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE delegate = (TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator(); TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE delegate = (TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator();
List<Feature<?>> features = new ArrayList<>(); List<Feature<?>> features = new ArrayList<>();
features.add(SpecialFeature.DESCENDING); features.add(SpecialFeature.REVERSE);
features.addAll(parentBuilder.getFeatures()); features.addAll(parentBuilder.getFeatures());
features.remove(SpecialFeature.COPYING); features.remove(SpecialFeature.COPYING);
features.remove(SpecialFeature.CHILDREN_COPY); 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) .named(parentBuilder.getName() + " reversed").withFeatures(features)
.suppressing(parentBuilder.getSuppressedTests()).createTestSuite(); .suppressing(parentBuilder.getSuppressedTests()).createTestSuite();
} }

View File

@ -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; 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); super(parent);
this.parent = parent; this.parent = parent;
} }
@Override @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE create(Entry KEY_VALUE_GENERIC_TYPE... elements) { 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(); ObjectList<Entry KEY_VALUE_GENERIC_TYPE> entries = new ObjectArrayList<Entry KEY_VALUE_GENERIC_TYPE>(elements);
} ObjectLists.reverse(entries);
return ((ORDERED_MAP KEY_VALUE_GENERIC_TYPE)parent.create(entries.toArray(Entry[]::new))).reversed();
@Override
public Iterable<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> order(List<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> insertionOrder) {
ObjectList<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> values = ObjectIterators.pour(ObjectIterators.wrap(parent.order(insertionOrder).iterator()));
ObjectLists.reverse(values);
return values;
}
@Override
public ObjectIterable<Entry KEY_VALUE_GENERIC_TYPE> order(ObjectList<Entry KEY_VALUE_GENERIC_TYPE> insertionOrder) {
ObjectList<Entry KEY_VALUE_GENERIC_TYPE> values = parent.order(insertionOrder).pourAsList();
ObjectLists.reverse(values);
return values;
} }
} }

View File

@ -18,6 +18,7 @@ public enum SpecialFeature implements Feature<Collection> {
ITERATOR_MODIFIABLE, ITERATOR_MODIFIABLE,
MAP_ENTRY, MAP_ENTRY,
DESCENDING, DESCENDING,
REVERSE,
SUBMAP; SUBMAP;
private final Set<Feature<? super Collection>> implied; private final Set<Feature<? super Collection>> implied;