Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template

433 lines
11 KiB
Plaintext

package speiger.src.collections.PACKAGE.lists;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
* Abstract implementation of the {@link LIST} interface.
*/
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
/**
* A Type-Specific implementation of add function that delegates to {@link #add(int, KEY_TYPE)}
*/
@Override
public boolean add(KEY_TYPE e) {
add(size(), e);
return true;
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public void add(int index, CLASS_TYPE element) {
add(index, OBJ_TO_KEY(element));
}
#endif
/**
* A Type-Specific implementation that iterates over the elements and adds them.
* @param c the elements that wants to be added
* @return true if the list was modified
*/
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
}
/**
* A Type-Specific implementation that iterates over the elements and adds them.
* @param c the elements that wants to be added
* @return true if the list was modified
*/
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) {
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
}
/**
* The IndexOf implementation iterates over all elements and compares them to the search value.
* @param o the value that the index is searched for.
* @return index of the value that was searched for. -1 if not found
* @deprecated it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
*/
@Override
@Primitive
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;
}
/**
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
* @param o the value that the index is searched for.
* @return the last index of the value that was searched for. -1 if not found
* @deprecated it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
*/
@Override
@Primitive
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
/**
* The indexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return index of the value that was searched for. -1 if not found
*/
@Override
public int indexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
while(iter.hasNext()) {
if(KEY_EQUALS(iter.NEXT(), e))
return iter.previousIndex();
}
return -1;
}
/**
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return the last index of the value that was searched for. -1 if not found
*/
@Override
public int lastIndexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
while(iter.hasPrevious()) {
if(KEY_EQUALS(iter.PREVIOUS(), e))
return iter.nextIndex();
}
return -1;
}
#endif
/**
* Compares if the list are the same.
*/
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
List<?> l = (List<?>)o;
if(l.size() != size()) return false;
#if !TYPE_OBJECT
if(l instanceof LIST)
{
LIST_ITERATOR e1 = listIterator();
LIST_ITERATOR e2 = ((LIST)l).listIterator();
while (e1.hasNext() && e2.hasNext()) {
if(!(KEY_EQUALS(e1.NEXT(), e2.NEXT())))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
#endif
ListIterator<CLASS_TYPE> e1 = listIterator();
ListIterator<?> e2 = l.listIterator();
while (e1.hasNext() && e2.hasNext()) {
if(!Objects.equals(e1.next(), e2.next()))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
/**
* Generates the hashcode based on the values stored in the list.
*/
@Override
public int hashCode() {
int hashCode = 1;
LIST_ITERATOR KEY_GENERIC_TYPE i = listIterator();
while(i.hasNext())
#if TYPE_OBJECT
hashCode = 31 * hashCode + i.next().hashCode();
#else
hashCode = 31 * hashCode + KEY_TO_HASH(i.NEXT());
#endif
return hashCode;
}
@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);
}
@Override
public void size(int size) {
while(size > size()) add(EMPTY_KEY_VALUE);
while(size < size()) REMOVE(size() - 1);
}
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++;
}
@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;
}
@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;
}
@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 void addElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
l.addElements(from + this.offset, a, offset, length);
size += length;
}
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
return l.getElements(from + this.offset, a, offset, length);
}
@Override
public void removeElements(int from, int to) {
checkRange(from);
checkRange(to);
l.removeElements(from + offset, to + offset);
size -= to - from;
}
#if TYPE_OBJECT
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) {
checkRange(from);
checkRange(to);
K[] a = l.extractElements(from + offset, to + offset, clz);
size -= to - from;
return a;
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
checkRange(from);
checkRange(to);
KEY_TYPE[] a = l.extractElements(from + offset, to + offset);
size -= to - from;
return a;
}
#endif
@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() {
lastReturned = index;
return GET_KEY(index++);
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = index;
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;
}
}
}