|
@@ -1,292 +1,292 @@
|
|
|
-/*
|
|
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
- * @copyright Ranides Atterwim
|
|
|
|
|
- * @license WTFPL
|
|
|
|
|
- * @url http://ranides.net/projects/assira
|
|
|
|
|
- */
|
|
|
|
|
-package net.ranides.assira.collection.arrays;
|
|
|
|
|
-
|
|
|
|
|
-import java.util.Comparator;
|
|
|
|
|
-import java.util.Iterator;
|
|
|
|
|
-import java.util.ListIterator;
|
|
|
|
|
-import java.util.Random;
|
|
|
|
|
-import java.util.function.BiPredicate;
|
|
|
|
|
-import net.ranides.assira.collection.IntComparator;
|
|
|
|
|
-import net.ranides.assira.collection.Swapper;
|
|
|
|
|
-import net.ranides.assira.collection.arrays.NativeArray.NativeComparator;
|
|
|
|
|
-import net.ranides.assira.collection.iterators.RandomAccessIterator;
|
|
|
|
|
-import net.ranides.assira.generic.CompareUtils;
|
|
|
|
|
-
|
|
|
|
|
-@SuppressWarnings({
|
|
|
|
|
- "PMD.AvoidReassigningParameters"
|
|
|
|
|
-})
|
|
|
|
|
-public final class NativeArrayUtils {
|
|
|
|
|
-
|
|
|
|
|
- private NativeArrayUtils() {
|
|
|
|
|
- // utility class
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> int collect(Iterator<? extends T> iterator, NativeArray target, int begin, int end) {
|
|
|
|
|
- NativeArrayAllocator.ensureFromTo(target, begin, end);
|
|
|
|
|
- int j = end;
|
|
|
|
|
- while (j-- != 0 && iterator.hasNext()) {
|
|
|
|
|
- target.set(begin++, iterator.next());
|
|
|
|
|
- }
|
|
|
|
|
- return end - j - 1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> int collect(Iterator<? extends T> iterator, NativeArray target) {
|
|
|
|
|
- return collect(iterator, target, 0, target.size());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Fills the given array with the given value.
|
|
|
|
|
- *
|
|
|
|
|
- * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
|
|
- * corresponding method in {@link java.util.Arrays}.
|
|
|
|
|
- *
|
|
|
|
|
- * @param array an array.
|
|
|
|
|
- * @param value the new value for all elements of the array.
|
|
|
|
|
- */
|
|
|
|
|
- public static <T> void fill(NativeArray array, T value) {
|
|
|
|
|
- array.set(0, array.size(), value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> void fill(NativeArray array, int begin, int end, T value) {
|
|
|
|
|
- NativeArrayAllocator.ensureFromTo(array, begin, end);
|
|
|
|
|
- array.set(begin, end, value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <S extends Swapper> S reverse(S swapper, int begin, int end){
|
|
|
|
|
- while(begin < --end){
|
|
|
|
|
- swapper.swap(begin++, end);
|
|
|
|
|
- }
|
|
|
|
|
- return swapper;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <S extends Swapper> S reverse(S swapper, int size) {
|
|
|
|
|
- return reverse(swapper, 0, size);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray reverse(NativeArray array) {
|
|
|
|
|
- reverse(array, array.size());
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static boolean equals(NativeArray array1, NativeArray array2) {
|
|
|
|
|
- return array1.equals(array2);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> NativeArray head(NativeArray values, int index) {
|
|
|
|
|
- return slice(values, 0, index);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> NativeArray head(NativeArray values, T value, Comparator<? super T> cmp) {
|
|
|
|
|
- return slice(values, 0, ifind(values, value, 0, cmp));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> NativeArray tail(NativeArray values, int index) {
|
|
|
|
|
- return slice(values, index, values.size());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> NativeArray tail(NativeArray values, T value, Comparator<? super T> cmp) {
|
|
|
|
|
- return slice(values, ifind(values, value, 0, cmp), values.size());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> NativeArray slice(NativeArray values, T begin, T end, Comparator<? super T> cmp) {
|
|
|
|
|
- int bi = ifind(values, begin, 0, cmp);
|
|
|
|
|
- int ei = ifind(values, end, bi, cmp);
|
|
|
|
|
- return slice(values, bi, ei);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray slice(NativeArray values, int begin, int end) {
|
|
|
|
|
- int size = end - begin;
|
|
|
|
|
- NativeArray result = values.allocate(size);
|
|
|
|
|
- NativeArrayUtils.copy(values, begin, result, 0, size);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray rotate(NativeArray array, int offset) {
|
|
|
|
|
- int n = array.size();
|
|
|
|
|
- offset = offset % n;
|
|
|
|
|
- if( offset > 0) {
|
|
|
|
|
- int a = n - offset;
|
|
|
|
|
- reverse(array, 0, a);
|
|
|
|
|
- reverse(array, a, n);
|
|
|
|
|
- reverse(array, 0, n);
|
|
|
|
|
- }
|
|
|
|
|
- else if( offset < 0) {
|
|
|
|
|
- rotate(array, offset+n);
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static <T> int ifind(NativeArray values, T value, int begin, Comparator<? super T> cmp) {
|
|
|
|
|
- NativeComparator icmp = values.rcmp(value, cmp);
|
|
|
|
|
- int i = begin, n = values.size();
|
|
|
|
|
- while(i<n && icmp.compare(i) < 0) {
|
|
|
|
|
- i++;
|
|
|
|
|
- }
|
|
|
|
|
- return i;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray shuffle(Random random, NativeArray array) {
|
|
|
|
|
- shuffle(random, array.size(), array);
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static void shuffle(Random random, int size, Swapper swapper) {
|
|
|
|
|
- for(int i=size; i>1; i--) {
|
|
|
|
|
- swapper.swap(i-1, random.nextInt(i));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static int size(NativeArray array) {
|
|
|
|
|
- return array.size();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("SuspiciousSystemArraycopy")
|
|
|
|
|
- public static <T> NativeArray copy(NativeArray src, int srcpos, NativeArray dst, int dstpos, int size) {
|
|
|
|
|
- System.arraycopy(src.array(), srcpos, dst.array(), dstpos, size);
|
|
|
|
|
- return dst;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray copy(NativeArray array) {
|
|
|
|
|
- int n = array.size();
|
|
|
|
|
- return copy(array, 0, NativeArrayAllocator.forPrototype(array, n), 0, n);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray concat(NativeArray a, NativeArray b) {
|
|
|
|
|
- int as = a.size();
|
|
|
|
|
- int bs = b.size();
|
|
|
|
|
- NativeArray result = a.allocate(as+bs);
|
|
|
|
|
- copy(a, 0, result, 0, as);
|
|
|
|
|
- copy(b, 0, result, as, bs);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray append(NativeArray a, Object value) {
|
|
|
|
|
- int as = a.size();
|
|
|
|
|
- NativeArray result = a.allocate(as + 1);
|
|
|
|
|
- copy(a, 0, result, 0, as);
|
|
|
|
|
- result.set(as, value);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static NativeArray prepend(NativeArray a, Object value) {
|
|
|
|
|
- int as = a.size();
|
|
|
|
|
- NativeArray result = a.allocate(as + 1);
|
|
|
|
|
- copy(a, 0, result, 1, as);
|
|
|
|
|
- result.set(0, value);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Removes first element from array and moves all elements to the left.
|
|
|
|
|
- * Note that last element in array will be duplicated.
|
|
|
|
|
- * @param a
|
|
|
|
|
- * @return removed value
|
|
|
|
|
- */
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public static <T> T shift(NativeArray a) {
|
|
|
|
|
- int n = a.size();
|
|
|
|
|
- if(n == 0) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- Object value = a.get(0);
|
|
|
|
|
- for(int i=1; i<n; i++) {
|
|
|
|
|
- a.move(i-1, i);
|
|
|
|
|
- }
|
|
|
|
|
- return (T)value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Removes last element from array and moves all elements to the right.
|
|
|
|
|
- * Note that first element in array will be duplicated.
|
|
|
|
|
- * @param a
|
|
|
|
|
- * @return
|
|
|
|
|
- */
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public static <T> T unshift(NativeArray a) {
|
|
|
|
|
- int n = a.size();
|
|
|
|
|
- if(n == 0) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- Object value = a.get(n-1);
|
|
|
|
|
- for(int i=n-1; i>0; i--) {
|
|
|
|
|
- a.move(i, i-1);
|
|
|
|
|
- }
|
|
|
|
|
- return (T)value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> ListIterator<T> iterator(NativeArray array) {
|
|
|
|
|
- return iterator(array, 0, array.size());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public static <T> ListIterator<T> iterator(NativeArray array, int begin, int end) {
|
|
|
|
|
- return new RandomAccessIterator<T>() {
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int size() {
|
|
|
|
|
- return end-begin;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected T get(int index) {
|
|
|
|
|
- return (T)array.get(begin+index);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected void set(int index, T value) {
|
|
|
|
|
- array.set(begin+index, value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> boolean equals(NativeArray a, NativeArray b, Comparator<? super T> cmp) {
|
|
|
|
|
- if(a.size() != b.size()) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- IntComparator icmp = a.comparator(b, cmp);
|
|
|
|
|
- for(int i=0, n=a.size(); i<n; i++) {
|
|
|
|
|
- if( 0 != icmp.compare(i,i)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> boolean equals(NativeArray a, NativeArray b, BiPredicate<? super T,? super T> predicate) {
|
|
|
|
|
- if(a.size() != b.size()) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- Comparator<T> vcmp = (av,bv) -> predicate.test(av, bv) ? 0 : -1;
|
|
|
|
|
- IntComparator icmp = a.comparator(b, vcmp);
|
|
|
|
|
- for(int i=0, n=a.size(); i<n; i++) {
|
|
|
|
|
- if( 0 != icmp.compare(i,i)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> int compare(NativeArray a, NativeArray b) {
|
|
|
|
|
- return icompare(a.size(), b.size(), a.comparator(b));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static <T> int compare(NativeArray a, NativeArray b, Comparator<? super T> cmp) {
|
|
|
|
|
- return icompare(a.size(), b.size(), a.comparator(b, cmp));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static <T> int icompare(int a, int b, IntComparator cmp) {
|
|
|
|
|
- for(int i=0, n=Math.min(a,b); i<n; i++) {
|
|
|
|
|
- int ic = cmp.compare(i,i);
|
|
|
|
|
- if(ic != 0) {
|
|
|
|
|
- return ic;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return CompareUtils.cmp(a,b);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
+ * @copyright Ranides Atterwim
|
|
|
|
|
+ * @license WTFPL
|
|
|
|
|
+ * @url http://ranides.net/projects/assira
|
|
|
|
|
+ */
|
|
|
|
|
+package net.ranides.assira.collection.arrays;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Comparator;
|
|
|
|
|
+import java.util.Iterator;
|
|
|
|
|
+import java.util.ListIterator;
|
|
|
|
|
+import java.util.Random;
|
|
|
|
|
+import java.util.function.BiPredicate;
|
|
|
|
|
+import net.ranides.assira.collection.IntComparator;
|
|
|
|
|
+import net.ranides.assira.collection.Swapper;
|
|
|
|
|
+import net.ranides.assira.collection.arrays.NativeArray.NativeComparator;
|
|
|
|
|
+import net.ranides.assira.collection.iterators.RandomAccessIterator;
|
|
|
|
|
+import net.ranides.assira.generic.CompareUtils;
|
|
|
|
|
+
|
|
|
|
|
+@SuppressWarnings({
|
|
|
|
|
+ "PMD.AvoidReassigningParameters"
|
|
|
|
|
+})
|
|
|
|
|
+public final class NativeArrayUtils {
|
|
|
|
|
+
|
|
|
|
|
+ private NativeArrayUtils() {
|
|
|
|
|
+ // utility class
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> int collect(Iterator<? extends T> iterator, NativeArray target, int begin, int end) {
|
|
|
|
|
+ NativeArrayAllocator.ensureFromTo(target, begin, end);
|
|
|
|
|
+ int j = end;
|
|
|
|
|
+ while (j-- != 0 && iterator.hasNext()) {
|
|
|
|
|
+ target.set(begin++, iterator.next());
|
|
|
|
|
+ }
|
|
|
|
|
+ return end - j - 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> int collect(Iterator<? extends T> iterator, NativeArray target) {
|
|
|
|
|
+ return collect(iterator, target, 0, target.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Fills the given array with the given value.
|
|
|
|
|
+ *
|
|
|
|
|
+ * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
|
|
+ * corresponding method in {@link java.util.Arrays}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param array an array.
|
|
|
|
|
+ * @param value the new value for all elements of the array.
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <T> void fill(NativeArray array, T value) {
|
|
|
|
|
+ array.set(0, array.size(), value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> void fill(NativeArray array, int begin, int end, T value) {
|
|
|
|
|
+ NativeArrayAllocator.ensureFromTo(array, begin, end);
|
|
|
|
|
+ array.set(begin, end, value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <S extends Swapper> S reverse(S swapper, int begin, int end){
|
|
|
|
|
+ while(begin < --end){
|
|
|
|
|
+ swapper.swap(begin++, end);
|
|
|
|
|
+ }
|
|
|
|
|
+ return swapper;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <S extends Swapper> S reverse(S swapper, int size) {
|
|
|
|
|
+ return reverse(swapper, 0, size);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray reverse(NativeArray array) {
|
|
|
|
|
+ reverse(array, array.size());
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean equals(NativeArray array1, NativeArray array2) {
|
|
|
|
|
+ return array1.equals(array2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> NativeArray head(NativeArray values, int index) {
|
|
|
|
|
+ return slice(values, 0, index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> NativeArray head(NativeArray values, T value, Comparator<? super T> cmp) {
|
|
|
|
|
+ return slice(values, 0, ifind(values, value, 0, cmp));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> NativeArray tail(NativeArray values, int index) {
|
|
|
|
|
+ return slice(values, index, values.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> NativeArray tail(NativeArray values, T value, Comparator<? super T> cmp) {
|
|
|
|
|
+ return slice(values, ifind(values, value, 0, cmp), values.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> NativeArray slice(NativeArray values, T begin, T end, Comparator<? super T> cmp) {
|
|
|
|
|
+ int bi = ifind(values, begin, 0, cmp);
|
|
|
|
|
+ int ei = ifind(values, end, bi, cmp);
|
|
|
|
|
+ return slice(values, bi, ei);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray slice(NativeArray values, int begin, int end) {
|
|
|
|
|
+ int size = end - begin;
|
|
|
|
|
+ NativeArray result = values.allocate(size);
|
|
|
|
|
+ NativeArrayUtils.copy(values, begin, result, 0, size);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray rotate(NativeArray array, int offset) {
|
|
|
|
|
+ int n = array.size();
|
|
|
|
|
+ offset = offset % n;
|
|
|
|
|
+ if( offset > 0) {
|
|
|
|
|
+ int a = n - offset;
|
|
|
|
|
+ reverse(array, 0, a);
|
|
|
|
|
+ reverse(array, a, n);
|
|
|
|
|
+ reverse(array, 0, n);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if( offset < 0) {
|
|
|
|
|
+ rotate(array, offset+n);
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static <T> int ifind(NativeArray values, T value, int begin, Comparator<? super T> cmp) {
|
|
|
|
|
+ NativeComparator icmp = values.rcmp(value, cmp);
|
|
|
|
|
+ int i = begin, n = values.size();
|
|
|
|
|
+ while(i<n && icmp.compare(i) < 0) {
|
|
|
|
|
+ i++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return i;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray shuffle(Random random, NativeArray array) {
|
|
|
|
|
+ shuffle(random, array.size(), array);
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void shuffle(Random random, int size, Swapper swapper) {
|
|
|
|
|
+ for(int i=size; i>1; i--) {
|
|
|
|
|
+ swapper.swap(i-1, random.nextInt(i));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static int size(NativeArray array) {
|
|
|
|
|
+ return array.size();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("SuspiciousSystemArraycopy")
|
|
|
|
|
+ public static <T> NativeArray copy(NativeArray src, int srcpos, NativeArray dst, int dstpos, int size) {
|
|
|
|
|
+ System.arraycopy(src.array(), srcpos, dst.array(), dstpos, size);
|
|
|
|
|
+ return dst;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray copy(NativeArray array) {
|
|
|
|
|
+ int n = array.size();
|
|
|
|
|
+ return copy(array, 0, NativeArrayAllocator.forPrototype(array, n), 0, n);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray concat(NativeArray a, NativeArray b) {
|
|
|
|
|
+ int as = a.size();
|
|
|
|
|
+ int bs = b.size();
|
|
|
|
|
+ NativeArray result = a.allocate(as+bs);
|
|
|
|
|
+ copy(a, 0, result, 0, as);
|
|
|
|
|
+ copy(b, 0, result, as, bs);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray append(NativeArray a, Object value) {
|
|
|
|
|
+ int as = a.size();
|
|
|
|
|
+ NativeArray result = a.allocate(as + 1);
|
|
|
|
|
+ copy(a, 0, result, 0, as);
|
|
|
|
|
+ result.set(as, value);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static NativeArray prepend(NativeArray a, Object value) {
|
|
|
|
|
+ int as = a.size();
|
|
|
|
|
+ NativeArray result = a.allocate(as + 1);
|
|
|
|
|
+ copy(a, 0, result, 1, as);
|
|
|
|
|
+ result.set(0, value);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Removes first element from array and moves all elements to the left.
|
|
|
|
|
+ * Note that last element in array will be duplicated.
|
|
|
|
|
+ * @param a
|
|
|
|
|
+ * @return removed value
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public static <T> T shift(NativeArray a) {
|
|
|
|
|
+ int n = a.size();
|
|
|
|
|
+ if(n == 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ Object value = a.get(0);
|
|
|
|
|
+ for(int i=1; i<n; i++) {
|
|
|
|
|
+ a.move(i-1, i);
|
|
|
|
|
+ }
|
|
|
|
|
+ return (T)value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Removes last element from array and moves all elements to the right.
|
|
|
|
|
+ * Note that first element in array will be duplicated.
|
|
|
|
|
+ * @param a
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public static <T> T unshift(NativeArray a) {
|
|
|
|
|
+ int n = a.size();
|
|
|
|
|
+ if(n == 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ Object value = a.get(n-1);
|
|
|
|
|
+ for(int i=n-1; i>0; i--) {
|
|
|
|
|
+ a.move(i, i-1);
|
|
|
|
|
+ }
|
|
|
|
|
+ return (T)value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> ListIterator<T> iterator(NativeArray array) {
|
|
|
|
|
+ return iterator(array, 0, array.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public static <T> ListIterator<T> iterator(NativeArray array, int begin, int end) {
|
|
|
|
|
+ return new RandomAccessIterator<T>() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int size() {
|
|
|
|
|
+ return end-begin;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected T get(int index) {
|
|
|
|
|
+ return (T)array.get(begin+index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected void set(int index, T value) {
|
|
|
|
|
+ array.set(begin+index, value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> boolean equals(NativeArray a, NativeArray b, Comparator<? super T> cmp) {
|
|
|
|
|
+ if(a.size() != b.size()) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ IntComparator icmp = a.comparator(b, cmp);
|
|
|
|
|
+ for(int i=0, n=a.size(); i<n; i++) {
|
|
|
|
|
+ if( 0 != icmp.compare(i,i)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> boolean equals(NativeArray a, NativeArray b, BiPredicate<? super T,? super T> predicate) {
|
|
|
|
|
+ if(a.size() != b.size()) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ Comparator<T> vcmp = (av,bv) -> predicate.test(av, bv) ? 0 : -1;
|
|
|
|
|
+ IntComparator icmp = a.comparator(b, vcmp);
|
|
|
|
|
+ for(int i=0, n=a.size(); i<n; i++) {
|
|
|
|
|
+ if( 0 != icmp.compare(i,i)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> int compare(NativeArray a, NativeArray b) {
|
|
|
|
|
+ return icompare(a.size(), b.size(), a.comparator(b));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static <T> int compare(NativeArray a, NativeArray b, Comparator<? super T> cmp) {
|
|
|
|
|
+ return icompare(a.size(), b.size(), a.comparator(b, cmp));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static <T> int icompare(int a, int b, IntComparator cmp) {
|
|
|
|
|
+ for(int i=0, n=Math.min(a,b); i<n; i++) {
|
|
|
|
|
+ int ic = cmp.compare(i,i);
|
|
|
|
|
+ if(ic != 0) {
|
|
|
|
|
+ return ic;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return CompareUtils.cmp(a,b);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|