diff --git a/.idea/artifacts/GeneralUtils_jar.xml b/.idea/artifacts/GeneralUtils_jar.xml
new file mode 100644
index 0000000..2047b5c
--- /dev/null
+++ b/.idea/artifacts/GeneralUtils_jar.xml
@@ -0,0 +1,8 @@
+
+
+ $PROJECT_DIR$/out/artifacts/GeneralUtils_jar
+
+
+
+
+
\ No newline at end of file
diff --git a/GeneralUtils.iml b/GeneralUtils.iml
index c90834f..03a7b64 100644
--- a/GeneralUtils.iml
+++ b/GeneralUtils.iml
@@ -4,8 +4,19 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/dev/asdf00/general/utils/list/PrimitiveList.java b/src/dev/asdf00/general/utils/list/PrimitiveList.java
index a955b43..a8f88ba 100644
--- a/src/dev/asdf00/general/utils/list/PrimitiveList.java
+++ b/src/dev/asdf00/general/utils/list/PrimitiveList.java
@@ -1,27 +1,26 @@
package dev.asdf00.general.utils.list;
-import dev.asdf00.general.utils.list.internal.AbstractBaseList;
-import dev.asdf00.general.utils.list.internal.ByteList;
+import dev.asdf00.general.utils.list.internal.*;
public abstract class PrimitiveList extends AbstractBaseList {
public static PrimitiveList create(Class boxedType) {
if (Byte.class == boxedType) {
return (PrimitiveList) new ByteList();
- } else if (Short.class.equals(boxedType)) {
- return null;
- } else if (Integer.class.equals(boxedType)) {
- return null;
- } else if (Long.class.equals(boxedType)) {
- return null;
- } else if (Float.class.equals(boxedType)) {
- return null;
- } else if (Double.class.equals(boxedType)) {
- return null;
- } else if (Character.class.equals(boxedType)) {
- return null;
- } else if (Boolean.class.equals(boxedType)) {
- return null;
+ } else if (Short.class == boxedType) {
+ return (PrimitiveList) new ShortList();
+ } else if (Integer.class == boxedType) {
+ return (PrimitiveList) new IntegerList();
+ } else if (Long.class == boxedType) {
+ return (PrimitiveList) new LongList();
+ } else if (Float.class == boxedType) {
+ return (PrimitiveList) new FloatList();
+ } else if (Double.class == boxedType) {
+ return (PrimitiveList) new DoubleList();
+ } else if (Character.class == boxedType) {
+ return (PrimitiveList) new CharacterList();
+ } else if (Boolean.class == boxedType) {
+ return (PrimitiveList) new BooleanList();
} else {
throw new IllegalArgumentException("%s is not a boxed type!".formatted(boxedType));
}
diff --git a/src/dev/asdf00/general/utils/list/internal/AbstractBaseList.java b/src/dev/asdf00/general/utils/list/internal/AbstractBaseList.java
index 087eba9..26a2ed1 100644
--- a/src/dev/asdf00/general/utils/list/internal/AbstractBaseList.java
+++ b/src/dev/asdf00/general/utils/list/internal/AbstractBaseList.java
@@ -37,12 +37,12 @@ public abstract class AbstractBaseList implements List {
@Override
public int size() {
- return size();
+ return size;
}
@Override
public boolean isEmpty() {
- return size() < 1;
+ return size < 1;
}
@Override
@@ -78,8 +78,12 @@ public abstract class AbstractBaseList implements List {
@Override
public boolean removeAll(Collection> c) {
boolean changed = false;
- for (Object o : c) {
- changed = remove(o) || changed;
+ ListIterator itr = listIterator();
+ while (itr.hasNext()) {
+ if (c.contains(itr.next())) {
+ itr.remove();
+ changed = true;
+ }
}
return changed;
}
@@ -89,7 +93,7 @@ public abstract class AbstractBaseList implements List {
boolean changed = false;
ListIterator itr = listIterator();
while (itr.hasNext()) {
- if (c.contains(itr.next())) {
+ if (!c.contains(itr.next())) {
itr.remove();
changed = true;
}
@@ -113,12 +117,6 @@ public abstract class AbstractBaseList implements List {
return directSet(index, element);
}
- @Override
- public boolean add(T t) {
- directSet(size++, t);
- return true;
- }
-
@Override
public ListIterator listIterator() {
return new ListItr<>(this, 0);
@@ -133,8 +131,10 @@ public abstract class AbstractBaseList implements List {
@Override
public List subList(int fromIndex, int toIndex) {
Objects.checkIndex(fromIndex, size);
- Objects.checkIndex(fromIndex, toIndex);
- int len = (toIndex - fromIndex) + 1;
+ if (toIndex < 0 || toIndex > size) {
+ throw new IndexOutOfBoundsException();
+ }
+ int len = toIndex - fromIndex;
if (len < 0) {
throw new IllegalArgumentException();
}
@@ -211,13 +211,12 @@ public abstract class AbstractBaseList implements List {
@Override
public void remove() {
checkConcurrentModification();
- Objects.checkIndex(cur, base.size);
if (last == -1) {
throw new IllegalStateException();
}
modCnt++;
- base.remove(--cur);
- last = -1;
+ base.remove(last);
+ cur--;
}
@Override
@@ -235,12 +234,16 @@ public abstract class AbstractBaseList implements List {
@Override
public void add(E e) {
checkConcurrentModification();
- Objects.checkIndex(cur, base.size);
if (last == -1) {
throw new IllegalStateException();
}
modCnt++;
- base.add(cur, e);
+ last++;
+ if (last == base.size) {
+ base.add(e);
+ } else {
+ base.add(last, e);
+ }
last = -1;
}
@@ -263,11 +266,25 @@ public abstract class AbstractBaseList implements List {
modCnt = base.modCnt;
}
+ @Override
+ public boolean add(E e) {
+ checkConcurrentModification();
+ modCnt++;
+ if (start + size == base.size) {
+ base.add(e);
+ } else {
+ base.add(start + size, e);
+ }
+ size++;
+ return true;
+ }
+
@Override
public boolean addAll(Collection extends E> c) {
for (E e : c) {
add(e);
}
+ size += c.size();
return c.size() > 0;
}
@@ -278,13 +295,15 @@ public abstract class AbstractBaseList implements List {
for (E e : c) {
add(i, e);
}
- return false;
+ size += c.size();
+ return c.size() > 0;
}
@Override
public void clear() {
checkConcurrentModification();
modCnt++;
+ base.modCnt++;
base.closeGap(start, size);
size = 0;
}
@@ -306,25 +325,20 @@ public abstract class AbstractBaseList implements List {
@Override
public E remove(int index) {
- return null;
- }
-
- @Override
- public ListIterator listIterator() {
- return new SubListItr<>(base, start, start, start + (size - 1));
- }
-
- @Override
- public ListIterator listIterator(int index) {
+ checkConcurrentModification();
Objects.checkIndex(index, size);
- return new SubListItr<>(base, start + index, start, start + (size - 1));
+ modCnt++;
+ size--;
+ return base.remove(start + index);
}
@Override
public List subList(int fromIndex, int toIndex) {
checkConcurrentModification();
Objects.checkIndex(fromIndex, size);
- Objects.checkIndex(toIndex, size);
+ if (toIndex < 0 || toIndex > size) {
+ throw new IndexOutOfBoundsException();
+ }
int len = (toIndex - fromIndex) + 1;
if (len < 0) {
throw new IllegalArgumentException();
@@ -373,114 +387,5 @@ public abstract class AbstractBaseList implements List {
throw new ConcurrentModificationException();
}
}
-
-
- private static class SubListItr implements ListIterator {
-
- private final AbstractBaseList base;
- private int modCnt;
- private int cur;
- private int lower;
- private int higher;
- private int last;
-
- public SubListItr(AbstractBaseList base, int start, int lower, int higher) {
- this.base = base;
- modCnt = base.modCnt;
- cur = start;
- this.lower = lower;
- this.higher = higher;
- last = -1;
- }
-
- @Override
- public boolean hasNext() {
- return cur <= higher;
- }
-
- @Override
- public TYPE next() {
- checkConcurrentModification();
- if (!hasNext()) {
- throw new IndexOutOfBoundsException();
- }
- last = cur;
- return base.get(cur++);
- }
-
- @Override
- public boolean hasPrevious() {
- return cur > lower;
- }
-
- @Override
- public TYPE previous() {
- checkConcurrentModification();
- if (!hasPrevious()) {
- throw new IndexOutOfBoundsException();
- }
- last = --cur;
- return base.get(cur);
- }
-
- @Override
- public int nextIndex() {
- return cur - lower;
- }
-
- @Override
- public int previousIndex() {
- return cur - lower - 1;
- }
-
- @Override
- public void remove() {
- checkConcurrentModification();
- rangeCheck();
- if (last == -1) {
- throw new IllegalStateException();
- }
- modCnt++;
- base.remove(last);
- last = -1;
- }
-
- @Override
- public void set(TYPE element) {
- checkConcurrentModification();
- rangeCheck();
- if (last == -1) {
- throw new IllegalStateException();
- }
- modCnt++;
- base.set(last, element);
- last = -1;
- }
-
- @Override
- public void add(TYPE element) {
- checkConcurrentModification();
- rangeCheck();
- if (last == -1) {
- throw new IllegalStateException();
- }
- modCnt++;
- base.add(last, element);
- last = -1;
- }
-
- private void checkConcurrentModification() {
- if (base.modCnt != modCnt) {
- throw new ConcurrentModificationException();
- }
- }
-
- private void rangeCheck() {
- if (cur < lower || cur > higher) {
- throw new IndexOutOfBoundsException();
- }
- }
- }
}
-
}
diff --git a/src/dev/asdf00/general/utils/list/internal/BooleanList.java b/src/dev/asdf00/general/utils/list/internal/BooleanList.java
new file mode 100644
index 0000000..972780d
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/BooleanList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class BooleanList extends PrimitiveList {
+
+ private boolean[] data;
+
+ public BooleanList() {
+ data = new boolean[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Boolean.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Boolean)) {
+ return -1;
+ }
+ boolean target = ((Boolean) o).booleanValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Boolean)) {
+ return -1;
+ }
+ boolean target = ((Boolean) o).booleanValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Boolean directSet(int index, Boolean element) {
+ boolean result = data[index];
+ data[index] = element.booleanValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Boolean element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Boolean> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Boolean b : c) {
+ data[i] = b.booleanValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Boolean> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Boolean b : c) {
+ data[i] = b.booleanValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new boolean[8];
+ size = 0;
+ }
+
+ @Override
+ public Boolean get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Boolean element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Boolean remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ boolean result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addBoolean(boolean value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public boolean getBoolean(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public boolean[] toBooleanArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public boolean[] finalizeAsBooleanArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ boolean[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/ByteList.java b/src/dev/asdf00/general/utils/list/internal/ByteList.java
index 70d905e..4b89ac2 100644
--- a/src/dev/asdf00/general/utils/list/internal/ByteList.java
+++ b/src/dev/asdf00/general/utils/list/internal/ByteList.java
@@ -32,6 +32,9 @@ public class ByteList extends PrimitiveList {
@Override
protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
if (!(o instanceof Byte)) {
return -1;
}
@@ -46,6 +49,9 @@ public class ByteList extends PrimitiveList {
@Override
protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
if (!(o instanceof Byte)) {
return -1;
}
@@ -72,7 +78,7 @@ public class ByteList extends PrimitiveList {
if (Integer.bitCount(size) == 1) {
data = Arrays.copyOf(data, size);
} else {
- data = Arrays.copyOf(data, Integer.highestOneBit(size) + 1);
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
}
}
System.arraycopy(data, start, data, start + len, (size - len) - start);
@@ -84,6 +90,16 @@ public class ByteList extends PrimitiveList {
size -= len;
}
+ @Override
+ public boolean add(Byte element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
@Override
public boolean addAll(Collection extends Byte> c) {
modCnt++;
@@ -127,38 +143,49 @@ public class ByteList extends PrimitiveList {
@Override
public void add(int index, Byte element) {
-
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
}
@Override
public Byte remove(int index) {
- return null;
+ Objects.checkIndex(index, size);
+ modCnt++;
+ byte result = data[index];
+ closeGap(index, 1);
+ return result;
}
@Override
public void addByte(byte value) {
-
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
}
@Override
public byte getByte(int index) {
- return 0;
+ Objects.checkIndex(index, size);
+ return data[index];
}
@Override
public byte[] toByteArray() {
- return new byte[0];
+ return Arrays.copyOf(data, size);
}
@Override
public byte[] finalizeAsByteArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
byte[] res = data;
data = null;
- AbstractBaseList.UNSAFE.putInt(data, AbstractBaseList.OFFSET_LEN, size);
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
return res;
}
-
- private void reallocateWithLen(int newLen) {
- data = Arrays.copyOf(data, newLen);
- }
}
diff --git a/src/dev/asdf00/general/utils/list/internal/CharacterList.java b/src/dev/asdf00/general/utils/list/internal/CharacterList.java
new file mode 100644
index 0000000..3edbddb
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/CharacterList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class CharacterList extends PrimitiveList {
+
+ private char[] data;
+
+ public CharacterList() {
+ data = new char[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Character.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Character)) {
+ return -1;
+ }
+ char target = ((Character) o).charValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Character)) {
+ return -1;
+ }
+ char target = ((Character) o).charValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Character directSet(int index, Character element) {
+ char result = data[index];
+ data[index] = element.charValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Character element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Character> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Character b : c) {
+ data[i] = b.charValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Character> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Character b : c) {
+ data[i] = b.charValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new char[8];
+ size = 0;
+ }
+
+ @Override
+ public Character get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Character element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Character remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ char result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addChar(char value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public char getChar(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public char[] toCharArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public char[] finalizeAsCharArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ char[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/DoubleList.java b/src/dev/asdf00/general/utils/list/internal/DoubleList.java
new file mode 100644
index 0000000..17a79e9
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/DoubleList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class DoubleList extends PrimitiveList {
+
+ private double[] data;
+
+ public DoubleList() {
+ data = new double[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Double.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Double)) {
+ return -1;
+ }
+ double target = ((Double) o).doubleValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Double)) {
+ return -1;
+ }
+ double target = ((Double) o).doubleValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Double directSet(int index, Double element) {
+ double result = data[index];
+ data[index] = element.doubleValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Double element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Double> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Double b : c) {
+ data[i] = b.doubleValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Double> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Double b : c) {
+ data[i] = b.doubleValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new double[8];
+ size = 0;
+ }
+
+ @Override
+ public Double get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Double element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Double remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ double result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addDouble(double value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public double getDouble(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public double[] toDoubleArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public double[] finalizeAsDoubleArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ double[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/FloatList.java b/src/dev/asdf00/general/utils/list/internal/FloatList.java
new file mode 100644
index 0000000..481ec57
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/FloatList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class FloatList extends PrimitiveList {
+
+ private float[] data;
+
+ public FloatList() {
+ data = new float[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Float.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Float)) {
+ return -1;
+ }
+ float target = ((Float) o).floatValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Float)) {
+ return -1;
+ }
+ float target = ((Float) o).floatValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Float directSet(int index, Float element) {
+ float result = data[index];
+ data[index] = element.floatValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Float element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Float> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Float b : c) {
+ data[i] = b.floatValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Float> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Float b : c) {
+ data[i] = b.floatValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new float[8];
+ size = 0;
+ }
+
+ @Override
+ public Float get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Float element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Float remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ float result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addFloat(float value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public float getFloat(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public float[] toFloatArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public float[] finalizeAsFloatArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ float[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/IntegerList.java b/src/dev/asdf00/general/utils/list/internal/IntegerList.java
new file mode 100644
index 0000000..1b7ac56
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/IntegerList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class IntegerList extends PrimitiveList {
+
+ private int[] data;
+
+ public IntegerList() {
+ data = new int[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Integer.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Integer)) {
+ return -1;
+ }
+ int target = ((Integer) o).intValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Integer)) {
+ return -1;
+ }
+ int target = ((Integer) o).intValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Integer directSet(int index, Integer element) {
+ int result = data[index];
+ data[index] = element.intValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Integer element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Integer> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Integer b : c) {
+ data[i] = b.intValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Integer> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Integer b : c) {
+ data[i] = b.intValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new int[8];
+ size = 0;
+ }
+
+ @Override
+ public Integer get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Integer element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Integer remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addInt(int value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public int getInt(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public int[] toIntArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public int[] finalizeAsIntArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ int[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/LongList.java b/src/dev/asdf00/general/utils/list/internal/LongList.java
new file mode 100644
index 0000000..6512624
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/LongList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class LongList extends PrimitiveList {
+
+ private long[] data;
+
+ public LongList() {
+ data = new long[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Long.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Long)) {
+ return -1;
+ }
+ long target = ((Long) o).longValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Long)) {
+ return -1;
+ }
+ long target = ((Long) o).longValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Long directSet(int index, Long element) {
+ long result = data[index];
+ data[index] = element.longValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Long element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Long> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Long b : c) {
+ data[i] = b.longValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Long> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Long b : c) {
+ data[i] = b.longValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new long[8];
+ size = 0;
+ }
+
+ @Override
+ public Long get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Long element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Long remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ long result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addLong(long value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public long getLong(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public long[] toLongArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public long[] finalizeAsLongArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ long[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/list/internal/ShortList.java b/src/dev/asdf00/general/utils/list/internal/ShortList.java
new file mode 100644
index 0000000..7c9ce02
--- /dev/null
+++ b/src/dev/asdf00/general/utils/list/internal/ShortList.java
@@ -0,0 +1,191 @@
+package dev.asdf00.general.utils.list.internal;
+
+import dev.asdf00.general.utils.list.PrimitiveList;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+public class ShortList extends PrimitiveList {
+
+ private short[] data;
+
+ public ShortList() {
+ data = new short[8];
+ size = 0;
+ modCnt = 0;
+ }
+
+ @Override
+ public boolean isFinalized() {
+ return data == null;
+ }
+
+ @Override
+ protected T1[] toArray(T1[] a, int start, int len) {
+ Object[] result = Arrays.copyOf(a, len, a.getClass());
+ for (int i = 0, j = start; i < len; i++, j++) {
+ result[i] = Short.valueOf(data[j]);
+ }
+ return (T1[]) result;
+ }
+
+ @Override
+ protected int indexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Short)) {
+ return -1;
+ }
+ short target = ((Short) o).shortValue();
+ for (int i = start; i < start + len; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int lastIndexOf(Object o, int start, int len) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (!(o instanceof Short)) {
+ return -1;
+ }
+ short target = ((Short) o).shortValue();
+ for (int i = (start + len) - 1; i >= start; i++) {
+ if (data[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected Short directSet(int index, Short element) {
+ short result = data[index];
+ data[index] = element.shortValue();
+ return result;
+ }
+
+ @Override
+ protected void createGap(int start, int len) {
+ size += len;
+ if (size > data.length) {
+ if (Integer.bitCount(size) == 1) {
+ data = Arrays.copyOf(data, size);
+ } else {
+ data = Arrays.copyOf(data, Integer.highestOneBit(size) << 1);
+ }
+ }
+ System.arraycopy(data, start, data, start + len, (size - len) - start);
+ }
+
+ @Override
+ protected void closeGap(int start, int len) {
+ System.arraycopy(data, start + len, data, start, size - (start + len));
+ size -= len;
+ }
+
+ @Override
+ public boolean add(Short element) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, element);
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection extends Short> c) {
+ modCnt++;
+ int i = size;
+ createGap(size, c.size());
+ for (Short b : c) {
+ data[i] = b.shortValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends Short> c) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ int i = index;
+ createGap(index, c.size());
+ for (Short b : c) {
+ data[i] = b.shortValue();
+ i++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ modCnt++;
+ data = new short[8];
+ size = 0;
+ }
+
+ @Override
+ public Short get(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public void add(int index, Short element) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ createGap(index, 1);
+ directSet(index, element);
+ }
+
+ @Override
+ public Short remove(int index) {
+ Objects.checkIndex(index, size);
+ modCnt++;
+ short result = data[index];
+ closeGap(index, 1);
+ return result;
+ }
+
+ @Override
+ public void addShort(short value) {
+ modCnt++;
+ if (size == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ directSet(size++, value);
+ }
+
+ @Override
+ public short getShort(int index) {
+ Objects.checkIndex(index, size);
+ return data[index];
+ }
+
+ @Override
+ public short[] toShortArray() {
+ return Arrays.copyOf(data, size);
+ }
+
+ @Override
+ public short[] finalizeAsShortArray() {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ short[] res = data;
+ data = null;
+ AbstractBaseList.UNSAFE.putInt(res, AbstractBaseList.OFFSET_LEN, size);
+ return res;
+ }
+}
diff --git a/src/dev/asdf00/general/utils/listOld/PrimitiveList.java b/src/dev/asdf00/general/utils/listOld/PrimitiveList.java
deleted file mode 100644
index 53b7549..0000000
--- a/src/dev/asdf00/general/utils/listOld/PrimitiveList.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package dev.asdf00.general.utils.listOld;
-
-import dev.asdf00.general.utils.listOld.internal.PrimitiveListImpl;
-import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
-import java.util.List;
-import java.util.RandomAccess;
-
-public abstract class PrimitiveList implements List, RandomAccess {
-
- private static final Unsafe UNSAFE;
-
- static {
- try {
- Field f = Unsafe.class.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- UNSAFE = (Unsafe) f.get(null);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static boolean isSupportedOnCurrentJVMConfiguration() {
- return UNSAFE.arrayIndexScale(byte[].class) == 1 && UNSAFE.arrayIndexScale(short[].class) == 2 &&
- UNSAFE.arrayIndexScale(int[].class) == 4 && UNSAFE.arrayIndexScale(long[].class) == 8 &&
- UNSAFE.arrayIndexScale(float[].class) == 4 && UNSAFE.arrayIndexScale(double[].class) == 8;
- }
-
- public static PrimitiveList create(Class boxedType) throws IllegalArgumentException, UnsupportedOperationException {
- return PrimitiveListImpl.create(boxedType);
- }
-
- public abstract byte[] toByteArray();
-
- public abstract short[] toShortArray();
-
- public abstract int[] toIntArray();
-
- public abstract long[] toLongArray();
-
- public abstract float[] toFloatArray();
-
- public abstract double[] toDoubleArray();
-
- public abstract char[] toCharArray();
-
- public abstract boolean[] toBooleanArray();
-
- public abstract byte getByte(int index);
-
- public abstract short getShort(int index);
-
- public abstract int getInt(int index);
-
- public abstract long getLong(int index);
-
- public abstract float getFloat(int index);
-
- public abstract double getDouble(int index);
-
- public abstract char getChar(int index);
-
- public abstract boolean getBoolean(int index);
-
- public abstract byte[] finalizeAsByteArray();
-
- public abstract short[] finalizeAsShortArray();
-
- public abstract int[] finalizeAsIntArray();
-
- public abstract long[] finalizeAsLongArray();
-
- public abstract float[] finalizeAsFloatArray();
-
- public abstract double[] finalizeAsDoubleArray();
-
- public abstract boolean isFinalized();
-}
diff --git a/src/dev/asdf00/general/utils/listOld/internal/PrimitiveListImpl.java b/src/dev/asdf00/general/utils/listOld/internal/PrimitiveListImpl.java
deleted file mode 100644
index cd0044e..0000000
--- a/src/dev/asdf00/general/utils/listOld/internal/PrimitiveListImpl.java
+++ /dev/null
@@ -1,1218 +0,0 @@
-package dev.asdf00.general.utils.listOld.internal;
-
-import dev.asdf00.general.utils.listOld.PrimitiveList;
-import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
-import java.util.*;
-
-public final class PrimitiveListImpl extends PrimitiveList {
-
- private static final Unsafe UNSAFE;
- private static final long OFFSET;
- private static final int KLASS_WORD_OFFSET;
- private static final int KLASS_WORD_SIZE;
- private static final int LENGTH_OFFSET;
-
- static {
- try {
- Field f = Unsafe.class.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- UNSAFE = (Unsafe) f.get(null);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- OFFSET = UNSAFE.arrayBaseOffset(long[].class);
- KLASS_WORD_OFFSET = UNSAFE.addressSize();
- KLASS_WORD_SIZE = UNSAFE.addressSize() == 4 || System.getProperty("java.vm.compressedOopsMode") != null ? 4 : 8;
- LENGTH_OFFSET = KLASS_WORD_OFFSET + KLASS_WORD_SIZE;
- }
-
-
- private long[] rawData;
- private int size;
- private int modCount = 0;
- private int type;
-
- private PrimitiveListImpl(int type) {
- this.type = type;
- rawData = new long[16 >> (0xFF & (type >> 16))];
- size = 0;
- }
-
- public static PrimitiveListImpl create(Class boxedType) throws UnsupportedOperationException {
- if (!isSupportedOnCurrentJVMConfiguration()) {
- throw new UnsupportedOperationException("this list is not supported with your current JVM settings due to a mismatch in array index scales!");
- }
- int type;
- if (Byte.class.equals(boxedType)) {
- type = 0x03_01_00;
- } else if (Short.class.equals(boxedType)) {
- type = 0x02_02_01;
- } else if (Integer.class.equals(boxedType)) {
- type = 0x01_04_02;
- } else if (Long.class.equals(boxedType)) {
- type = 0x00_08_03;;
- } else if (Float.class.equals(boxedType)) {
- type = 0x01_04_04;
- } else if (Double.class.equals(boxedType)) {
- type = 0x00_08_05;
- } else if (Character.class.equals(boxedType)) {
- type = 0x01_04_06;
- } else if (Boolean.class.equals(boxedType)) {
- type = 0x03_01_07;
- } else {
- throw new IllegalArgumentException("%s is not a boxed type!".formatted(boxedType));
- }
- return new PrimitiveListImpl<>(type);
- }
-
-
- @Override
- public boolean isFinalized() {
- return type == -1;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public boolean isEmpty() {
- return size < 1;
- }
-
- @Override
- public boolean contains(Object o) {
- return indexOf(o) >= 0;
- }
-
- @Override
- public Iterator iterator() {
- return listIterator();
- }
-
- @Override
- public Object[] toArray() {
- return toArray(Object[]::new);
- }
-
- @Override
- public T1[] toArray(T1[] a) {
- return toArray(a, 0, size);
- }
-
- @Override
- public boolean add(T t) {
- increaseSize(1);
- directSet(size - 1, t);
- return true;
- }
-
- @Override
- public boolean remove(Object o) {
- int index = indexOf(o);
- if (index >= 0) {
- remove(index);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean containsAll(Collection> c) {
- BitSet checked = new BitSet(c.size());
- int i;
- for (T element : this) {
- i = 0;
- for (Object inner : c) {
- if (element.equals(inner)) {
- checked.set(i);
- }
- }
- }
- for (i = 0; i < c.size(); i++) {
- if (!checked.get(i)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public boolean addAll(Collection extends T> c) {
- int i = size;
- increaseSize(c.size());
- for (T element : c) {
- directSet(i++, element);
- }
- return true;
- }
-
- @Override
- public boolean addAll(int index, Collection extends T> c) {
- Objects.checkIndex(index, size);
- increaseSize(c.size());
- openGap(index, c.size());
- int i = index;
- for (T element : c) {
- directSet(i, element);
- }
- return true;
- }
-
- @Override
- public boolean removeAll(Collection> c) {
- for (int i = 0; i < size; i++) {
- if (c.contains(get(i))) {
- remove(i);
- }
- }
- return true;
- }
-
- @Override
- public boolean retainAll(Collection> c) {
- for (int i = 0; i < size; i++) {
- if (!c.contains(get(i))) {
- remove(i);
- }
- }
- return false;
- }
-
- @Override
- public void clear() {
- checkFinalized();
- modCount++;
- size = 0;
- rawData = new long[16 >> (0xFF & (type >> 16))];
- }
-
- @Override
- public T get(int index) {
- Objects.checkIndex(index, size);
- switch (0xFF & type) {
- case 0:
- return (T) Byte.valueOf(UNSAFE.getByte(rawData, OFFSET + index));
- case 1:
- return (T) Short.valueOf(UNSAFE.getShort(rawData, OFFSET + (index << 1)));
- case 2:
- return (T) Integer.valueOf(UNSAFE.getInt(rawData, OFFSET + (index << 2)));
- case 3:
- return (T) Long.valueOf(UNSAFE.getLong(rawData, OFFSET + (index << 3)));
- case 4:
- return (T) Float.valueOf(UNSAFE.getFloat(rawData, OFFSET + (index << 2)));
- case 5:
- return (T) Double.valueOf(UNSAFE.getDouble(rawData, OFFSET + (index << 3)));
- case 6:
- return (T) Character.valueOf((char) UNSAFE.getInt(rawData, OFFSET + (index << 2)));
- case 7:
- return (T) Boolean.valueOf(UNSAFE.getByte(rawData, OFFSET + index) != 0);
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- }
-
- @Override
- public T set(int index, T element) {
- Objects.checkIndex(index, size);
- T prev = get(index);
- directSet(index, element);
- return prev;
- }
-
- @Override
- public void add(int index, T element) {
- Objects.checkIndex(index, size);
- increaseSize(1);
- openGap(index, 1);
- directSet(index, element);
- }
-
- @Override
- public T remove(int index) {
- Objects.checkIndex(index, size);
- T removed = get(index);
- fillGap(index, 1);
- size--;
- return removed;
- }
-
- @Override
- public int indexOf(Object o) {
- return indexOf(o, 0, size);
- }
-
- @Override
- public int lastIndexOf(Object o) {
- return lastIndexOf(o, 0, size);
- }
-
- @Override
- public ListIterator listIterator() {
- return new ListItr<>(this, 0);
- }
-
- @Override
- public ListIterator listIterator(int index) {
- Objects.checkIndex(index, size);
- return new ListItr<>(this, index);
- }
-
- @Override
- public List subList(int fromIndex, int toIndex) {
- Objects.checkIndex(fromIndex, size);
- Objects.checkIndex(toIndex, size);
- checkFinalized();
- if (fromIndex > toIndex) {
- throw new IllegalArgumentException();
- }
- return new SubList<>(this, fromIndex, toIndex);
- }
-
- //======================================================
- // additional primitive access points
- //======================================================
- @Override
- public byte[] toByteArray() {
- checkFinalized();
- int shift = 3 - (0xFF & (type >> 16));
- int targetSize = size << shift;
- byte[] result = new byte[targetSize];
- UNSAFE.copyMemory(rawData, OFFSET, result, UNSAFE.arrayBaseOffset(byte[].class), targetSize);
- return result;
- }
-
- @Override
- public short[] toShortArray() {
- checkFinalized();
- int shift = 2 - (0xFF & (type >> 16));
- if (shift < 0) {
- throw new UnsupportedOperationException("cannot transform this into short[]");
- }
- int targetSize = size << shift;
- short[] result = new short[targetSize];
- UNSAFE.copyMemory(rawData, OFFSET, result, UNSAFE.arrayBaseOffset(short[].class), targetSize << 1);
- return result;
- }
-
- @Override
- public int[] toIntArray() {
- checkFinalized();
- int shift = 1 - (0xFF & (type >> 16));
- if (shift < 0) {
- throw new UnsupportedOperationException("cannot transform this into int[]");
- }
- int targetSize = size << shift;
- int[] result = new int[targetSize];
- UNSAFE.copyMemory(rawData, OFFSET, result, UNSAFE.arrayBaseOffset(int[].class), targetSize << 2);
- return result;
- }
-
- @Override
- public long[] toLongArray() {
- checkFinalized();
- if ((0xFF & (type >> 16)) != 0) {
- throw new UnsupportedOperationException("cannot transform this into long[]");
- }
- return Arrays.copyOf(rawData, size);
- }
-
- @Override
- public float[] toFloatArray() {
- checkFinalized();
- int shift = 1 - (0xFF & (type >> 16));
- if (shift < 0) {
- throw new UnsupportedOperationException("cannot this transform into float[]");
- }
- int targetSize = size << shift;
- float[] result = new float[targetSize];
- UNSAFE.copyMemory(rawData, OFFSET, result, UNSAFE.arrayBaseOffset(float[].class), size << 2);
- return result;
- }
-
- @Override
- public double[] toDoubleArray() {
- checkFinalized();
- if ((0xFF & (type >> 16)) != 0) {
- throw new UnsupportedOperationException("cannot transform this into double[]");
- }
- double[] result = new double[size];
- UNSAFE.copyMemory(rawData, OFFSET, result, UNSAFE.arrayBaseOffset(byte[].class), size << 3);
- return result;
- }
-
- @Override
- public char[] toCharArray() {
- checkFinalized();
- int shift = 1 - (0xFF & (type >> 16));
- if (shift < 0) {
- throw new UnsupportedOperationException("cannot transform this into char[]");
- }
- int targetSize = size << shift;
- char[] result = new char[targetSize];
- for (int i = 0; i < targetSize; i++) {
- result[i] = (char) UNSAFE.getInt(rawData, OFFSET + (i << 2));
- }
- return result;
- }
-
- @Override
- public boolean[] toBooleanArray() {
- checkFinalized();
- int shift = 3 - (0xFF & (type >> 16));
- int targetSize = size << shift;
- boolean[] result = new boolean[targetSize];
- for (int i = 0; i < targetSize; i++) {
- result[i] = UNSAFE.getByte(rawData, OFFSET + i) != 0;
- }
- return result;
- }
-
- @Override
- public byte getByte(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 0) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Byte!");
- }
- return UNSAFE.getByte(rawData, OFFSET + index);
- }
-
- @Override
- public short getShort(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 1) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Short!");
- }
- return UNSAFE.getShort(rawData, OFFSET + (index << 1));
- }
-
- @Override
- public int getInt(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 2) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Integer!");
- }
- return UNSAFE.getInt(rawData, OFFSET + (index << 2));
- }
-
- @Override
- public long getLong(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 3) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Long!");
- }
- return UNSAFE.getLong(rawData, OFFSET + (index << 3));
- }
-
- @Override
- public float getFloat(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 4) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Float!");
- }
- return UNSAFE.getFloat(rawData, OFFSET + (index << 2));
- }
-
- @Override
- public double getDouble(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 5) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Double!");
- }
- return UNSAFE.getDouble(rawData, OFFSET + (index << 3));
- }
-
- @Override
- public char getChar(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 6) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Character!");
- }
- return (char) UNSAFE.getInt(rawData, OFFSET + (index << 2));
- }
-
- @Override
- public boolean getBoolean(int index) {
- Objects.checkIndex(index, size);
- if ((0xFF & type) != 7) {
- checkFinalized();
- throw new UnsupportedOperationException("this list is not of type Boolean!");
- }
- return UNSAFE.getByte(rawData, OFFSET + index) != 0;
- }
-
- @Override
- public byte[] finalizeAsByteArray() {
- checkFinalized();
- if ((0xFF & type) != 0) {
- throw new UnsupportedOperationException("this list is not of type Byte!");
- }
- rewriteArrayHeader(new byte[0]);
- return (byte[]) (Object) rawData;
- }
-
- @Override
- public short[] finalizeAsShortArray() {
- checkFinalized();
- if ((0xFF & type) != 1) {
- throw new UnsupportedOperationException("this list is not of type Short!");
- }
- rewriteArrayHeader(new short[0]);
- return (short[]) (Object) rawData;
- }
-
- @Override
- public int[] finalizeAsIntArray() {
- checkFinalized();
- if ((0xFF & type) != 2) {
- throw new UnsupportedOperationException("this list is not of type Integer!");
- }
- rewriteArrayHeader(new int[0]);
- return (int[]) (Object) rawData;
- }
-
- @Override
- public long[] finalizeAsLongArray() {
- checkFinalized();
- if ((0xFF & type) != 3) {
- throw new UnsupportedOperationException("this list is not of type Long!");
- }
- rewriteArrayHeader(new long[0]);
- return rawData;
- }
-
- @Override
- public float[] finalizeAsFloatArray() {
- checkFinalized();
- if ((0xFF & type) != 4) {
- throw new UnsupportedOperationException("this list is not of type Float!");
- }
- rewriteArrayHeader(new float[0]);
- return (float[]) (Object) rawData;
- }
-
- @Override
- public double[] finalizeAsDoubleArray() {
- checkFinalized();
- if ((0xFF & type) != 5) {
- throw new UnsupportedOperationException("this list is not of type Float!");
- }
- rewriteArrayHeader(new double[0]);
- return (double[]) (Object) rawData;
- }
-
- //======================================================
- // private helper methods
- //======================================================
- private void rewriteArrayHeader(Object emptyArrayInstance) {
- type = -1;
- if (KLASS_WORD_SIZE == 4) {
- UNSAFE.putInt(rawData, KLASS_WORD_OFFSET, UNSAFE.getInt(emptyArrayInstance, KLASS_WORD_OFFSET));
- } else {
- UNSAFE.putLong(rawData, KLASS_WORD_OFFSET, UNSAFE.getLong(emptyArrayInstance, KLASS_WORD_OFFSET));
- }
- UNSAFE.putInt(rawData, LENGTH_OFFSET, size);
- }
-
- private void checkFinalized() {
- if (type == -1) {
- throw new IllegalStateException("this list has been finalized!");
- }
- }
-
- private void increaseSize(int by) {
- checkFinalized();
- if (Integer.MAX_VALUE - by < size) {
- throw new IllegalStateException("size reached integer overflow!");
- }
- int shiftBy = type >> 16;
- // shiftBy gets implicitly masked to 0x1F
- int capacity = rawData.length << shiftBy;
- size += by;
- if (capacity < size) {
- capacity = Integer.highestOneBit(size);
- if (capacity != size) {
- capacity <<= 1;
- }
- rawData = Arrays.copyOf(rawData, capacity >> shiftBy);
- }
- }
-
- private void directSet(int index, T element) {
- modCount++;
- switch (0xFF & type) {
- case 0:
- UNSAFE.putByte(rawData, OFFSET + index, ((Byte) element).byteValue());
- return;
- case 1:
- UNSAFE.putShort(rawData, OFFSET + (index << 1), ((Short) element).shortValue());
- return;
- case 2:
- UNSAFE.putInt(rawData, OFFSET + (index << 2), ((Integer) element).intValue());
- return;
- case 3:
- UNSAFE.putLong(rawData, OFFSET + (index << 3), ((Long) element).longValue());
- return;
- case 4:
- UNSAFE.putFloat(rawData, OFFSET + (index << 2), ((Float) element).floatValue());
- return;
- case 5:
- UNSAFE.putDouble(rawData, OFFSET + (index << 3), ((Double) element).doubleValue());
- return;
- case 6:
- UNSAFE.putInt(rawData, OFFSET + (index << 2), ((Character) element).charValue());
- return;
- case 7:
- UNSAFE.putByte(rawData, OFFSET + index, ((Boolean) element) ? (byte) 1 : (byte) 0);
- return;
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- }
-
- private void fillGap(int at, int gapSize) {
- modCount++;
- switch (0xFF & (type >> 16)) {
- case 3: // byte sized elements
- for (int i = at; i + gapSize < size; i++) {
- UNSAFE.putByte(rawData, OFFSET + i, UNSAFE.getByte(rawData, OFFSET + i + gapSize));
- }
- break;
- case 2: // short sized elements
- for (int i = at; i + gapSize < size; i++) {
- UNSAFE.putShort(rawData, OFFSET + (i << 1), UNSAFE.getShort(rawData, OFFSET + ((i + gapSize) << 1)));
- }
- break;
- case 1: // int sized elements
- for (int i = at; i + gapSize < size; i++) {
- UNSAFE.putInt(rawData, OFFSET + (i << 2), UNSAFE.getInt(rawData, OFFSET + ((i + gapSize) << 2)));
- }
- break;
- case 0: // long sized elements
- for (int i = at; i + gapSize < size; i++) {
- UNSAFE.putLong(rawData, OFFSET + (i << 3), UNSAFE.getLong(rawData, OFFSET + ((i + gapSize) << 3)));
- }
- break;
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- }
-
- private void openGap(int at, int gapSize) {
- modCount++;
- switch (0xFF & (type >> 16)) {
- case 3: // byte sized elements
- for (int i = size - 1; i - gapSize >= at; i--) {
- UNSAFE.putByte(rawData, OFFSET + i, UNSAFE.getByte(rawData, OFFSET + i - gapSize));
- }
- break;
- case 2: // short sized elements
- for (int i = size - 1; i - gapSize >= at; i--) {
- UNSAFE.putShort(rawData, OFFSET + (i << 1), UNSAFE.getShort(rawData, OFFSET + ((i - gapSize) << 1)));
- }
- break;
- case 1: // int sized elements
- for (int i = size - 1; i - gapSize >= at; i--) {
- UNSAFE.putInt(rawData, OFFSET + (i << 2), UNSAFE.getInt(rawData, OFFSET + ((i - gapSize) << 2)));
- }
- break;
- case 0: // long sized elements
- for (int i = size - 1; i - gapSize >= at; i--) {
- UNSAFE.putLong(rawData, OFFSET + (i << 3), UNSAFE.getLong(rawData, OFFSET + ((i - gapSize) << 3)));
- }
- break;
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- }
-
- private T1[] toArray(T1[] a, int from, int to) {
- Object[] dest = Arrays.copyOf(a, to - from, a.getClass());
- switch (0xFF & type) {
- case 0:
- for (int i = from; i < to; i++) {
- dest[i] = Byte.valueOf(UNSAFE.getByte(rawData, OFFSET + i));
- }
- break;
- case 1:
- for (int i = from; i < to; i++) {
- dest[i] = Short.valueOf(UNSAFE.getShort(rawData, OFFSET + i * 2));
- }
- break;
- case 2:
- for (int i = from; i < to; i++) {
- dest[i] = Integer.valueOf(UNSAFE.getInt(rawData, OFFSET + i * 4));
- }
- break;
- case 3:
- for (int i = from; i < to; i++) {
- dest[i] = Long.valueOf(UNSAFE.getLong(rawData, OFFSET + i * 8));
- }
- break;
- case 4:
- for (int i = from; i < to; i++) {
- dest[i] = Float.valueOf(UNSAFE.getFloat(rawData, OFFSET + i * 4));
- }
- break;
- case 5:
- for (int i = from; i < to; i++) {
- dest[i] = Double.valueOf(UNSAFE.getDouble(rawData, OFFSET + i * 8));
- }
- break;
- case 6:
- for (int i = from; i < to; i++) {
- dest[i] = Character.valueOf((char) UNSAFE.getInt(rawData, OFFSET + i * 4));
- }
- break;
- case 7:
- for (int i = from; i < to; i++) {
- dest[i] = Boolean.valueOf(UNSAFE.getByte(rawData, OFFSET + i) == 1);
- }
- break;
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- return (T1[]) dest;
- }
-
- private int indexOf(Object o, int from, int to) {
- switch (0xFF & type) {
- case 0: {
- byte target = ((Byte) o).byteValue();
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getByte(rawData, OFFSET + i)) {
- return i;
- }
- }
- break;
- }
- case 1: {
- short target = ((Short) o).shortValue();
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getShort(rawData, OFFSET + (i << 1))) {
- return i;
- }
- }
- break;
- }
- case 2: {
- int target = ((Integer) o).intValue();
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getInt(rawData, OFFSET + (i << 2))) {
- return i;
- }
- }
- break;
- }
- case 3: {
- long target = ((Long) o).longValue();
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getLong(rawData, OFFSET + (i << 3))) {
- return i;
- }
- }
- break;
- }
- case 4: {
- float target = ((Float) o).floatValue();
- for (int i = from; i < to; i++) {
- if (Float.compare(target, UNSAFE.getFloat(rawData, OFFSET + (i << 2))) == 0) {
- return i;
- }
- }
- break;
- }
- case 5: {
- double target = ((Double) o).doubleValue();
- for (int i = from; i < to; i++) {
- if (Double.compare(target, UNSAFE.getDouble(rawData, OFFSET + (i << 3))) == 0) {
- return i;
- }
- }
- break;
- }
- case 6: {
- int target = ((Character) o).charValue();
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getInt(rawData, OFFSET + (i << 2))) {
- return i;
- }
- }
- break;
- }
- case 7: {
- byte target = ((Boolean) o) ? (byte) 1 : (byte) 0;
- for (int i = from; i < to; i++) {
- if (target == UNSAFE.getByte(rawData, OFFSET + i)) {
- return i;
- }
- }
- break;
- }
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- return -1;
- }
-
- private int lastIndexOf(Object o, int from, int to) {
- switch (0xFF & type) {
- case 0: {
- byte target = ((Byte) o).byteValue();
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getByte(rawData, OFFSET + i)) {
- return i;
- }
- }
- break;
- }
- case 1: {
- short target = ((Short) o).shortValue();
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getShort(rawData, OFFSET + (i << 1))) {
- return i;
- }
- }
- break;
- }
- case 2: {
- int target = ((Integer) o).intValue();
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getInt(rawData, OFFSET + (i << 2))) {
- return i;
- }
- }
- break;
- }
- case 3: {
- long target = ((Long) o).longValue();
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getLong(rawData, OFFSET + (i << 3))) {
- return i;
- }
- }
- break;
- }
- case 4: {
- float target = ((Float) o).floatValue();
- for (int i = to - 1; i >= from; i--) {
- if (Float.compare(target, UNSAFE.getFloat(rawData, OFFSET + (i << 2))) == 0) {
- return i;
- }
- }
- break;
- }
- case 5: {
- double target = ((Double) o).doubleValue();
- for (int i = to - 1; i >= from; i--) {
- if (Double.compare(target, UNSAFE.getDouble(rawData, OFFSET + (i << 3))) == 0) {
- return i;
- }
- }
- break;
- }
- case 6: {
- int target = ((Character) o).charValue();
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getInt(rawData, OFFSET + (i << 2))) {
- return i;
- }
- }
- break;
- }
- case 7: {
- byte target = ((Boolean) o) ? (byte) 1 : (byte) 0;
- for (int i = to - 1; i >= from; i--) {
- if (target == UNSAFE.getByte(rawData, OFFSET + i)) {
- return i;
- }
- }
- break;
- }
- default:
- throw new IllegalStateException("this list has been finalized!");
- }
- return -1;
- }
-
- //======================================================
- // internal classes
- //======================================================
- private static class ListItr implements ListIterator {
- private final PrimitiveListImpl parent;
- private int cur;
- private int expectedModCount;
-
- public ListItr(PrimitiveListImpl parent, int startingAt) {
- if (parent.type == -1) {
- throw new IllegalStateException("this list has been finalized!");
- }
- this.parent = parent;
- cur = startingAt;
- expectedModCount = parent.modCount;
- }
-
- @Override
- public boolean hasNext() {
- return cur < parent.size;
- }
-
- @Override
- public E next() {
- checkForConcurrentModification();
- return parent.get(cur++);
- }
-
- @Override
- public boolean hasPrevious() {
- return cur > 0;
- }
-
- @Override
- public E previous() {
- checkForConcurrentModification();
- return parent.get(--cur);
- }
-
- @Override
- public int nextIndex() {
- return cur;
- }
-
- @Override
- public int previousIndex() {
- return cur - 1;
- }
-
- @Override
- public void remove() {
- checkForConcurrentModification();
- parent.remove(cur);
- expectedModCount++;
- }
-
- @Override
- public void set(E e) {
- checkForConcurrentModification();
- parent.set(cur, e);
- expectedModCount++;
- }
-
- @Override
- public void add(E e) {
- checkForConcurrentModification();
- parent.add(cur, e);
- expectedModCount += 2;
- }
-
- private void checkForConcurrentModification() {
- if (parent.modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
- }
-
- private static class SubList implements List {
- private final PrimitiveListImpl baseList;
- private final int start;
- private int to;
- private int expectedModCount;
-
- public SubList(PrimitiveListImpl baseList, int start, int to) {
- this.baseList = baseList;
- this.start = start;
- this.to = to;
- expectedModCount = baseList.modCount;
- }
-
- @Override
- public int size() {
- return to - start;
- }
-
- @Override
- public boolean isEmpty() {
- return size() < 1;
- }
-
- @Override
- public boolean contains(Object o) {
- checkForConcurrentModification();
- return indexOf(o) >= 0;
- }
-
- @Override
- public Iterator iterator() {
- return listIterator();
- }
-
- @Override
- public Object[] toArray() {
- return toArray(Object[]::new);
- }
-
- @Override
- public T[] toArray(T[] a) {
- checkForConcurrentModification();
- return baseList.toArray(a, start, to);
- }
-
- @Override
- public boolean add(E e) {
- checkForConcurrentModification();
- expectedModCount += 2;
- baseList.add(to, e);
- to++;
- return true;
- }
-
- @Override
- public boolean remove(Object o) {
- checkForConcurrentModification();
- int index = indexOf(o);
- if (index >= 0) {
- remove(index);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean containsAll(Collection> c) {
- checkForConcurrentModification();
- BitSet checked = new BitSet(c.size());
- int i;
- for (E element : this) {
- i = 0;
- for (Object inner : c) {
- if (element.equals(inner)) {
- checked.set(i);
- }
- }
- }
- for (i = 0; i < c.size(); i++) {
- if (!checked.get(i)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public boolean addAll(Collection extends E> c) {
- checkForConcurrentModification();
- expectedModCount += 1 + c.size();
- baseList.addAll(to, c);
- to += c.size();
- return true;
- }
-
- @Override
- public boolean addAll(int index, Collection extends E> c) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- expectedModCount += 1 + c.size();
- baseList.addAll(start + index, c);
- to += c.size();
- return true;
- }
-
- @Override
- public boolean removeAll(Collection> c) {
- checkForConcurrentModification();
- for (int i = 0; i < size(); i++) {
- if (c.contains(get(i))) {
- remove(i);
- }
- }
- return true;
- }
-
- @Override
- public boolean retainAll(Collection> c) {
- for (int i = 0; i < size(); i++) {
- if (!c.contains(get(i))) {
- remove(i);
- }
- }
- return true;
- }
-
- @Override
- public void clear() {
- checkForConcurrentModification();
- baseList.fillGap(start, size());
- baseList.size -= size();
- expectedModCount++;
- to = start;
- }
-
- @Override
- public E get(int index) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- return get(start + index);
- }
-
- @Override
- public E set(int index, E element) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- expectedModCount++;
- return baseList.set(start + index, element);
- }
-
- @Override
- public void add(int index, E element) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- expectedModCount += 2;
- baseList.add(start, element);
- }
-
- @Override
- public E remove(int index) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- expectedModCount++;
- E result = baseList.get(start + index);
- baseList.remove(start + index);
- return result;
- }
-
- @Override
- public int indexOf(Object o) {
- checkForConcurrentModification();
- return baseList.indexOf(o, start, to);
- }
-
- @Override
- public int lastIndexOf(Object o) {
- checkForConcurrentModification();
- return baseList.lastIndexOf(o, start, to);
- }
-
- @Override
- public ListIterator listIterator() {
- checkForConcurrentModification();
- return new InnerIterator<>(this, start);
- }
-
- @Override
- public ListIterator listIterator(int index) {
- Objects.checkIndex(index, size());
- checkForConcurrentModification();
- return new InnerIterator<>(this, start + index);
- }
-
- @Override
- public List subList(int fromIndex, int toIndex) {
- if (fromIndex > toIndex) {
- throw new IllegalArgumentException();
- }
- Objects.checkIndex(fromIndex, size());
- Objects.checkIndex(toIndex, size());
- checkForConcurrentModification();
- return new SubList<>(baseList, start + fromIndex, start + fromIndex + toIndex);
- }
-
- private void checkForConcurrentModification() {
- if (baseList.modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- private static class InnerIterator implements ListIterator {
- private final SubList parent;
- private int cur;
- private int expectedModCount;
-
- public InnerIterator(SubList parent, int startingAtBase) {
- this.parent = parent;
- cur = startingAtBase;
- expectedModCount = parent.expectedModCount;
- }
-
- @Override
- public boolean hasNext() {
- return cur < parent.to;
- }
-
- @Override
- public E next() {
- checkBounds(cur);
- checkForConcurrentModification();
- return parent.baseList.get(cur++);
- }
-
- @Override
- public boolean hasPrevious() {
- return cur > parent.start;
- }
-
- @Override
- public E previous() {
- checkBounds(cur);
- checkForConcurrentModification();
- return parent.baseList.get(--cur);
- }
-
- @Override
- public int nextIndex() {
- return cur;
- }
-
- @Override
- public int previousIndex() {
- return cur - 1;
- }
-
- @Override
- public void remove() {
- checkBounds(cur);
- checkForConcurrentModification();
- expectedModCount++;
- parent.baseList.remove(cur);
- }
-
- @Override
- public void set(E e) {
- checkBounds(cur);
- checkForConcurrentModification();
- expectedModCount++;
- parent.baseList.set(cur, e);
- }
-
- @Override
- public void add(E e) {
- checkBounds(cur);
- checkForConcurrentModification();
- expectedModCount += 2;
- parent.baseList.add(cur, e);
- }
-
- private void checkForConcurrentModification() {
- if (parent.baseList.modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- private void checkBounds(int index) {
- if (index < parent.start || index >= parent.to) {
- throw new IndexOutOfBoundsException();
- }
- }
- }
- }
-
-}
diff --git a/src/module-info.java b/src/module-info.java
index f003344..e9f306d 100644
--- a/src/module-info.java
+++ b/src/module-info.java
@@ -1,5 +1,4 @@
module GeneralUtils {
requires jdk.unsupported;
- exports dev.asdf00.general.utils.listOld;
exports dev.asdf00.general.utils.list;
}
\ No newline at end of file
diff --git a/test/dev/asdf00/general/utils/list/TestList.java b/test/dev/asdf00/general/utils/list/TestList.java
new file mode 100644
index 0000000..e673f5a
--- /dev/null
+++ b/test/dev/asdf00/general/utils/list/TestList.java
@@ -0,0 +1,138 @@
+package dev.asdf00.general.utils.list;
+
+import dev.asdf00.general.utils.list.internal.ByteList;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.*;
+
+import static dev.asdf00.general.utils.list.internal.ListReader.*;
+import static org.junit.Assert.*;
+
+public class TestList {
+
+ @Test
+ public void basicByteTest() {
+ var list = PrimitiveList.create(Byte.class);
+ list.add((byte) 3);
+ list.addByte((byte) 4);
+ assertListStats(list, 2, 2, 8);
+
+ var array = createByteArray(14);
+ list.addAll(1, toBoxedBytes(array));
+ assertListStats(list, 16, 3, 16);
+ assertEquals("last element", 4, list.getByte(15));
+ assertEquals("first element", Byte.valueOf((byte) 3), list.get(0));
+
+ list.add(1, (byte) 11);
+ assertListStats(list, 17, 4, 32);
+
+ list.remove(Byte.valueOf((byte) 3));
+ assertListStats(list, 16, 5, 32);
+ assertEquals("first element", 11, list.getByte(0));
+
+ assertThrows(ConcurrentModificationException.class, () -> {
+ for (Byte b : list) {
+ list.remove(b);
+ }
+ });
+ list.remove(14);
+ assertListStats(list, 14, 7, 32);
+ assertArrayEquals("toArray", toBoxedBytes(array).toArray(Byte[]::new), list.toArray(Byte[]::new));
+ assertArrayEquals("finalizeAsArray", array, list.finalizeAsByteArray());
+ assertTrue("isFinalized", list.isFinalized());
+ assertThrows(NullPointerException.class, () -> list.lastIndexOf(12));
+ assertThrows(NullPointerException.class, () -> list.get(0));
+ assertThrows(NullPointerException.class, () -> list.finalizeAsByteArray());
+ assertThrows(UnsupportedOperationException.class, () -> list.toBooleanArray());
+ }
+
+ @Test
+ public void indexOutOfBoundsByte() {
+ assertThrows(IllegalArgumentException.class, () -> PrimitiveList.create(Object.class));
+
+ var list = PrimitiveList.create(Byte.class);
+ assertTrue("empty", list.isEmpty());
+ assertEquals("size", 0, list.size());
+ assertThrows(IndexOutOfBoundsException.class, () -> list.getByte(-1));
+ assertThrows(IndexOutOfBoundsException.class, () -> list.getByte(0));
+ assertThrows(IndexOutOfBoundsException.class, () -> list.get(0));
+ assertThrows(IndexOutOfBoundsException.class, () -> list.add(-1, Byte.valueOf((byte) 1)));
+ list.add((byte) 2);
+ list.add((byte) 2);
+ assertThrows(IllegalArgumentException.class, () -> list.subList(1, 0));
+ }
+
+ @Test
+ public void subListTestByte() {
+ var a0 = new byte[]{0, 1, 1, 1, 0, 0};
+ var list = PrimitiveList.create(Byte.class);
+ list.addAll(toBoxedBytes(a0));
+ List subList = list.subList(3, 6);
+ subList.remove(0);
+ assertListStats(list, 5, 2, 8);
+ assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0}, list.toByteArray());
+
+ subList.add((byte) 1);
+ assertListStats(list, 6, 3, 8);
+ assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0, 1}, list.toByteArray());
+
+ subList = list.subList(2, 2);
+ assertTrue("subList empty", subList.isEmpty());
+ subList.add((byte) 2);
+ assertListStats(list, 7, 4, 8);
+ assertArrayEquals("data", new byte[]{0, 1, 2, 1, 0, 0, 1}, list.toByteArray());
+
+ subList.clear();
+ assertListStats(list, 6, 5, 8);
+ assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0, 1}, list.toByteArray());
+
+ list.add(3, (byte) 2);
+ subList = list.subList(1, 5);
+ subList.removeAll(List.of((byte) 1, (byte) 2));
+ assertListStats(list, 4, 9, 8);
+ assertArrayEquals("data", new byte[]{0, 0, 0, 1}, list.toByteArray());
+
+ list.addAll(List.of((byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 3));
+ final List finalSubList = subList;
+ assertThrows(ConcurrentModificationException.class, () -> finalSubList.get(0));
+ assertListStats(list, 9, 10, 16);
+ assertArrayEquals("data", new byte[]{0, 0, 0, 1, 0, 1, 0, 2, 3}, list.toByteArray());
+
+ list.retainAll(List.of((byte) 1, (byte) 2));
+ assertListStats(list, 3, 16, 16);
+ assertArrayEquals("data", new byte[]{1, 1, 2}, list.toByteArray());
+
+ list.clear();
+ assertListStats(list, 0, 17, 8);
+ }
+
+
+
+ public static void assertListStats(PrimitiveList> list, int size, int modCnt, int length) {
+ assertEquals("size", size, getSize(list));
+ assertEquals("modCnt", modCnt, getModCnt(list));
+ assertEquals("length", length, getLength(list));
+ }
+
+ public static final Random seedRng = new Random(42);
+
+ public static byte[] createByteArray(int len) {
+ return createByteArray(len, seedRng.nextInt());
+ }
+
+ public static byte[] createByteArray(int len, int seed) {
+ Random rng = new Random(seed);
+ var array = new byte[len];
+ for (int i = 0; i < len; array[i++] = (byte) rng.nextInt());
+ return array;
+ }
+
+ public static Collection toBoxedBytes(byte[] array) {
+ var result = new ArrayList(array.length);
+ for (byte b : array) {
+ result.add(b);
+ }
+ return result;
+ }
+}
diff --git a/test/dev/asdf00/general/utils/list/internal/ListReader.java b/test/dev/asdf00/general/utils/list/internal/ListReader.java
new file mode 100644
index 0000000..e6d74cc
--- /dev/null
+++ b/test/dev/asdf00/general/utils/list/internal/ListReader.java
@@ -0,0 +1,30 @@
+package dev.asdf00.general.utils.list.internal;
+
+import java.lang.reflect.Field;
+
+public class ListReader {
+ public static int getSize(AbstractBaseList list) {
+ return list.size;
+ }
+
+ public static int getModCnt(AbstractBaseList list) {
+ return list.modCnt;
+ }
+
+ public static int getLength(AbstractBaseList list) {
+ try {
+ Class> cls = list.getClass();
+ Field data = cls.getDeclaredField("data");
+ if (!data.canAccess(list)) {
+ data.setAccessible(true);
+ }
+ Object array = data.get(list);
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ return AbstractBaseList.UNSAFE.getInt(array, AbstractBaseList.OFFSET_LEN);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}