New Content patch getting big progress on base and progress on lists.

-Changed: Build Task no longer Sync's because it is 9x slower and a File Builder never collides with another File Builder.
-Added: getEquals() function for faster compare builders.
-Changed: getNonClassType to getNonFileType()
-Added: New Rule to the Rule Sheet.
-Added: Regex Helper so recursion is supported
-Added: FunctionMapper that supports more then 1 argument.
-Changed: Injection & FunctionMapper support recursion-
-Added: Loads of Variables to the GlobalVariables as they were added for templates.
-Added: AbstractCollection, AbstractList, List, ListIterator, BidirectionalIterator, Arrays and ArrayList template.
This commit is contained in:
Speiger 2020-11-16 02:55:33 +01:00
parent c61c8a7806
commit 5cc4f35407
19 changed files with 995 additions and 29 deletions

View File

@ -12,5 +12,6 @@ Some Base Rules:
- Function overloads should be avoided. They are only causing problems. - Function overloads should be avoided. They are only causing problems.
- If a primitive function would cause a overload then a rename should try to add a shortened primitive name in it. If that destroys the naming flow then a cut version name. If that does not work a new rule has to be made up. Example: "get -> getInt" while "removeIf => removeIfInt" does not work so we default to "removeIf => remIf". - If a primitive function would cause a overload then a rename should try to add a shortened primitive name in it. If that destroys the naming flow then a cut version name. If that does not work a new rule has to be made up. Example: "get -> getInt" while "removeIf => removeIfInt" does not work so we default to "removeIf => remIf".
- If a function would break the java interface rules (ArrayList.trimToSize) a dedicated interface should be created for it. - If a function would break the java interface rules (ArrayList.trimToSize) a dedicated interface should be created for it.
- If a #if is wrapping a function the #if always starts after a empty new line and the #endif always has a empty new line before itself. That way empty lines match up no matter the type
Rules can be added or altered, but should only be so if there is a real reason to be present. Rules can be added or altered, but should only be so if there is a real reason to be present.

View File

@ -37,9 +37,9 @@ public enum ClassType
return classType; return classType;
} }
public String getNonClassType() public String getNonFileType()
{ {
return this == OBJECT ? "" : classType; return this == OBJECT ? "" : fileType;
} }
public String getFileType() public String getFileType()
@ -67,6 +67,17 @@ public enum ClassType
return this == BYTE || this == SHORT || this == CHAR || this == FLOAT; return this == BYTE || this == SHORT || this == CHAR || this == FLOAT;
} }
public String getEquals()
{
switch(this)
{
case DOUBLE: return "Double.doubleToLongBits(%1$s) == Double.doubleToLongBits(%2$s)";
case FLOAT: return "Float.floatToIntBits(%1$s) == Float.floatToIntBits(%2$s)";
case OBJECT: return "Objects.equals(%1$s, %2$s)";
default: return "%1$s == %2$s";
}
}
public ClassType getCustomJDKType() public ClassType getCustomJDKType()
{ {
switch(this) switch(this)

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.ArgumentMapper;
import speiger.src.builder.mappers.InjectMapper; import speiger.src.builder.mappers.InjectMapper;
import speiger.src.builder.mappers.SimpleMapper; import speiger.src.builder.mappers.SimpleMapper;
import speiger.src.builder.processor.TemplateProcess; import speiger.src.builder.processor.TemplateProcess;
@ -28,15 +29,23 @@ public class GlobalVariables
addSimpleMapper("CLASS_TYPE", type.getClassType()); addSimpleMapper("CLASS_TYPE", type.getClassType());
addSimpleMapper("KEY_TYPE", type.getKeyType()); addSimpleMapper("KEY_TYPE", type.getKeyType());
addSimpleMapper(" KEY_GENERIC_TYPE", type == ClassType.OBJECT ? "<"+type.getKeyType()+">" : ""); addSimpleMapper(" KEY_GENERIC_TYPE", type == ClassType.OBJECT ? "<"+type.getKeyType()+">" : "");
addSimpleMapper(" GENERIC_BRACES", type == ClassType.OBJECT ? " <"+type.getKeyType()+">" : "");
addSimpleMapper("BRACES", type == ClassType.OBJECT ? "<>" : "");
if(type.needsCustomJDKType()) if(type.needsCustomJDKType())
{ {
addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType()); addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType());
addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType()); addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType());
} }
return this;
}
public GlobalVariables createHelperVariables()
{
addArgumentMapper("EQUALS_KEY_TYPE", type == ClassType.OBJECT ? "Objects.equals(%1$s, %2$s)" : "Objects.equals(KEY_TO_OBJ(%1$s), %2$s)").removeBraces();
addArgumentMapper("EQUALS", type.getEquals()).removeBraces();
addSimpleMapper("KEY_TO_OBJ", type.getClassType()+".valueOf"); addSimpleMapper("KEY_TO_OBJ", type.getClassType()+".valueOf");
addInjectMapper("OBJ_TO_KEY(\\([^)]+\\)|\\S)", "%s."+type.getKeyType()+"Value()").removeBraces(); addInjectMapper("OBJ_TO_KEY", type == ClassType.OBJECT ? "%s" : "%s."+type.getKeyType()+"Value()").removeBraces();
addInjectMapper("CLASS_TO_KEY(\\([^)]+\\)|\\S)", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces(); addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces();
return this; return this;
} }
@ -44,17 +53,31 @@ public class GlobalVariables
{ {
addSimpleMapper("JAVA_PREDICATE", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Predicate"); addSimpleMapper("JAVA_PREDICATE", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Predicate");
addSimpleMapper("JAVA_CONSUMER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Consumer"); addSimpleMapper("JAVA_CONSUMER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Consumer");
addSimpleMapper("CONSUMER", type.getFileType()+"Consumer"); addClassMapper("CONSUMER", "Consumer");
addSimpleMapper("ITERATOR", type.getFileType()+"Iterator"); addClassMapper("ITERATORS", "Iterators");
addSimpleMapper("ITERABLE", type.getFileType()+"Iterable"); addClassMapper("BI_ITERATOR", "BidirectionalIterator");
addSimpleMapper("ABSTRACT_COLLECTION", type.getFileType()+"AbstractCollection"); addClassMapper("LIST_ITERATOR", "ListIterator");
addSimpleMapper("COLLECTION", type.getFileType()+"Collection"); addClassMapper("ITERATOR", "Iterator");
addClassMapper("ITERABLE", "Iterable");
addClassMapper("ABSTRACT_COLLECTION", "AbstractCollection");
addClassMapper("COLLECTION", "Collection");
addClassMapper("ARRAYS", "Arrays");
addClassMapper("ABSTRACT_LIST", "AbstractList");
addClassMapper("LIST_ITER", "ListIter");
addClassMapper("SUB_LIST", "SubList");
addClassMapper("ARRAY_LIST", "ArrayList");
addClassMapper("LIST", "List");
return this; return this;
} }
public GlobalVariables createFunctions() public GlobalVariables createFunctions()
{ {
addSimpleMapper("NEXT()", "next"+type.getNonClassType()+"()"); addFunctionMapper("NEXT", "next");
addSimpleMapper("TO_ARRAY", "to"+type.getNonFileType()+"Array");
addFunctionMapper("GET_KEY", "get");
addFunctionMapper("REMOVE_KEY", "rem");
addFunctionMapper("REMOVE", "remove");
addFunctionMapper("PREVIOUS", "previous");
return this; return this;
} }
@ -86,6 +109,16 @@ public class GlobalVariables
return type; return type;
} }
private void addClassMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(pattern, type.getFileType()+replacement));
}
private void addFunctionMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(pattern, replacement+type.getNonFileType()));
}
private void addSimpleMapper(String pattern, String replacement) private void addSimpleMapper(String pattern, String replacement)
{ {
operators.add(new SimpleMapper(pattern, replacement)); operators.add(new SimpleMapper(pattern, replacement));
@ -98,6 +131,18 @@ public class GlobalVariables
return mapper; return mapper;
} }
private ArgumentMapper addArgumentMapper(String pattern, String replacement)
{
return addArgumentMapper(pattern, replacement, ", ");
}
private ArgumentMapper addArgumentMapper(String pattern, String replacement, String splitter)
{
ArgumentMapper mapper = new ArgumentMapper(pattern, replacement, splitter);
operators.add(mapper);
return mapper;
}
class PathBuilder implements UnaryOperator<Path> class PathBuilder implements UnaryOperator<Path>
{ {
String before; String before;

View File

@ -45,6 +45,7 @@ public class TestBuilder extends TemplateProcessor
{ {
GlobalVariables type = new GlobalVariables(clzType); GlobalVariables type = new GlobalVariables(clzType);
type.createFlags(); type.createFlags();
type.createHelperVariables();
type.createVariables(); type.createVariables();
type.createClassTypes(); type.createClassTypes();
type.createFunctions(); type.createFunctions();

View File

@ -0,0 +1,65 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import speiger.src.builder.misc.RegexUtil;
public class ArgumentMapper implements UnaryOperator<String>
{
Pattern pattern;
String replacement;
String argumentBreaker;
String braces = "()";
boolean removeBraces;
public ArgumentMapper(String pattern, String replacement, String argumentBreaker)
{
this.pattern = Pattern.compile(pattern);
this.replacement = replacement;
this.argumentBreaker = argumentBreaker;
}
public ArgumentMapper setBraceType(String s)
{
if(s.length() != 2) throw new IllegalStateException("Start and End char only");
braces = s;
return this;
}
public ArgumentMapper removeBraces()
{
removeBraces = true;
return this;
}
@Override
public String apply(String t)
{
Matcher matcher = pattern.matcher(t);
if(matcher.find())
{
StringBuffer buffer = new StringBuffer();
do
{
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
{
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
buffer.append(String.format(replacement, (Object[])getString(text).split(argumentBreaker)));
}
}
while(matcher.find());
matcher.appendTail(buffer);
return buffer.toString();
}
return t;
}
protected String getString(String s)
{
return removeBraces ? s.substring(1, s.length() - 1) : s;
}
}

View File

@ -4,10 +4,13 @@ import java.util.function.UnaryOperator;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import speiger.src.builder.misc.RegexUtil;
public class InjectMapper implements UnaryOperator<String> public class InjectMapper implements UnaryOperator<String>
{ {
Pattern pattern; Pattern pattern;
String replacement; String replacement;
String braces = "()";
boolean removeBraces; boolean removeBraces;
public InjectMapper(String pattern, String replacement) public InjectMapper(String pattern, String replacement)
@ -16,6 +19,13 @@ public class InjectMapper implements UnaryOperator<String>
this.replacement = replacement; this.replacement = replacement;
} }
public InjectMapper setBraceType(String s)
{
if(s.length() != 2) throw new IllegalStateException("Start and End char only");
braces = s;
return this;
}
public InjectMapper removeBraces() public InjectMapper removeBraces()
{ {
removeBraces = true; removeBraces = true;
@ -29,7 +39,14 @@ public class InjectMapper implements UnaryOperator<String>
if(matcher.find()) if(matcher.find())
{ {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
do { matcher.appendReplacement(buffer, String.format(replacement, getString(matcher.group(1)))); do
{
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
{
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
buffer.append(String.format(replacement, getString(text)));
}
} while (matcher.find()); } while (matcher.find());
matcher.appendTail(buffer); matcher.appendTail(buffer);
return buffer.toString(); return buffer.toString();
@ -37,7 +54,7 @@ public class InjectMapper implements UnaryOperator<String>
return t; return t;
} }
private String getString(String s) protected String getString(String s)
{ {
return removeBraces ? s.substring(1, s.length() - 1) : s; return removeBraces ? s.substring(1, s.length() - 1) : s;
} }

View File

@ -0,0 +1,68 @@
package speiger.src.builder.misc;
import java.lang.reflect.Field;
import java.util.regex.Matcher;
public class RegexUtil
{
static Field LAST_POS;
public static Matcher skip(Matcher matcher, int amount)
{
try
{
LAST_POS.setInt(matcher, LAST_POS.getInt(matcher) + amount);
}
catch(Exception e)
{
e.printStackTrace();
}
return matcher;
}
public static String searchUntil(String text, int startIndex, char increase, char decrease)
{
if(text.charAt(startIndex + 1) != increase)
{
return "";
}
int inc = 0;
StringBuilder builder = new StringBuilder();
for(int i = startIndex + 1;i<text.length();i++)
{
char current = text.charAt(i);
if(current == '\\' && i < text.length() - 1 && text.charAt(i+1) == 'n')
{
return "";
}
else if(current == increase)
{
inc++;
}
else if(current == decrease)
{
inc--;
if(inc <= 0)
{
return builder.append(decrease).toString();
}
}
builder.append(current);
}
return "";
}
static
{
try
{
Field field = Matcher.class.getDeclaredField("lastAppendPosition");
field.setAccessible(true);
LAST_POS = field;
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

View File

@ -32,7 +32,7 @@ public class BuildTask implements Runnable
catch(Exception e) catch(Exception e)
{ {
} }
try(BufferedWriter writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.SYNC)) try(BufferedWriter writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE))
{ {
writer.write(s); writer.write(s);
writer.flush(); writer.flush();

View File

@ -0,0 +1,17 @@
package speiger.src.collections.utils;
import java.util.Iterator;
public interface BidirectionalIterator<E> extends Iterator<E>
{
public E previous();
public boolean hasPrevious();
public default int back(int amount) {
if(amount < 0) throw new IllegalStateException("Can't go forward");
int i = 0;
for(;i<amount && hasPrevious();previous(),i++);
return i;
}
}

View File

@ -1,13 +1,19 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import java.util.Collection;
#endif
import java.util.AbstractCollection; import java.util.AbstractCollection;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractCollection<CLASS_TYPE> implements COLLECTION KEY_GENERIC_TYPE public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractCollection<CLASS_TYPE> implements COLLECTION KEY_GENERIC_TYPE
{ {
@Override @Override
public abstract ITERATOR KEY_GENERIC_TYPE iterator(); public abstract ITERATOR KEY_GENERIC_TYPE iterator();
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean add(CLASS_TYPE e) { return COLLECTION.super.add(e); } public boolean add(CLASS_TYPE e) { return COLLECTION.super.add(e); }
@ -31,6 +37,30 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
return false; return false;
} }
@Override
public boolean containsAll(Collection<?> c)
{
return c instanceof COLLECTION ? containsAll((COLLECTION)c) : super.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends CLASS_TYPE> c)
{
return c instanceof COLLECTION ? addAll((COLLECTION)c) : super.addAll(c);
}
@Override
public boolean removeAll(Collection<?> c)
{
return c instanceof COLLECTION ? removeAll((COLLECTION)c) : super.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c)
{
return c instanceof COLLECTION ? retainAll((COLLECTION)c) : super.retainAll(c);
}
@Override @Override
public boolean containsAll(COLLECTION c) { public boolean containsAll(COLLECTION c) {
for(KEY_TYPE e : c) for(KEY_TYPE e : c)
@ -51,6 +81,17 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Deprecated @Deprecated
public boolean remove(Object e) { return COLLECTION.super.remove(e); } public boolean remove(Object e) { return COLLECTION.super.remove(e); }
@Override
public boolean REMOVE_KEY(KEY_TYPE e) {
for(ITERATOR iter = iterator();iter.hasNext();) {
if(EQUALS(iter.NEXT(), e)) {
iter.remove();
return true;
}
}
return false;
}
@Override @Override
public boolean removeAll(COLLECTION c) { public boolean removeAll(COLLECTION c) {
boolean modified = false; boolean modified = false;
@ -74,5 +115,15 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
} }
return modified; return modified;
} }
public KEY_TYPE[] TO_ARRAY() {
return TO_ARRAY(new KEY_TYPE[size()]);
}
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
ITERATORS.unwrap(a, iterator());
return a;
}
#endif #endif
} }

View File

@ -0,0 +1,28 @@
package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else
import speiger.src.collections.utils.BidirectionalIterator;
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, BidirectionalIterator<CLASS_TYPE>
#endif
{
public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT
@Override
@Deprecated
public default CLASS_TYPE previous() {
return KEY_TO_OBJ(PREVIOUS());
}
@Override
default int skip(int amount)
{
return ITERATOR.super.skip(amount);
}
#endif
}

View File

@ -19,7 +19,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
public boolean containsAny(COLLECTION c); public boolean containsAny(COLLECTION c);
public boolean remove(KEY_TYPE o); public boolean REMOVE_KEY(KEY_TYPE o);
public boolean removeAll(COLLECTION c); public boolean removeAll(COLLECTION c);
@ -43,7 +43,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
return removed; return removed;
} }
#endif #endif
@Override @Override
@Deprecated @Deprecated
public default boolean add(CLASS_TYPE o) { return add(OBJ_TO_KEY(o)); } public default boolean add(CLASS_TYPE o) { return add(OBJ_TO_KEY(o)); }
@ -56,14 +56,6 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
@Deprecated @Deprecated
public default boolean remove(Object o) { return o != null && remove(CLASS_TO_KEY(o)); } public default boolean remove(Object o) { return o != null && remove(CLASS_TO_KEY(o)); }
@Override
@Deprecated
public <K> K[] toArray(K[] a);
@Override
@Deprecated
public Object[] toArray();
#endif #endif
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator(); public ITERATOR KEY_GENERIC_TYPE iterator();

View File

@ -16,7 +16,7 @@ public interface ITERATOR KEY_GENERIC_TYPE extends Iterator<CLASS_TYPE>
@Deprecated @Deprecated
@Override @Override
public default CLASS_TYPE next() { return KEY_TO_OBJ(next()); } public default CLASS_TYPE next() { return KEY_TO_OBJ(NEXT()); }
public default void forEachRemaining(CONSUMER action) { public default void forEachRemaining(CONSUMER action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@ -33,8 +33,8 @@ public interface ITERATOR KEY_GENERIC_TYPE extends Iterator<CLASS_TYPE>
#endif #endif
default int skip(int amount) { default 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");
int temp = amount; int i = 0;
for(;amount > 0 && hasNext();NEXT(), amount--); for(;i<amount && hasNext();NEXT(), i++);
return temp - amount; return i;
} }
} }

View File

@ -0,0 +1,296 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.Collection;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
@Override
public boolean add(KEY_TYPE e) {
add(size(), e);
return true;
}
@Override
public boolean addAll(COLLECTION c) {
boolean modified = false;
for(KEY_TYPE e : c)
modified |= add(e);
return modified;
}
#endif
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) {
boolean modified = false;
for(KEY_TYPE e : c)
modified |= add(e);
return modified;
}
@Override
public int indexOf(Object o) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
#if TYPE_OBJECT
if(o == null) {
while(iter.hasNext()) {
if(iter.NEXT() == null)
return iter.previousIndex();
}
return -1;
}
#else
if(o == null) return -1;
#endif
while(iter.hasNext()) {
if(EQUALS_KEY_TYPE(iter.NEXT(), o))
return iter.previousIndex();
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
#if TYPE_OBJECT
if(o == null) {
while(iter.hasPrevious()) {
if(iter.PREVIOUS() == null)
return iter.nextIndex();
}
return -1;
}
#else
if(o == null) return -1;
#endif
while(iter.hasPrevious()) {
if(EQUALS_KEY_TYPE(iter.PREVIOUS(), o))
return iter.nextIndex();
}
return -1;
}
#if !TYPE_OBJECT
@Override
public int indexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
while(iter.hasNext()) {
if(EQUALS(iter.NEXT(), e))
return iter.previousIndex();
}
return -1;
}
@Override
public int lastIndexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
while(iter.hasPrevious()) {
if(EQUALS(iter.PREVIOUS(), e))
return iter.nextIndex();
}
return -1;
}
#endif
@Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
return new SUB_LIST(this, fromIndex, toIndex);
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return listIterator(0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return listIterator(0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
return new LIST_ITER(index);
}
private class SUB_LIST extends ABSTRACT_LIST KEY_GENERIC_TYPE {
ABSTRACT_LIST KEY_GENERIC_TYPE l;
int offset;
int size;
SUB_LIST(ABSTRACT_LIST KEY_GENERIC_TYPE l, int from, int to) {
if (from < 0) throw new IndexOutOfBoundsException("fromIndex = " + from);
else if (to > l.size()) throw new IndexOutOfBoundsException("toIndex = " + to);
else if (from > to) throw new IllegalArgumentException("fromIndex(" + from + ") > toIndex(" + to + ")");
this.l = l;
offset = from;
size = to - from;
}
@Override
public void add(int index, KEY_TYPE e) {
checkAddRange(index);
l.add(index+offset, e);
size++;
}
#if !TYPE_OBJECT
@Override
public void add(int index, CLASS_TYPE element) {
add(index, OBJ_TO_KEY(element));
}
#endif
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
#if !TYPE_OBJECT
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
#endif
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
@Override
public KEY_TYPE GET_KEY(int index) {
checkRange(index);
return l.GET_KEY(index + offset);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
checkRange(index);
return l.set(index + offset, e);
}
@Override
public KEY_TYPE REMOVE(int index) {
checkRange(index);
size--;
return l.REMOVE(index + offset);
}
@Override
public int size() {
return size;
}
private void checkRange(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
private void checkAddRange(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
int lastReturned = -1;
LIST_ITER(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
}
@Override
public KEY_TYPE NEXT() {
return GET_KEY(index++);
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
return GET_KEY(index--);
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.REMOVE(lastReturned);
if(lastReturned < index)
index--;
lastReturned = -1;
}
@Override
public void set(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.set(lastReturned, e);
}
@Override
public void add(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.add(index++, e);
lastReturned = -1;
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index);
index += steps;
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
return steps;
}
}
}

View File

@ -0,0 +1,147 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.Collection;
import java.util.Iterator;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
{
transient KEY_TYPE[] data;
private int size = 0;
public ARRAY_LIST(int size)
{
#if TYPE_OBJECT
data = (KEY_TYPE[])new Object[size];
#else
data = new KEY_TYPE[size];
#endif
}
@Override
public void add(int index, CLASS_TYPE element)
{
checkAddRange(index);
ensureCapacity(size + 1);
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
data[index] = OBJ_TO_KEY(element);
size++;
}
@Override
public boolean add(KEY_TYPE e)
{
ensureCapacity(size + 1);
data[size++] = e;
return true;
}
#if !TYPE_OBJECT
@Override
public void add(int index, KEY_TYPE e)
{
checkAddRange(index);
ensureCapacity(size + 1);
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
data[index] = e;
size++;
}
#endif
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c)
{
#if !TYPE_OBJECT
if(c instanceof COLLECTION) return addAll((COLLECTION)c);
#endif
int add = c.size();
if(add <= 0) return false;
ensureCapacity(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
Iterator<? extends CLASS_TYPE> iter = c.iterator();
while(add != 0) data[index++] = OBJ_TO_KEY(iter.next());
return true;
}
#if !TYPE_OBJECT
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c)
{
if(c instanceof LIST) return addAll((LIST)c);
int add = c.size();
if(add <= 0) return false;
ensureCapacity(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
ITERATOR KEY_GENERIC_TYPE iter = c.iterator();
while(add != 0) data[index++] = iter.NEXT();
return true;
}
#endif
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c)
{
return false;
}
@Override
public KEY_TYPE GET_KEY(int index)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
return data[index];
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
KEY_TYPE old = data[index];
data[index] = e;
return old;
}
@Override
public KEY_TYPE REMOVE(int index)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
KEY_TYPE old = data[index];
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
data[size] = null;
#endif
size--;
return old;
}
@Override
public int size()
{
return size;
}
@Override
public void clear()
{
#if TYPE_OBJECT
for(int i = 0;i<size;data[i] = null,i++);
#endif
size = 0;
}
protected void ensureCapacity(int capacity)
{
}
protected void checkAddRange(int index)
{
}
}

View File

@ -0,0 +1,90 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.List;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List<CLASS_TYPE>
{
#if !TYPE_OBJECT
public boolean add(KEY_TYPE e);
public void add(int index, KEY_TYPE e);
public boolean addAll(int index, COLLECTION c);
#endif
public boolean addAll(LIST KEY_GENERIC_TYPE c);
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
#if !TYPE_OBJECT
public KEY_TYPE GET_KEY(int index);
public KEY_TYPE set(int index, KEY_TYPE e);
public KEY_TYPE REMOVE(int index);
public int indexOf(KEY_TYPE e);
public int lastIndexOf(KEY_TYPE e);
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator();
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index);
@Override
public LIST KEY_GENERIC_TYPE subList(int from, int to);
#if !TYPE_OBJECT
@Override
@Deprecated
public default boolean add(CLASS_TYPE e) {
return COLLECTION.super.add(e);
}
@Override
@Deprecated
public default CLASS_TYPE get(int index) {
return KEY_TO_OBJ(GET_KEY(index));
}
@Override
@Deprecated
public default CLASS_TYPE set(int index, CLASS_TYPE e) {
return KEY_TO_OBJ(set(index, OBJ_TO_KEY(e)));
}
@Override
@Deprecated
public default int indexOf(Object o) {
return indexOf(CLASS_TO_KEY(o));
}
@Override
@Deprecated
public default int lastIndexOf(Object o) {
return indexOf(CLASS_TO_KEY(o));
}
@Override
@Deprecated
public default boolean contains(Object o) {
return COLLECTION.super.contains(o);
}
@Override
@Deprecated
public default boolean remove(Object o) {
return COLLECTION.super.remove(o);
}
@Override
@Deprecated
public default CLASS_TYPE remove(int index) {
return KEY_TO_OBJ(REMOVE(index));
}
#endif
}

View File

@ -0,0 +1,38 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.ListIterator;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
public interface LIST_ITERATOR KEY_GENERIC_TYPE extends ListIterator<CLASS_TYPE>, BI_ITERATOR KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
public void set(KEY_TYPE e);
public void add(KEY_TYPE e);
@Override
@Deprecated
public default CLASS_TYPE previous() {
return BI_ITERATOR.super.previous();
}
@Override
@Deprecated
public default CLASS_TYPE next() {
return BI_ITERATOR.super.next();
}
@Override
@Deprecated
public default void set(CLASS_TYPE e) {
set(OBJ_TO_KEY(e));
}
@Override
@Deprecated
public default void add(CLASS_TYPE e) {
add(OBJ_TO_KEY(e));
}
#endif
}

View File

@ -0,0 +1,20 @@
package speiger.src.collections.PACKAGE.utils;
public class ARRAYS
{
#if !TYPE_OBJECT
public static CLASS_TYPE[] wrap(KEY_TYPE[] a) {
CLASS_TYPE[] result = new CLASS_TYPE[a.length];
for(int i = 0,m=a.length;i<m;i++)
result[i] = KEY_TO_OBJ(a[i]);
return result;
}
public static KEY_TYPE[] unwrap(CLASS_TYPE[] a) {
KEY_TYPE[] result = new KEY_TYPE[a.length];
for(int i = 0,m=a.length;i<m;i++)
result[i] = OBJ_TO_KEY(a[i]);
return result;
}
#endif
}

View File

@ -0,0 +1,79 @@
package speiger.src.collections.PACKAGE.utils;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
public class ITERATORS
{
public static GENERIC_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) {
return wrap(a, 0, a.length);
}
public static GENERIC_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int start, int end) {
return new ArrayIteratorBRACES(a, start, end);
}
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
return unwrap(a, i, 0, a.length);
}
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
return unwrap(a, i, offset, a.length);
}
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
int index = 0;
for(;index<max && i.hasNext();index++) a[index+offset] = i.NEXT();
return index;
}
#if !TYPE_OBJECT
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
return unwrap(a, i, 0, a.length);
}
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
return unwrap(a, i, offset, a.length);
}
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
int index = 0;
for(;index<max && i.hasNext();index++) a[index+offset] = KEY_TO_OBJ(i.NEXT());
return index;
}
#endif
private static class ArrayIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{
KEY_TYPE[] a;
int from;
int to;
ArrayIterator(KEY_TYPE[] a, int from, int to) {
this.a = a;
this.from = from;
this.to = to;
}
@Override
public boolean hasNext() {
return from < to;
}
@Override
public KEY_TYPE NEXT() {
return a[from++];
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int left = Math.min(amount, to - from);
from += left;
return amount - left;
}
}
}