diff --git a/Changelog.md b/Changelog.md index 9f641f42..398c97ad 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,9 @@ ### Version 0.3.2 - Fixed: Map.put wasn't referring to primitive variants. +- Added: ImmutableList. +- Added: Iterator pour function into a List or Array +- Changed: Arrays Wrap is now accessible to Objects and now is ? extends TYPE instead of TYPE. ### Version 0.3.1 - Fixed: containsKey & containsValue in HashMaps were deprecated for Object Variants. diff --git a/src/builder/java/speiger/src/builder/GlobalVariables.java b/src/builder/java/speiger/src/builder/GlobalVariables.java index a42c994d..e1270bac 100644 --- a/src/builder/java/speiger/src/builder/GlobalVariables.java +++ b/src/builder/java/speiger/src/builder/GlobalVariables.java @@ -132,6 +132,7 @@ public class GlobalVariables //Final Classes addClassMapper("ARRAY_LIST", "ArrayList"); + addAbstractMapper("IMMUTABLE_LIST", "Immutable%sList"); addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue"); addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue"); addClassMapper("HEAP_PRIORITY_QUEUE", "HeapPriorityQueue"); diff --git a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java index 5e14871a..453a84c5 100644 --- a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java +++ b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java @@ -79,6 +79,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor nameRemapper.put("AbstractList", "Abstract%sList"); nameRemapper.put("EnumMap", "Enum2%sMap"); nameRemapper.put("LinkedEnumMap", "LinkedEnum2%sMap"); + nameRemapper.put("ImmutableList", "Immutable%sList"); addBlockage(ClassType.OBJECT, "Consumer", "Comparator", "Stack"); addBlockage(ClassType.BOOLEAN, "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet"); addBlockage(ClassType.BOOLEAN, "SortedMap", "NavigableMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap"); diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template index e99c0a70..5dc4f125 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -116,7 +116,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE * Creates a new ArrayList with a Copy of the array * @param a the array that should be copied */ - public ARRAY_LIST(KEY_TYPE[] a) { + public ARRAY_LIST(KEY_TYPE... a) { this(a, 0, a.length); } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template new file mode 100644 index 00000000..1909d27e --- /dev/null +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template @@ -0,0 +1,389 @@ +package speiger.src.collections.PACKAGE.lists; + +import java.util.Arrays; +#if TYPE_OBJECT +import java.util.Comparator; +#endif +import java.util.Collection; +import java.util.Objects; +#if TYPE_OBJECT +import java.util.function.Consumer; +#endif +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +#if PRIMITIVES +import java.util.function.JAVA_PREDICATE; +import java.util.function.JAVA_UNARY_OPERATOR; +#endif + +import speiger.src.collections.PACKAGE.collections.COLLECTION; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +import speiger.src.collections.PACKAGE.functions.CONSUMER; +import speiger.src.collections.PACKAGE.utils.ARRAYS; +#endif +import speiger.src.collections.objects.utils.ObjectArrays; +import speiger.src.collections.PACKAGE.utils.ITERATORS; +#if PRIMITIVES +import java.util.stream.JAVA_STREAM; +import java.util.stream.StreamSupport; +#endif +import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; +import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; +import speiger.src.collections.utils.SanityChecks; + +#if TYPE_OBJECT +/** + * A Type-Specific Immutable implementation of list that is written to reduce (un)boxing + * + * @Type(T) + */ +public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE +#else +/** + * A Type-Specific Immutable implementation of list that is written to reduce (un)boxing + */ +public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE +#endif +{ + /** The backing array */ + protected transient KEY_TYPE[] data; + + /** + * Creates a new Immutable copy of the contents of the Collection. + * @param c the elements that should be added into the list + */ + public IMMUTABLE_LIST(Collection c) { + data = ARRAYS.pour(ITERATORS.wrap(c.iterator())); + } + + /** + * Creates a new Immutable copy of the contents of the Collection. + * @param c the elements that should be added into the list + */ + public IMMUTABLE_LIST(COLLECTION KEY_GENERIC_TYPE c) { + data = ARRAYS.pour(c.iterator()); + } + + /** + * Creates a new Immutable copy of the contents of the List. + * @param l the elements that should be added into the list + */ + public IMMUTABLE_LIST(LIST KEY_GENERIC_TYPE l) { + KEY_TYPE[] temp = NEW_KEY_ARRAY(l.size()); + l.getElements(0, temp, 0, l.size()); + data = temp; + } + + /** + * Creates a new Immutable copy of the contents of the Array. + * @param a the array that should be copied + */ + public IMMUTABLE_LIST(KEY_TYPE... a) { + this(a, 0, a.length); + } + + /** + * Creates a new ImmutableList copy of the array with a custom length + * @param a the array that should be copied + * @param length the desired length that should be copied + */ + public IMMUTABLE_LIST(KEY_TYPE[] a, int length) { + this(a, 0, length); + } + + /** + * Creates a new ImmutableList copy of the array with in the custom range. + * @param a the array that should be copied + * @param offset the starting offset of where the array should be copied from + * @param length the desired length that should be copied + * @throws IllegalStateException if offset is smaller then 0 + * @throws IllegalStateException if the offset + length exceeds the array length + */ + public IMMUTABLE_LIST(KEY_TYPE[] a, int offset, int length) { + SanityChecks.checkArrayCapacity(a.length, offset, length); + data = Arrays.copyOfRange(a, offset, offset+length); + } + + @Override + public boolean add(KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + public void add(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + @Primitive + public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } + @Override + public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } + @Override + public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } + @Override + public void addElements(int from, KEY_TYPE[] a, int offset, int length) { throw new UnsupportedOperationException(); } + + @Override + public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { + SanityChecks.checkArrayCapacity(data.length, offset, length); + System.arraycopy(data, from, a, offset, length); + return a; + } + + @Override + public void removeElements(int from, int to) { throw new UnsupportedOperationException(); } +#if TYPE_OBJECT + @Override + public K[] extractElements(int from, int to, Class type) { throw new UnsupportedOperationException(); } + +#else + @Override + public KEY_TYPE[] extractElements(int from, int to) { throw new UnsupportedOperationException(); } + +#endif + + /** + * A function to find if the Element is present in this list. + * @param o the element that is searched for + * @return if the element was found. + */ + @Override + @Primitive + public boolean contains(Object o) { + return indexOf(o) != -1; + } + + /** + * A function to find the index of a given element + * @param o the element that is searched for + * @return the index of the element if found. (if not found then -1) + */ + @Override + @Primitive + public int indexOf(Object o) { +#if TYPE_OBJECT + if(o == null) { + for(int i = 0,m=data.length;i=0;i--) + if(data[i] == null) return i; + return -1; + } +#else + if(o == null) return -1; +#endif + for(int i = data.length - 1;i>=0;i--) { + if(EQUALS_KEY_TYPE(data[i], o)) return i; + } + return -1; + } + +#if TYPE_OBJECT + @Override + public void sort(Comparator c) { throw new UnsupportedOperationException(); } + @Override + public void unstableSort(Comparator c) { throw new UnsupportedOperationException(); } + +#else + /** + * A Type Specific implementation of the Collection#contains function. + * @param e the element that is searched for. + * @return if the element was found + */ + @Override + public boolean contains(KEY_TYPE e) { + return indexOf(e) != -1; + } + + /** + * A Type-Specific function to find the index of a given element + * @param e the element that is searched for + * @return the index of the element if found. (if not found then -1) + */ + @Override + public int indexOf(KEY_TYPE e) { + for(int i = 0,m=data.length;i=0;i--) { + if(KEY_EQUALS(data[i], e)) return i; + } + return -1; + } + + @Override + public void sort(COMPARATOR c) { throw new UnsupportedOperationException(); } + @Override + public void unstableSort(COMPARATOR c) { throw new UnsupportedOperationException(); } + +#endif + /** + * A Type-Specific get function to reduce (un)boxing + * @param index the index of the element to fetch + * @return the value of the requested index + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public KEY_TYPE GET_KEY(int index) { + checkRange(index); + return data[index]; + } + + /** + * A Type Specific foreach function that reduces (un)boxing + * + * @implSpec + *

The default implementation behaves as if: + *

{@code
+     *     for(int i = 0;i
+     *
+     * @param action The action to be performed for each element
+     * @throws NullPointerException if the specified action is null
+     * @see Iterable#forEach(java.util.function.Consumer)
+     */
+	@Override
+	public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
+		Objects.requireNonNull(action);
+		for(int i = 0,m=data.length;i o) { throw new UnsupportedOperationException(); }
+#if PRIMITIVES
+	@Override
+	public void REPLACE(JAVA_UNARY_OPERATOR o) { throw new UnsupportedOperationException(); }
+#endif
+	@Override
+	public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); }
+
+#if !TYPE_OBJECT
+	@Override
+	public boolean REMOVE_KEY(KEY_TYPE type) { throw new UnsupportedOperationException(); }
+
+#endif
+	@Override
+	@Primitive
+	public boolean removeAll(Collection c) { throw new UnsupportedOperationException(); }
+	@Override
+	@Primitive
+	public boolean retainAll(Collection c) { throw new UnsupportedOperationException(); }
+	@Override
+	@Primitive
+	public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); }
+	@Override
+	public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
+	@Override
+	public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
+	
+#if PRIMITIVES
+	@Override
+	public boolean remIf(JAVA_PREDICATE filter) { throw new UnsupportedOperationException(); }
+	
+#endif
+	/**
+	 * A toArray implementation that ensures the Array itself is a Object.
+	 * @return a Array of the elements in the list
+	 */
+	@Override
+	@Primitive
+	public Object[] toArray() {
+		Object[] obj = new Object[data.length];
+		for(int i = 0,m=data.length;i E[] toArray(E[] a) {
+		if(a == null) a = (E[])new Object[data.length];
+		else if(a.length < data.length) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), data.length);
+		for(int i = 0,m=data.length;i= data.length)
+			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length);
+	}
+	
+#if PRIMITIVES
+	/**
+	 * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
+	 * @return a Stream of the closest java type
+	 * @note characteristics are ordered, sized, subsized
+	 */
+	@Override
+	public JAVA_STREAM primitiveStream() { return StreamSupport.NEW_STREAM(SPLIT_ITERATORS.createArrayJavaSplititerator(data, data.length, 16464), false); }
+	
+#endif
+	/**
+	 * A Type Specific Type Splititerator to reduce boxing/unboxing
+	 * @return type specific splititerator
+	 * @note characteristics are ordered, sized, subsized
+	 */
+	@Override
+	public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); }
+}
\ No newline at end of file
diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template
index 54afbdef..d9f359dd 100644
--- a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template
+++ b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template
@@ -10,6 +10,9 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR;
 import java.util.Comparator;
 
 #endif
+import speiger.src.collections.PACKAGE.collections.ITERATOR;
+import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
+import speiger.src.collections.PACKAGE.utils.ITERATORS;
 import speiger.src.collections.utils.SanityChecks;
 
 /**
@@ -111,6 +114,28 @@ public class ARRAYS
 	}
 	
 #endif
+	/**
+	 * A Helper function that pours all elements of a iterator into a Array
+	 * @param iter the elements that should be gathered.
+	 * @ArrayType(T)
+	 * @return array with all elements of the iterator
+	 */
+	public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter) {
+		return pour(iter, Integer.MAX_VALUE);
+	}
+	
+	/**
+	 * A Helper function that pours all elements of a iterator into a Array
+	 * @param iter the elements that should be gathered.
+	 * @param max how many elements should be added
+	 * @ArrayType(T)
+	 * @return array with all requested elements of the iterator
+	 */
+	public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) {
+		ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
+		ITERATORS.pour(iter, list, max);
+		return list.TO_ARRAY(NEW_KEY_ARRAY(list.size()));
+	}
 	/**
 	 * Method to validate if the current value is the lowest value in the heap
 	 * @param data the current heap.
diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template
index efb8f86d..01032b9e 100644
--- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template
+++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template
@@ -3,8 +3,11 @@ package speiger.src.collections.PACKAGE.utils;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import speiger.src.collections.PACKAGE.collections.ITERATOR;
+import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
+import speiger.src.collections.PACKAGE.lists.LIST;
 import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
 import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
+import speiger.src.collections.PACKAGE.collections.COLLECTION;
 
 /**
  * A Helper class for Iterators
@@ -78,18 +81,16 @@ public class ITERATORS
 	public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE unmodifiable(LIST_ITERATOR KEY_GENERIC_TYPE iterator) {
 		return iterator instanceof UnmodifiableListIterator ? iterator : new UnmodifiableListIteratorBRACES(iterator);
 	}
-	
-#if !TYPE_OBJECT
-	/**
+		/**
 	 * Helper function to convert a Object Iterator into a Primitive Iterator
 	 * @param iterator that should be converted to a unboxing iterator
+	 * @ArrayType(T)
 	 * @return a primitive iterator
 	 */
-	public static ITERATOR wrap(Iterator iterator) {
-		return iterator instanceof ITERATOR ? (ITERATOR)iterator : new IteratorWrapper(iterator);
+	public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE wrap(Iterator iterator) {
+		return iterator instanceof ITERATOR ? (ITERATOR KEY_GENERIC_TYPE)iterator : new IteratorWrapperBRACES(iterator);
 	}
 	
-#endif
 	/**
 	 * Returns a Array Wrapping iterator
 	 * @param a the array that should be wrapped
@@ -197,28 +198,6 @@ public class ITERATORS
 		return index;
 	}
 	
-	/**
-	 * Helper Iterator that concats other iterators together
-	 * @param array the Iterators that should be concatenated
-	 * @ArrayType(T)
-	 * @return iterator of the inputted iterators
-	 */
-	public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE concat(ITERATOR KEY_GENERIC_TYPE... array) {
-		return concat(array, 0, array.length);
-	}
-	
-	/**
-	 * Helper Iterator that concats other iterators together
-	 * @param array the Iterators that should be concatenated
-	 * @param offset where to start within the array
-	 * @param length the length of the array
-	 * @ArrayType(T)
-	 * @return iterator of the inputted iterators
-	 */
-	public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE concat(ITERATOR KEY_GENERIC_TYPE[] array, int offset, int length) {
-		return new ConcatIteratorBRACES(array, offset, length);
-	}
-	
 #if !TYPE_OBJECT
 	/**
 	 * A Function to convert a Primitive Iterator to a Object array.
@@ -264,11 +243,84 @@ public class ITERATORS
 		return index;
 	}
 	
-	private static class IteratorWrapper implements ITERATOR
+#endif
+	/**
+	 * A Helper function to pours all elements of a Iterator into a List
+	 * @param iter the elements that should be poured into list.
+	 * @ArrayType(T)
+	 * @return A list of all elements of the Iterator
+	 */
+	public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE pour(ITERATOR KEY_GENERIC_TYPE iter) {
+		return pour(iter, Integer.MAX_VALUE);
+	}
+	
+	/**
+	 * A Helper function to pours all elements of a Iterator into a List
+	 * @param iter the elements that should be poured into list.
+	 * @param max the maximum amount of elements that should be collected
+	 * @ArrayType(T)
+	 * @return A list of all requested elements of the Iterator
+	 */
+	public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE pour(ITERATOR KEY_GENERIC_TYPE iter, int max) {
+		ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
+		pour(iter, list, max);
+		list.trim();
+		return list;
+	}
+	
+	/**
+	 * A Helper function to pours all elements of a Iterator into a Collection
+	 * @param iter the elements that should be poured into list.
+	 * @param c the collection where the elements should be poured into
+	 * @ArrayType(T)
+	 * @return the amount of elements that were added
+	 */
+	public static GENERIC_KEY_BRACES int pour(ITERATOR KEY_GENERIC_TYPE iter, COLLECTION KEY_GENERIC_TYPE c) {
+		return pour(iter, c, Integer.MAX_VALUE);
+	}
+	
+	/**
+	 * A Helper function to pours all elements of a Iterator into a Collection
+	 * @param iter the elements that should be poured into list.
+	 * @param c the collection where the elements should be poured into
+	 * @param max the maximum amount of elements that should be collected
+	 * @ArrayType(T)
+	 * @return the amount of elements that were added
+	 */
+	public static GENERIC_KEY_BRACES int pour(ITERATOR KEY_GENERIC_TYPE iter, COLLECTION KEY_GENERIC_TYPE c, int max) {
+		if(max < 0) throw new IllegalStateException("Max is negative");
+		int done = 0;
+		for(;done iter;
+		Iterator iter;
 		
-		public IteratorWrapper(Iterator iter) {
+		public IteratorWrapper(Iterator iter) {
 			this.iter = iter;
 		}
 		
@@ -282,14 +334,15 @@ public class ITERATORS
 			return OBJ_TO_KEY(iter.next());
 		}
 		
+#if !TYPE_OBJECT
 		@Override
 		@Deprecated
 		public CLASS_TYPE next() {
 			return iter.next();
 		}
+#endif
 	}
 	
-#endif
 	private static class ConcatIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
 	{
 		ITERATOR KEY_GENERIC_TYPE[] iters;