diff --git a/build.gradle b/build.gradle index 44cd562f..0214f4e8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,8 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } +apply plugin: 'eclipse' + eclipse { classpath { downloadJavadoc = true diff --git a/src/main/java/speiger/src/builder/example/ClassType.java b/src/main/java/speiger/src/builder/example/ClassType.java index ec304c83..a5a83818 100644 --- a/src/main/java/speiger/src/builder/example/ClassType.java +++ b/src/main/java/speiger/src/builder/example/ClassType.java @@ -34,6 +34,11 @@ public enum ClassType return keyType; } + public String getKeyType(boolean value) + { + return value && this == OBJECT ? "V" : keyType; + } + public String getValueType() { return this == OBJECT ? "V" : keyType; @@ -44,6 +49,11 @@ public enum ClassType return classType; } + public String getClassType(boolean value) + { + return value && this == OBJECT ? "V" : classType; + } + public String getClassValueType() { return this == OBJECT ? "V" : classType; diff --git a/src/main/java/speiger/src/builder/example/GlobalVariables.java b/src/main/java/speiger/src/builder/example/GlobalVariables.java index dfcc2675..44cb6aa7 100644 --- a/src/main/java/speiger/src/builder/example/GlobalVariables.java +++ b/src/main/java/speiger/src/builder/example/GlobalVariables.java @@ -62,6 +62,10 @@ public class GlobalVariables addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType()); addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType()); } + if(valueType.needsCustomJDKType()) + { + addSimpleMapper("SANITY_CAST_VALUE", "castTo"+valueType.getFileType()); + } addAnnontion("@PrimitiveOverride", "@Override"); addSimpleMapper("@PrimitiveDoc", ""); addAnnontion("@Primitive", "@Deprecated"); @@ -70,39 +74,35 @@ public class GlobalVariables public GlobalVariables createHelperVariables() { - addArgumentMapper("EQUALS_KEY_TYPE", type.isObject() ? "Objects.equals(%2$s, %1$s)" : "Objects.equals(%2$s, KEY_TO_OBJ(%1$s))").removeBraces(); - addInjectMapper("KEY_EQUALS_NOT_NULL", type.getComparableValue()+" != "+(type.isPrimitiveBlocking() ? type.getEmptyValue() : (type.needsCast() ? type.getEmptyValue() : "0"))).removeBraces(); - addInjectMapper("KEY_EQUALS_NULL", type.getComparableValue()+" == "+(type.isPrimitiveBlocking() ? type.getEmptyValue() : (type.needsCast() ? type.getEmptyValue() : "0"))).removeBraces(); - addArgumentMapper("KEY_EQUALS_NOT", type.getEquals(true)).removeBraces(); - addArgumentMapper("KEY_EQUALS", type.getEquals(false)).removeBraces(); - addArgumentMapper("VALUE_EQUALS_NOT", valueType.getEquals(true)).removeBraces(); - addArgumentMapper("VALUE_EQUALS", valueType.getEquals(false)).removeBraces(); - - addArgumentMapper("COMPARE_TO_KEY", type.isObject() ? "((Comparable)%1$s).compareTo((T)%2$s)" : type.getClassType()+".compare(%1$s, %2$s)").removeBraces(); - addArgumentMapper("COMPARE_TO", type.isObject() ? "%1$s.compareTo(%2$s)" : type.getClassType()+".compare(%1$s, %2$s)").removeBraces(); - - addInjectMapper("KEY_TO_OBJ", type.isObject() ? "%s" : type.getClassType()+".valueOf(%s)").removeBraces(); - addInjectMapper("OBJ_TO_KEY", type.isObject() ? "%s" : "%s."+type.getKeyType()+"Value()").removeBraces(); - addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces(); - - addInjectMapper("VALUE_TO_OBJ", valueType.isObject() ? "%s" : valueType.getClassType()+".valueOf(%s)").removeBraces(); - addInjectMapper("OBJ_TO_VALUE", valueType.isObject() ? "%s" : "%s."+valueType.getKeyType()+"Value()").removeBraces(); - addInjectMapper("CLASS_TO_VALUE", "(("+valueType.getClassValueType()+")%s)."+valueType.getValueType()+"Value()").removeBraces(); - - addInjectMapper("KEY_TO_HASH", type.isObject() ? "%s.hashCode()" : type.getClassType()+".hashCode(%s)").removeBraces(); - - addSimpleMapper("CAST_KEY_ARRAY ", type.isObject() ? "(KEY_TYPE[])" : ""); - addSimpleMapper("EMPTY_KEY_ARRAY", type.isObject() ? "(KEY_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY"); - addInjectMapper("NEW_KEY_ARRAY", type.isObject() ? "(KEY_TYPE[])new Object[%s]" : "new KEY_TYPE[%s]").removeBraces(); - addInjectMapper("NEW_CLASS_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces(); - - addSimpleMapper("CAST_VALUE_ARRAY ", valueType.isObject() ? "(VALUE_TYPE[])" : ""); - addSimpleMapper("EMPTY_VALUE_ARRAY", valueType.isObject() ? "(VALUE_TYPE[])VALUE_ARRAYS.EMPTY_ARRAY" : "VALUE_ARRAYS.EMPTY_ARRAY"); - addInjectMapper("NEW_VALUE_ARRAY", valueType.isObject() ? "(VALUE_TYPE[])new Object[%s]" : "new VALUE_TYPE[%s]").removeBraces(); - addInjectMapper("NEW_CLASS_VALUE_ARRAY", valueType.isObject() ? "(CLASS_VALUE_TYPE[])new Object[%s]" : "new CLASS_VALUE_TYPE[%s]").removeBraces(); + createHelperVars(type, false, "KEY"); + createHelperVars(valueType, true, "VALUE"); return this; } + private void createHelperVars(ClassType type, boolean value, String fix) + { + addArgumentMapper("EQUALS_"+fix+"_TYPE", "Objects.equals(%2$s, "+(type.isObject() ? "%1$s" : fix+"_TO_OBJ(%1$s)")+")").removeBraces(); + addInjectMapper(fix+"_EQUALS_NOT_NULL", type.getComparableValue()+" != "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces(); + addInjectMapper(fix+"_EQUALS_NULL", type.getComparableValue()+" == "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces(); + addArgumentMapper(fix+"_EQUALS_NOT", type.getEquals(true)).removeBraces(); + addArgumentMapper(fix+"_EQUALS", type.getEquals(false)).removeBraces(); + + addArgumentMapper("COMPAREABLE_TO_"+fix, type.isObject() ? "((Comparable<"+type.getKeyType(value)+">)%1$s).compareTo(("+type.getKeyType(value)+")%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces(); + addArgumentMapper("COMPARE_TO_"+fix, type.isObject() ? "%1$s.compareTo(%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces(); + + addInjectMapper(fix+"_TO_OBJ", type.isObject() ? "%s" : type.getClassType(value)+".valueOf(%s)").removeBraces(); + addInjectMapper("OBJ_TO_"+fix, type.isObject() ? "%s" : "%s."+type.getKeyType(value)+"Value()").removeBraces(); + addInjectMapper("CLASS_TO_"+fix, "(("+type.getClassType(value)+")%s)."+type.getKeyType(value)+"Value()").removeBraces(); + + addInjectMapper(fix+"_TO_HASH", type.isObject() ? "%s.hashCode()" : type.getClassType(value)+".hashCode(%s)").removeBraces(); + addInjectMapper(fix+"_TO_STRING", type.isObject() ? "%s.toString()" : type.getClassType(value)+".toString(%s)").removeBraces(); + + addSimpleMapper("CAST_"+fix+"_ARRAY ", type.isObject() ? "("+fix+"_TYPE[])" : ""); + addSimpleMapper("EMPTY_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY"); + addInjectMapper("NEW_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces(); + addInjectMapper("NEW_CLASS"+(value ? "_VALUE" : "")+"_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces(); + } + public GlobalVariables createPreFunctions() { addSimpleMapper("ENTRY_SET", type.getFileType().toLowerCase()+"2"+valueType.getFileType()+"EntrySet"); @@ -134,6 +134,7 @@ public class GlobalVariables addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection"); addAbstractMapper("ABSTRACT_SET", "Abstract%sSet"); addAbstractMapper("ABSTRACT_LIST", "Abstract%sList"); + addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2"); addClassMapper("SUB_LIST", "SubList"); //Helper Classes @@ -180,9 +181,9 @@ public class GlobalVariables public GlobalVariables createFunctions() { - addSimpleMapper("APPLY_VALUE", "applyAs"+valueType.getNonFileType()); + addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType()); addSimpleMapper("APPLY_CAST", "applyAs"+type.getCustomJDKType().getNonFileType()); - addSimpleMapper("APPLY", "applyAs"+type.getNonFileType()); + addSimpleMapper("APPLY", type.isObject() ? "apply" : "applyAs"+type.getNonFileType()); addFunctionValueMappers("COMPUTE_IF_ABSENT", "compute%sIfAbsent"); addFunctionValueMappers("COMPUTE_IF_PRESENT", "compute%sIfPresent"); addFunctionValueMapper("COMPUTE", "compute"); @@ -266,11 +267,18 @@ public class GlobalVariables private void addAbstractMapper(String pattern, String replacement) { + operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, String.format(replacement, valueType.getFileType()))); operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getFileType()))); } + private void addAbstractBiMapper(String pattern, String replacement, String splitter) + { + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getFileType()+splitter+valueType.getFileType()))); + } + private void addFunctionMapper(String pattern, String replacement) { + operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, replacement+valueType.getNonFileType())); operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement+type.getNonFileType())); } @@ -281,6 +289,7 @@ public class GlobalVariables private void addFunctionMappers(String pattern, String replacement) { + operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, String.format(replacement, valueType.getNonFileType()))); operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getNonFileType()))); } diff --git a/src/main/java/speiger/src/builder/example/TestBuilder.java b/src/main/java/speiger/src/builder/example/TestBuilder.java index 8a0e4296..173364be 100644 --- a/src/main/java/speiger/src/builder/example/TestBuilder.java +++ b/src/main/java/speiger/src/builder/example/TestBuilder.java @@ -61,13 +61,16 @@ public class TestBuilder extends TemplateProcessor create(clzType, subType); } } +// blocked.put("AbstractMap", EnumSet.allOf(ClassType.class)); biRequired.put("BiConsumer", ""); biRequired.put("Function", "2"); biRequired.put("UnaryOperator", ""); biRequired.put("Map", "2"); biRequired.put("Maps", "2"); + biRequired.put("AbstractMap", "2"); nameRemapper.put("BiConsumer", "%sConsumer"); nameRemapper.put("IArray", "I%sArray"); + nameRemapper.put("AbstractMap", "Abstract%sMap"); nameRemapper.put("AbstractCollection", "Abstract%sCollection"); nameRemapper.put("AbstractSet", "Abstract%sSet"); nameRemapper.put("AbstractList", "Abstract%sList"); diff --git a/src/main/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template b/src/main/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template new file mode 100644 index 00000000..8e4dff3a --- /dev/null +++ b/src/main/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template @@ -0,0 +1,385 @@ +package speiger.src.collections.PACKAGE.maps.abstracts; + +import java.util.AbstractMap; +import java.util.Map; +import java.util.Objects; + +import speiger.src.collections.PACKAGE.collections.ITERATOR; +import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; +import speiger.src.collections.PACKAGE.functions.function.FUNCTION; +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.maps.interfaces.MAP; +import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; +import speiger.src.collections.PACKAGE.sets.SET; +import speiger.src.collections.PACKAGE.utils.maps.MAPS; +import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; +import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; +#if !SAME_TYPE +import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; +import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; +#endif +#if !TYPE_OBJECT && !VALUE_OBJECT +import speiger.src.collections.objects.collections.ObjectIterator; +#endif +#if !TYPE_OBJECT +import speiger.src.collections.objects.sets.ObjectSet; +#endif + +public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap implements MAP KEY_VALUE_GENERIC_TYPE +{ + VALUE_TYPE defaultReturnValue = EMPTY_VALUE; + + @Override + public VALUE_TYPE getDefaultReturnValue() { + return defaultReturnValue; + } + + @Override + public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) { + defaultReturnValue = v; + return this; + } + + @Override + public void putAll(MAP KEY_VALUE_GENERIC_TYPE m) { + for(ObjectIterator iter = MAPS.fastIterator(m);iter.hasNext();) { + MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); + put(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); + } + } + + @Override + public void putAll(Map m) + { + if(m instanceof MAP) putAll((MAP KEY_VALUE_GENERIC_TYPE)m); + else super.putAll(m); + } + +#if TYPE_OBJECT + + @Override + public boolean containsKey(Object key) { + for(ITERATOR KEY_GENERIC_TYPE iter = keySet().iterator();iter.hasNext();) + if(EQUALS_KEY_TYPE(iter.NEXT(), key)) return true; + return false; + } +#else + + @Override + public boolean containsKey(KEY_TYPE key) { + for(ITERATOR KEY_GENERIC_TYPE iter = keySet().iterator();iter.hasNext();) + if(KEY_EQUALS(iter.NEXT(), key)) return true; + return false; + } +#endif +#if VALUE_OBJECT + + @Override + public boolean containsValue(Object value) { + for(VALUE_ITERATOR VALUE_GENERIC_TYPE iter = values().iterator();iter.hasNext();) + if(EQUALS_VALUE_TYPE(iter.VALUE_NEXT(), value)) return true; + return false; + } +#else + + @Override + public boolean containsValue(VALUE_TYPE value) { + for(VALUE_ITERATOR VALUE_GENERIC_TYPE iter = values().iterator();iter.hasNext();) + if(VALUE_EQUALS(iter.VALUE_NEXT(), value)) return true; + return false; + } +#endif + + @Override + public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue) { + VALUE_TYPE curValue = get(key); + if (VALUE_EQUALS_NOT(curValue, oldValue) || (VALUE_EQUALS(curValue, getDefaultReturnValue()) && !containsKey(key))) { + return false; + } + put(key, newValue); + return true; + } + + @Override + public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value) { + VALUE_TYPE curValue; + if (VALUE_EQUALS_NOT((curValue = get(key)), getDefaultReturnValue()) || containsKey(key)) { + curValue = put(key, value); + } + return curValue; + } + + @Override + public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { + Objects.requireNonNull(mappingFunction); + for(ObjectIterator iter = MAPS.fastIterator(this);iter.hasNext();) { + MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); + entry.setValue(mappingFunction.APPLY_VALUE(entry.ENTRY_KEY(), entry.ENTRY_VALUE())); + } + } + + @Override + public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { + Objects.requireNonNull(mappingFunction); + VALUE_TYPE value = get(key); + VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value); + if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { + if(VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key)) { + remove(key); + return getDefaultReturnValue(); + } + return getDefaultReturnValue(); + } + put(key, newValue); + return newValue; + } + + @Override + public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { + Objects.requireNonNull(mappingFunction); + VALUE_TYPE value; + if((value = get(key)) == getDefaultReturnValue()) { + VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); + if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) { + put(key, newValue); + return newValue; + } + } + return value; + } + + @Override + public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { + Objects.requireNonNull(mappingFunction); + VALUE_TYPE value; + if(VALUE_EQUALS_NOT((value = get(key)), getDefaultReturnValue())) { + VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value); + if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) { + put(key, newValue); + return newValue; + } + remove(key); + } + return getDefaultReturnValue(); + } + + @Override + public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { + Objects.requireNonNull(mappingFunction); + VALUE_TYPE oldValue = get(key); + VALUE_TYPE newValue = VALUE_EQUALS(oldValue, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(oldValue, value); + if(VALUE_EQUALS(newValue, getDefaultReturnValue())) remove(key); + else put(key, newValue); + return newValue; + } + +#if TYPE_OBJECT + @Override + public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) { + VALUE_TYPE value = get(key); + return VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key) ? value : defaultValue; + } + +#else + @Override + public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { + VALUE_TYPE value = get(key); + return VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key) ? value : defaultValue; + } + +#endif + @Override + public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(ObjectIterator iter = MAPS.fastIterator(this);iter.hasNext();) { + MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); + action.accept(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); + } + } + + @Override + public SET KEY_GENERIC_TYPE keySet() { + return new ABSTRACT_SET KEY_GENERIC_TYPE() { +#if !TYPE_OBJECT + @Override + public boolean remove(KEY_TYPE o) { + return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue()); + } + +#else + @Override + public boolean remove(Object o) { + return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue()); + } + +#endif + @Override + public boolean add(KEY_TYPE o) { + throw new UnsupportedOperationException(); + } + + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() { + return new ITERATOR KEY_GENERIC_TYPE() { + ObjectIterator iter = MAPS.fastIterator(ABSTRACT_MAP.this); + @Override + public boolean hasNext() { + return iter.hasNext(); + } + + @Override + public KEY_TYPE NEXT() { + return iter.next().ENTRY_KEY(); + } + + @Override + public void remove() { + iter.remove(); + } + }; + } + + @Override + public int size() { + return ABSTRACT_MAP.this.size(); + } + + @Override + public void clear() { + ABSTRACT_MAP.this.clear(); + } + }; + } + + @Override + public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { + return new VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE() { + @Override + public boolean add(VALUE_TYPE o) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return ABSTRACT_MAP.this.size(); + } + + @Override + public void clear() { + ABSTRACT_MAP.this.clear(); + } + + @Override + public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { + return new VALUE_ITERATOR VALUE_GENERIC_TYPE() { + ObjectIterator iter = MAPS.fastIterator(ABSTRACT_MAP.this); + @Override + public boolean hasNext() { + return iter.hasNext(); + } + + @Override + public VALUE_TYPE VALUE_NEXT() { + return iter.next().ENTRY_VALUE(); + } + + @Override + public void remove() { + iter.remove(); + } + }; + } + }; + } + + @Override + @SuppressWarnings("rawtypes") + public ObjectSet> entrySet() { + return (ObjectSet)ENTRY_SET(); + } + + @Override + public boolean equals(Object o) { + if(o == this) return true; + if(o instanceof Map) { + if(size() != ((Map)o).size()) return false; + if(o instanceof MAP) return ENTRY_SET().containsAll(((MAP KEY_VALUE_GENERIC_TYPE)o).ENTRY_SET()); + return ENTRY_SET().containsAll(((Map)o).entrySet()); + } + return false; + } + + @Override + public int hashCode() { + int hash = 0; + ObjectIterator iter = MAPS.fastIterator(this); + while(iter.hasNext()) hash += iter.next().hashCode(); + return hash; + } + + public static class BasicEntry KEY_VALUE_GENERIC_TYPE implements MAP.Entry KEY_VALUE_GENERIC_TYPE { + protected KEY_TYPE key; + protected VALUE_TYPE value; + + public BasicEntry() {} +#if !TYPE_OBJECT + public BasicEntry(CLASS_TYPE key, CLASS_VALUE_TYPE value) { + this.key = OBJ_TO_KEY(key); + this.value = OBJ_TO_VALUE(value); + } + +#endif + public BasicEntry(KEY_TYPE key, VALUE_TYPE value) { + this.key = key; + this.value = value; + } + + @Override + public KEY_TYPE ENTRY_KEY() { + return key; + } + + @Override + public VALUE_TYPE ENTRY_VALUE() { + return value; + } + + @Override + public VALUE_TYPE setValue(VALUE_TYPE value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof Map.Entry) { + if(obj instanceof MAP.Entry) { + MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; + return key == entry.ENTRY_KEY() && value == entry.ENTRY_VALUE(); + } + Map.Entry entry = (Map.Entry)obj; + Object key = entry.getKey(); + Object value = entry.getValue(); +#if TYPE_OBJECT && VALUE_OBJECT + return KEY_EQUALS(this.key, key) && VALUE_EQUALS(this.value, value); +#else if TYPE_OBJECT + return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(this.key, key) && VALUE_EQUALS(this.value, CLASS_TO_VALUE(value)); +#else if VALUE_OBJECT + return key instanceof CLASS_TYPE && KEY_EQUALS(this.key, CLASS_TO_KEY(key)) && VALUE_EQUALS(this.value, value); +#else + return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(this.key, CLASS_TO_KEY(key)) && VALUE_EQUALS(this.value, CLASS_TO_VALUE(value)); +#endif + } + return false; + } + + @Override + public int hashCode() { + return KEY_TO_HASH(key) ^ VALUE_TO_HASH(value); + } + + @Override + public String toString() { + return KEY_TO_STRING(key) + "->" + VALUE_TO_STRING(value); + } + } +} \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template b/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template index 0016e00c..810be10c 100644 --- a/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template +++ b/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template @@ -91,7 +91,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY public void ENQUEUE(KEY_TYPE e) { if(size == array.length) array = Arrays.copyOf(array, size+1); if(firstIndex != -1){ - int compare = comparator == null ? COMPARE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]); + int compare = comparator == null ? COMPAREABLE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]); if(compare < 0) firstIndex = size; else if(compare > 0) firstIndex = -1; } @@ -191,7 +191,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY KEY_TYPE value = array[index]; if(comparator == null) { for(int i = index;i>=0;i--) { - if(COMPARE_TO_KEY(array[i], value) < 0) + if(COMPAREABLE_TO_KEY(array[i], value) < 0) value = array[index = i]; } } diff --git a/src/main/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template b/src/main/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template index 9cbef3e9..28ad30ac 100644 --- a/src/main/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template +++ b/src/main/resources/speiger/assets/collections/templates/sets/AVLTreeSet.template @@ -402,7 +402,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE } } - protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPARE_TO_KEY(k, v);} + protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);} /** From CLR */ protected void rotateLeft(Entry KEY_GENERIC_TYPE entry) { diff --git a/src/main/resources/speiger/assets/collections/templates/sets/RBTreeSet.template b/src/main/resources/speiger/assets/collections/templates/sets/RBTreeSet.template index 4e7b3ed4..08302963 100644 --- a/src/main/resources/speiger/assets/collections/templates/sets/RBTreeSet.template +++ b/src/main/resources/speiger/assets/collections/templates/sets/RBTreeSet.template @@ -405,7 +405,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE } } - protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPARE_TO_KEY(k, v);} + protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);} protected static GENERIC_KEY_BRACES boolean isBlack(Entry KEY_GENERIC_TYPE p) { return p == null || p.isBlack(); } protected static GENERIC_KEY_BRACES Entry KEY_GENERIC_TYPE parentOf(Entry KEY_GENERIC_TYPE p) { return (p == null ? null : p.parent); } protected static GENERIC_KEY_BRACES void setBlack(Entry KEY_GENERIC_TYPE p, boolean c) { if(p != null) p.setBlack(c); } diff --git a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template index 65b639d4..6901d066 100644 --- a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -125,8 +125,8 @@ public class ARRAYS int child = (index << 1) + 1; KEY_TYPE childValue = data[child]; int right = child+1; - if(right < size && COMPARE_TO_KEY(data[right], childValue) < 0) childValue = data[child = right]; - if(COMPARE_TO_KEY(value, childValue) <= 0) break; + if(right < size && COMPAREABLE_TO_KEY(data[right], childValue) < 0) childValue = data[child = right]; + if(COMPAREABLE_TO_KEY(value, childValue) <= 0) break; data[index] = childValue; index = child; } @@ -150,7 +150,7 @@ public class ARRAYS while(index > 0) { int parent = (index - 1) >>> 1; KEY_TYPE parentValue = data[parent]; - if(COMPARE_TO_KEY(value, parentValue) >= 0) break; + if(COMPAREABLE_TO_KEY(value, parentValue) >= 0) break; data[index] = parentValue; index = parent; } @@ -379,7 +379,7 @@ public class ARRAYS for (int i = from+1;i= from && COMPARE_TO(current, array[j]) < 0) { + while(j >= from && COMPAREABLE_TO_KEY(current, array[j]) < 0) { array[j+1] = array[j--]; } array[j+1] = current; @@ -455,7 +455,7 @@ public class ARRAYS KEY_TYPE min = array[i]; int minId = i; for(int j = i+1; j < to; j++) { - if(COMPARE_TO(array[j], min) < 0) { + if(COMPAREABLE_TO_KEY(array[j], min) < 0) { min = array[j]; minId = j; } @@ -550,13 +550,13 @@ public class ARRAYS int mid = (from + to) >>> 1; mergeSort(supp, array, from, mid); mergeSort(supp, array, mid, to); - if(COMPARE_TO(supp[mid - 1], supp[mid]) <= 0) + if(COMPAREABLE_TO_KEY(supp[mid - 1], supp[mid]) <= 0) { System.arraycopy(supp, from, array, from, to - from); return; } for(int p = from, q = mid;from < to;from++) { - if(q >= to || p < mid && COMPARE_TO(supp[p], supp[q]) < 0) array[from] = supp[p++]; + if(q >= to || p < mid && COMPAREABLE_TO_KEY(supp[p], supp[q]) < 0) array[from] = supp[p++]; else array[from] = supp[q++]; } } @@ -749,15 +749,15 @@ public class ARRAYS int mid = (from + to) >>> 1; memFreeMergeSort(array, from, mid); memFreeMergeSort(array, mid, to); - if(COMPARE_TO(array[mid - 1], array[mid]) <= 0) + if(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0) return; for(int i = from, j = mid, comp;i < j && j < to;) { - if((comp = COMPARE_TO(array[i], array[j])) < 0) + if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0) i++; else if(comp == 0) swap(array, ++i, j); else { int k = j; - for(;k < to - 1 && COMPARE_TO(array[i], array[k + 1]) > 0;k++); + for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue; @@ -970,10 +970,10 @@ public class ARRAYS KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; int a = from, b = a, c = to - 1, d = c; for(int comp = 0;;swap(array, b++, c--)) { - for(;b<=c && (comp = COMPARE_TO(array[b], pivot)) <= 0;b++) { + for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) { if(comp == 0) swap(array, a++, b); } - for(;c>=b && (comp = COMPARE_TO(array[c], pivot)) >= 0;c--) { + for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) { if(comp == 0) swap(array, c, d--); } if(b>c) break; @@ -1091,7 +1091,7 @@ public class ARRAYS } static COMPAREABLE_KEY_BRACES int medium(KEY_TYPE[] data, int a, int b, int c) { - return COMPARE_TO(data[a], data[b]) < 0 ? (COMPARE_TO(data[b], data[c]) < 0 ? b : COMPARE_TO(data[a], data[c]) < 0 ? c : a) : (COMPARE_TO(data[b], data[c]) > 0 ? b : COMPARE_TO(data[a], data[c]) > 0 ? c : a); + return COMPAREABLE_TO_KEY(data[a], data[b]) < 0 ? (COMPAREABLE_TO_KEY(data[b], data[c]) < 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) < 0 ? c : a) : (COMPAREABLE_TO_KEY(data[b], data[c]) > 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) > 0 ? c : a); } static class QuickSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction { @@ -1119,10 +1119,10 @@ public class ARRAYS KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; int a = from, b = a, c = to - 1, d = c; for(int comp = 0;;swap(array, b++, c--)) { - for(;b<=c && (comp = COMPARE_TO(array[b], pivot)) <= 0;b++) { + for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) { if(comp == 0) swap(array, a++, b); } - for(;c>=b && (comp = COMPARE_TO(array[c], pivot)) >= 0;c--) { + for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) { if(comp == 0) swap(array, c, d--); } if(b>c) break; @@ -1203,13 +1203,13 @@ public class ARRAYS if(supp == null) supp = Arrays.copyOf(array, to); int mid = (from + to) >>> 1; invokeAll(new MergeSortActionBRACES(supp, array, from, mid), new MergeSortActionBRACES(supp, array, mid, to)); - if(COMPARE_TO(supp[mid - 1], supp[mid]) <= 0) + if(COMPAREABLE_TO_KEY(supp[mid - 1], supp[mid]) <= 0) { System.arraycopy(supp, from, array, from, to - from); return; } for(int p = from, q = mid;from < to;from++) { - if(q >= to || p < mid && COMPARE_TO(supp[p], supp[q]) < 0) array[from] = supp[p++]; + if(q >= to || p < mid && COMPAREABLE_TO_KEY(supp[p], supp[q]) < 0) array[from] = supp[p++]; else array[from] = supp[q++]; } } @@ -1276,15 +1276,15 @@ public class ARRAYS } int mid = (from + to) >>> 1; invokeAll(new MemFreeMergeSortActionBRACES(array, from, mid), new MemFreeMergeSortActionBRACES(array, mid, to)); - if(COMPARE_TO(array[mid - 1], array[mid]) <= 0) + if(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0) return; for(int i = from, j = mid, comp;i < j && j < to;) { - if((comp = COMPARE_TO(array[i], array[j])) < 0) + if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0) i++; else if(comp == 0) swap(array, ++i, j); else { int k = j; - for(;k < to - 1 && COMPARE_TO(array[i], array[k + 1]) > 0;k++); + for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue;