/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Business Objects nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Array.java
* Created: Sep 28, 2005
* By: Bo Ilic
*/
package org.openquark.cal.internal.foreignsupport.module.ArrayPrimitives;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.RandomAccess;
import org.openquark.cal.runtime.CalValue;
import org.openquark.util.ByteArrays;
/**
* A collection of helpers for the Array module.
*
* @author Bo Ilic
*/
public final class Array {
private Array(){}
/**
* The CharArray subclass is hand-written. The other subclasses are largely boiler-plated via running this main method.
*
* @param args
*/
public static void main(String[] args) {
System.out.println("Array.main inFileName outFileName");
System.out.println("Utility to boilerplate char functions to the other primitive types and Object.");
if (args == null || args.length != 2) {
throw new IllegalArgumentException("invalid number of command-line arguments.");
}
String inputFileName = args[0];
File inputFile = new File(inputFileName);
if (!inputFile.exists()) {
throw new IllegalArgumentException("invalid input file name " + inputFileName);
}
String inputString = readFile(inputFile);
String boilerplate = createBoilerplate(inputString);
String outputFileName = args[1];
File outputFile = new File(outputFileName);
writeFile(outputFile, boilerplate);
}
private static String createBoilerplate(String charBasedCode) {
String[] javaBoxedNames = {"Character", "Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double", "Object", "CalValue"};
String[] javaUnboxedNames = {"char", "boolean", "byte", "short", "int", "long", "float", "double", "Object", "CalValue"};
String heading = "\n ////////////////////////////////////////////////////////////////////////////////////\n";
StringBuilder result = new StringBuilder(heading).append(" //BEGIN AUTOMATICALLY GENERATED CODE- DO NOT MODIFY\n\n");
//start at 1 to skip "char".
for (int i = 1; i < javaUnboxedNames.length; ++i) {
String typeName = javaUnboxedNames[i];
char firstChar = typeName.charAt(0);
String properTypeName = typeName.replace(firstChar, Character.toUpperCase(firstChar));
String typeBasedCode =
charBasedCode.replaceAll("Character", javaBoxedNames[i])
.replaceAll("char", typeName)
.replaceAll("Char", properTypeName);
result.append(typeBasedCode).append('\n');
}
result.append("\n //END AUTOMATICALLY GENERATED CODE").append(heading).append("\n\n");
return result.toString();
}
private static String readFile (File fileName) {
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
StringBuilder resultString = new StringBuilder();
try {
int c;
while ((c = in.read()) != -1) {
resultString.append((char)c);
}
} finally {
in.close();
}
return resultString.toString();
} catch (IOException e) {
throw new RuntimeException("unable to read file " + fileName);
}
}
private static void writeFile (File fileName, String contents) {
try {
FileWriter writer = new FileWriter(fileName);
try {
writer.write(contents);
} finally {
writer.close();
}
} catch (IOException e) {
throw new RuntimeException("unable to write file " + fileName);
}
}
/**
* Non-boilerplated sort for boolean arrays. Java doesn't consider boolean to be orderable,
* but in CAL, false < true.
*/
static private boolean[] sortBooleanArray(boolean[] array) {
int len = array.length;
if (len == 0) {
return array;
}
int nFalse = 0;
for (int i = 0; i < len; ++i) {
if (!array[i]) {
++nFalse;
}
}
boolean[] result = new boolean[len]; //by default, initialized to all false.
Arrays.fill(result, nFalse, len, true);
return result;
}
private static int compareInt(int x, int y) {
return x < y ? -1 : (x == y ? 0 : 1);
}
/**
* Collection of static helper functions and fields for working with empty arrays.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
* @author Joseph Wong
*/
public static final class EmptyArray {
private EmptyArray() {}
public static final void throwArrayIndexOutOfBoundsException(int index) {
throw new ArrayIndexOutOfBoundsException(index);
}
/**
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return true if the subarray is the empty array
*/
public static boolean isSubArrayOK(int fromIndex, int toIndex) {
int sourceArrayLength = 0;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
return newArrayLength == 0;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return true if the array with indices from fromIndex to toIndex removed is the empty array
*/
public static boolean isRemoveRangeOK(int fromIndex, int toIndex) {
int sourceArrayLength = 0;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
return nElementsRemoved == 0;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
* IMPORTANT: the char array primitives are hand written. The others are a copy-paste where
* char/Char/Character are replaced with int/Int/Integer etc. respectively.
* Run the main method of the Array class to get the boilerplate generated.
*
* In a few cases manual modification is needed for the particular types. Use a diff tool to see
* where...
*/
/**
* Collection of static helper functions and fields for working with the Java char array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class CharArray {
private CharArray() {}
public static final char[] empty = new char[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(char[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final char[] array1(char value) {
return new char[] {value};
}
public static final char[] array2(char value1, char value2) {
return new char[] {value1, value2};
}
public static final char[] array3(char value1, char value2, char value3) {
return new char[] {value1, value2, value3};
}
public static final char[] array4(char value1, char value2, char value3, char value4) {
return new char[] {value1, value2, value3, value4};
}
public static final char[] array5(char value1, char value2, char value3, char value4, char value5) {
return new char[] {value1, value2, value3, value4, value5};
}
public static final char[] array6(char value1, char value2, char value3, char value4, char value5, char value6) {
return new char[] {value1, value2, value3, value4, value5, value6};
}
public static final char[] array7(char value1, char value2, char value3, char value4, char value5, char value6, char value7) {
return new char[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final char[] cloneReplacingNullArray (char[] array) {
if (array == null) {
return CharArray.empty;
}
return array.clone();
}
public static final char[] listToArray(List<Character> list) {
int size = list.size();
if (size == 0) {
return CharArray.empty;
}
char[] resultArray = new char[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).charValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final char[] listToArrayWithFirstElement(char firstElement, List<Character> list) {
int size = list.size() + 1;
char[] resultArray = new char[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).charValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the char array and hence any modifications
* to the char array will modify the list.
*/
public static final List<Character> arrayToList(final char[] array) {
class CharList extends AbstractList<Character> implements RandomAccess {
@Override
public Character get(int index) {
return Character.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new CharList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return char[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static char[] concat(char[] array1, char[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final char[] resultArray = new char[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of char[] Objects
* @return concatenation of the char arrays in the List
*/
public static char[] concatList(List<char[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return CharArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final char[] result = new char[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final char[] currentcharArray = list.get(i);
final int currentcharArrayLength = currentcharArray.length;
System.arraycopy(currentcharArray, 0, result, copyStartPos, currentcharArrayLength);
copyStartPos += currentcharArrayLength;
}
return result;
}
public static char[] reverse(char[] array) {
int len = array.length;
if (len == 0) {
return CharArray.empty;
}
char[] resultArray = new char[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static char[] subArray(char[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return CharArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
char[] newArray = new char[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static char[] removeRange(char[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return CharArray.empty;
}
char[] newArray = new char[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static char[] replicate(int nCopies, char valueToReplicate) {
if (nCopies <= 0) {
return CharArray.empty;
}
char[] result = new char[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Char. This relies on the
* fact that the implementation of Eq Char is just java primitive char equality.
*/
public static boolean equals(char[] array1, char[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(char[] array1, char[] array2) {
return !equals(array1, array2);
}
private static int compareElem(char x, char y) {
return x < y ? -1 : (x == y ? 0 : 1);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Char. This relies on the
* fact that the implementation of Ord Char is just java primitive char comparison.
*
* Comparison using lexicographic ordering with Ord Char used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(char[] array1, char[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareElem(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(char[] array1, char[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(char[] array1, char[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(char[] array1, char[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(char[] array1, char[] array2) {
return compare(array1, array2) > 0;
}
public static char[] max(char[] array1, char[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static char[] min(char[] array1, char[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Char is java primitive comparison on chars.
*
* @param array array to search for element in.
* @param element char to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(char[] array, char element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element char to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(char[] array, char element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(char[] array, char element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element char to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(char[] array, char element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static char[] replace(char[] array, char oldElementValue, char newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return CharArray.empty;
}
char[] newArray = new char[len];
for (int i = 0; i < len; ++i) {
char currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static char[] sort(char[] array) {
if (array.length == 0) {
return array;
}
char[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
////////////////////////////////////////////////////////////////////////////////////
//BEGIN AUTOMATICALLY GENERATED CODE- DO NOT MODIFY
/**
* Collection of static helper functions and fields for working with the Java boolean array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class BooleanArray {
private BooleanArray() {}
public static final boolean[] empty = new boolean[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(boolean[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final boolean[] array1(boolean value) {
return new boolean[] {value};
}
public static final boolean[] array2(boolean value1, boolean value2) {
return new boolean[] {value1, value2};
}
public static final boolean[] array3(boolean value1, boolean value2, boolean value3) {
return new boolean[] {value1, value2, value3};
}
public static final boolean[] array4(boolean value1, boolean value2, boolean value3, boolean value4) {
return new boolean[] {value1, value2, value3, value4};
}
public static final boolean[] array5(boolean value1, boolean value2, boolean value3, boolean value4, boolean value5) {
return new boolean[] {value1, value2, value3, value4, value5};
}
public static final boolean[] array6(boolean value1, boolean value2, boolean value3, boolean value4, boolean value5, boolean value6) {
return new boolean[] {value1, value2, value3, value4, value5, value6};
}
public static final boolean[] array7(boolean value1, boolean value2, boolean value3, boolean value4, boolean value5, boolean value6, boolean value7) {
return new boolean[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final boolean[] cloneReplacingNullArray (boolean[] array) {
if (array == null) {
return BooleanArray.empty;
}
return array.clone();
}
public static final boolean[] listToArray(List<Boolean> list) {
int size = list.size();
if (size == 0) {
return BooleanArray.empty;
}
boolean[] resultArray = new boolean[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).booleanValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final boolean[] listToArrayWithFirstElement(boolean firstElement, List<Boolean> list) {
int size = list.size() + 1;
boolean[] resultArray = new boolean[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).booleanValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the boolean array and hence any modifications
* to the boolean array will modify the list.
*/
public static final List<Boolean> arrayToList(final boolean[] array) {
class BooleanList extends AbstractList<Boolean> implements RandomAccess {
@Override
public Boolean get(int index) {
return Boolean.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new BooleanList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return boolean[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static boolean[] concat(boolean[] array1, boolean[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final boolean[] resultArray = new boolean[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of boolean[] Objects
* @return concatenation of the boolean arrays in the List
*/
public static boolean[] concatList(List<boolean[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return BooleanArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final boolean[] result = new boolean[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final boolean[] currentbooleanArray = list.get(i);
final int currentbooleanArrayLength = currentbooleanArray.length;
System.arraycopy(currentbooleanArray, 0, result, copyStartPos, currentbooleanArrayLength);
copyStartPos += currentbooleanArrayLength;
}
return result;
}
public static boolean[] reverse(boolean[] array) {
int len = array.length;
if (len == 0) {
return BooleanArray.empty;
}
boolean[] resultArray = new boolean[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static boolean[] subArray(boolean[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return BooleanArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
boolean[] newArray = new boolean[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static boolean[] removeRange(boolean[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return BooleanArray.empty;
}
boolean[] newArray = new boolean[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static boolean[] replicate(int nCopies, boolean valueToReplicate) {
if (nCopies <= 0) {
return BooleanArray.empty;
}
boolean[] result = new boolean[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Boolean. This relies on the
* fact that the implementation of Eq Boolean is just java primitive boolean equality.
*/
public static boolean equals(boolean[] array1, boolean[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(boolean[] array1, boolean[] array2) {
return !equals(array1, array2);
}
private static int compareElem(boolean x, boolean y) {
//false < true in CAL, but Java does not define an ordering on booleans.
return x ? (y ? 0 : 1) : (y ? -1 : 0);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Boolean. This relies on the
* fact that the implementation of Ord Boolean is just java primitive boolean comparison.
*
* Comparison using lexicographic ordering with Ord Boolean used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(boolean[] array1, boolean[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareElem(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(boolean[] array1, boolean[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(boolean[] array1, boolean[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(boolean[] array1, boolean[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(boolean[] array1, boolean[] array2) {
return compare(array1, array2) > 0;
}
public static boolean[] max(boolean[] array1, boolean[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static boolean[] min(boolean[] array1, boolean[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Boolean is java primitive comparison on booleans.
*
* @param array array to search for element in.
* @param element boolean to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(boolean[] array, boolean element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element boolean to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(boolean[] array, boolean element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(boolean[] array, boolean element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element boolean to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(boolean[] array, boolean element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static boolean[] replace(boolean[] array, boolean oldElementValue, boolean newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return BooleanArray.empty;
}
boolean[] newArray = new boolean[len];
for (int i = 0; i < len; ++i) {
boolean currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static boolean[] sort(boolean[] array) {
return Array.sortBooleanArray(array);
}
}
/**
* Collection of static helper functions and fields for working with the Java byte array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class ByteArray {
private ByteArray() {}
public static final byte[] empty = new byte[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(byte[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final byte[] array1(byte value) {
return new byte[] {value};
}
public static final byte[] array2(byte value1, byte value2) {
return new byte[] {value1, value2};
}
public static final byte[] array3(byte value1, byte value2, byte value3) {
return new byte[] {value1, value2, value3};
}
public static final byte[] array4(byte value1, byte value2, byte value3, byte value4) {
return new byte[] {value1, value2, value3, value4};
}
public static final byte[] array5(byte value1, byte value2, byte value3, byte value4, byte value5) {
return new byte[] {value1, value2, value3, value4, value5};
}
public static final byte[] array6(byte value1, byte value2, byte value3, byte value4, byte value5, byte value6) {
return new byte[] {value1, value2, value3, value4, value5, value6};
}
public static final byte[] array7(byte value1, byte value2, byte value3, byte value4, byte value5, byte value6, byte value7) {
return new byte[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final byte[] cloneReplacingNullArray (byte[] array) {
if (array == null) {
return ByteArray.empty;
}
return array.clone();
}
public static final byte[] listToArray(List<Byte> list) {
int size = list.size();
if (size == 0) {
return ByteArray.empty;
}
byte[] resultArray = new byte[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).byteValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final byte[] listToArrayWithFirstElement(byte firstElement, List<Byte> list) {
int size = list.size() + 1;
byte[] resultArray = new byte[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).byteValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the byte array and hence any modifications
* to the byte array will modify the list.
*/
public static final List<Byte> arrayToList(final byte[] array) {
class ByteList extends AbstractList<Byte> implements RandomAccess {
@Override
public Byte get(int index) {
return Byte.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new ByteList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return byte[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static byte[] concat(byte[] array1, byte[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final byte[] resultArray = new byte[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of byte[] Objects
* @return concatenation of the byte arrays in the List
*/
public static byte[] concatList(List<byte[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return ByteArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final byte[] result = new byte[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final byte[] currentbyteArray = list.get(i);
final int currentbyteArrayLength = currentbyteArray.length;
System.arraycopy(currentbyteArray, 0, result, copyStartPos, currentbyteArrayLength);
copyStartPos += currentbyteArrayLength;
}
return result;
}
public static byte[] reverse(byte[] array) {
int len = array.length;
if (len == 0) {
return ByteArray.empty;
}
byte[] resultArray = new byte[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static byte[] subArray(byte[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return ByteArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
byte[] newArray = new byte[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static byte[] removeRange(byte[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return ByteArray.empty;
}
byte[] newArray = new byte[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static byte[] replicate(int nCopies, byte valueToReplicate) {
if (nCopies <= 0) {
return ByteArray.empty;
}
byte[] result = new byte[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Byte. This relies on the
* fact that the implementation of Eq Byte is just java primitive byte equality.
*/
public static boolean equals(byte[] array1, byte[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(byte[] array1, byte[] array2) {
return !equals(array1, array2);
}
private static int compareElem(byte x, byte y) {
return x < y ? -1 : (x == y ? 0 : 1);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Byte. This relies on the
* fact that the implementation of Ord Byte is just java primitive byte comparison.
*
* Comparison using lexicographic ordering with Ord Byte used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(byte[] array1, byte[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareElem(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(byte[] array1, byte[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(byte[] array1, byte[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(byte[] array1, byte[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(byte[] array1, byte[] array2) {
return compare(array1, array2) > 0;
}
public static byte[] max(byte[] array1, byte[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static byte[] min(byte[] array1, byte[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Byte is java primitive comparison on bytes.
*
* @param array array to search for element in.
* @param element byte to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(byte[] array, byte element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element byte to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(byte[] array, byte element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(byte[] array, byte element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element byte to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(byte[] array, byte element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static byte[] replace(byte[] array, byte oldElementValue, byte newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return ByteArray.empty;
}
byte[] newArray = new byte[len];
for (int i = 0; i < len; ++i) {
byte currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static byte[] sort(byte[] array) {
if (array.length == 0) {
return array;
}
byte[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
/**
* Returns a compressed version of a byte array.
*/
public static byte[] compress(byte[] byteArray) throws IOException {
return ByteArrays.compressByteArray(byteArray);
}
/**
* Returns a decompressed version of a byte array.
*/
public static byte[] decompress(byte[] byteArray) throws IOException {
return ByteArrays.decompressByteArray(byteArray);
}
}
/**
* Collection of static helper functions and fields for working with the Java short array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class ShortArray {
private ShortArray() {}
public static final short[] empty = new short[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(short[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final short[] array1(short value) {
return new short[] {value};
}
public static final short[] array2(short value1, short value2) {
return new short[] {value1, value2};
}
public static final short[] array3(short value1, short value2, short value3) {
return new short[] {value1, value2, value3};
}
public static final short[] array4(short value1, short value2, short value3, short value4) {
return new short[] {value1, value2, value3, value4};
}
public static final short[] array5(short value1, short value2, short value3, short value4, short value5) {
return new short[] {value1, value2, value3, value4, value5};
}
public static final short[] array6(short value1, short value2, short value3, short value4, short value5, short value6) {
return new short[] {value1, value2, value3, value4, value5, value6};
}
public static final short[] array7(short value1, short value2, short value3, short value4, short value5, short value6, short value7) {
return new short[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final short[] cloneReplacingNullArray (short[] array) {
if (array == null) {
return ShortArray.empty;
}
return array.clone();
}
public static final short[] listToArray(List<Short> list) {
int size = list.size();
if (size == 0) {
return ShortArray.empty;
}
short[] resultArray = new short[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).shortValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final short[] listToArrayWithFirstElement(short firstElement, List<Short> list) {
int size = list.size() + 1;
short[] resultArray = new short[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).shortValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the short array and hence any modifications
* to the short array will modify the list.
*/
public static final List<Short> arrayToList(final short[] array) {
class ShortList extends AbstractList<Short> implements RandomAccess {
@Override
public Short get(int index) {
return Short.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new ShortList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return short[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static short[] concat(short[] array1, short[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final short[] resultArray = new short[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of short[] Objects
* @return concatenation of the short arrays in the List
*/
public static short[] concatList(List<short[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return ShortArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final short[] result = new short[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final short[] currentshortArray = list.get(i);
final int currentshortArrayLength = currentshortArray.length;
System.arraycopy(currentshortArray, 0, result, copyStartPos, currentshortArrayLength);
copyStartPos += currentshortArrayLength;
}
return result;
}
public static short[] reverse(short[] array) {
int len = array.length;
if (len == 0) {
return ShortArray.empty;
}
short[] resultArray = new short[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static short[] subArray(short[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return ShortArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
short[] newArray = new short[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static short[] removeRange(short[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return ShortArray.empty;
}
short[] newArray = new short[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static short[] replicate(int nCopies, short valueToReplicate) {
if (nCopies <= 0) {
return ShortArray.empty;
}
short[] result = new short[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Short. This relies on the
* fact that the implementation of Eq Short is just java primitive short equality.
*/
public static boolean equals(short[] array1, short[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(short[] array1, short[] array2) {
return !equals(array1, array2);
}
private static int compareElem(short x, short y) {
return x < y ? -1 : (x == y ? 0 : 1);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Short. This relies on the
* fact that the implementation of Ord Short is just java primitive short comparison.
*
* Comparison using lexicographic ordering with Ord Short used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(short[] array1, short[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareElem(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(short[] array1, short[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(short[] array1, short[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(short[] array1, short[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(short[] array1, short[] array2) {
return compare(array1, array2) > 0;
}
public static short[] max(short[] array1, short[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static short[] min(short[] array1, short[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Short is java primitive comparison on shorts.
*
* @param array array to search for element in.
* @param element short to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(short[] array, short element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element short to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(short[] array, short element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(short[] array, short element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element short to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(short[] array, short element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static short[] replace(short[] array, short oldElementValue, short newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return ShortArray.empty;
}
short[] newArray = new short[len];
for (int i = 0; i < len; ++i) {
short currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static short[] sort(short[] array) {
if (array.length == 0) {
return array;
}
short[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
/**
* Collection of static helper functions and fields for working with the Java int array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class IntArray {
private IntArray() {}
public static final int[] empty = new int[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(int[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final int[] array1(int value) {
return new int[] {value};
}
public static final int[] array2(int value1, int value2) {
return new int[] {value1, value2};
}
public static final int[] array3(int value1, int value2, int value3) {
return new int[] {value1, value2, value3};
}
public static final int[] array4(int value1, int value2, int value3, int value4) {
return new int[] {value1, value2, value3, value4};
}
public static final int[] array5(int value1, int value2, int value3, int value4, int value5) {
return new int[] {value1, value2, value3, value4, value5};
}
public static final int[] array6(int value1, int value2, int value3, int value4, int value5, int value6) {
return new int[] {value1, value2, value3, value4, value5, value6};
}
public static final int[] array7(int value1, int value2, int value3, int value4, int value5, int value6, int value7) {
return new int[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final int[] cloneReplacingNullArray (int[] array) {
if (array == null) {
return IntArray.empty;
}
return array.clone();
}
public static final int[] listToArray(List<Integer> list) {
int size = list.size();
if (size == 0) {
return IntArray.empty;
}
int[] resultArray = new int[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).intValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final int[] listToArrayWithFirstElement(int firstElement, List<Integer> list) {
int size = list.size() + 1;
int[] resultArray = new int[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).intValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the int array and hence any modifications
* to the int array will modify the list.
*/
public static final List<Integer> arrayToList(final int[] array) {
class IntList extends AbstractList<Integer> implements RandomAccess {
@Override
public Integer get(int index) {
return Integer.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new IntList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return int[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static int[] concat(int[] array1, int[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final int[] resultArray = new int[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of int[] Objects
* @return concatenation of the int arrays in the List
*/
public static int[] concatList(List<int[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return IntArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final int[] result = new int[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final int[] currentintArray = list.get(i);
final int currentintArrayLength = currentintArray.length;
System.arraycopy(currentintArray, 0, result, copyStartPos, currentintArrayLength);
copyStartPos += currentintArrayLength;
}
return result;
}
public static int[] reverse(int[] array) {
int len = array.length;
if (len == 0) {
return IntArray.empty;
}
int[] resultArray = new int[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static int[] subArray(int[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return IntArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
int[] newArray = new int[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static int[] removeRange(int[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return IntArray.empty;
}
int[] newArray = new int[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static int[] replicate(int nCopies, int valueToReplicate) {
if (nCopies <= 0) {
return IntArray.empty;
}
int[] result = new int[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Int. This relies on the
* fact that the implementation of Eq Int is just java primitive int equality.
*/
public static boolean equals(int[] array1, int[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(int[] array1, int[] array2) {
return !equals(array1, array2);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Int. This relies on the
* fact that the implementation of Ord Int is just java primitive int comparison.
*
* Comparison using lexicographic ordering with Ord Int used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(int[] array1, int[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareInt(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(int[] array1, int[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(int[] array1, int[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(int[] array1, int[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(int[] array1, int[] array2) {
return compare(array1, array2) > 0;
}
public static int[] max(int[] array1, int[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static int[] min(int[] array1, int[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Int is java primitive comparison on ints.
*
* @param array array to search for element in.
* @param element int to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(int[] array, int element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element int to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(int[] array, int element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(int[] array, int element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element int to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(int[] array, int element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int[] replace(int[] array, int oldElementValue, int newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return IntArray.empty;
}
int[] newArray = new int[len];
for (int i = 0; i < len; ++i) {
int currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static int[] sort(int[] array) {
if (array.length == 0) {
return array;
}
int[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
/**
* Collection of static helper functions and fields for working with the Java long array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class LongArray {
private LongArray() {}
public static final long[] empty = new long[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(long[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final long[] array1(long value) {
return new long[] {value};
}
public static final long[] array2(long value1, long value2) {
return new long[] {value1, value2};
}
public static final long[] array3(long value1, long value2, long value3) {
return new long[] {value1, value2, value3};
}
public static final long[] array4(long value1, long value2, long value3, long value4) {
return new long[] {value1, value2, value3, value4};
}
public static final long[] array5(long value1, long value2, long value3, long value4, long value5) {
return new long[] {value1, value2, value3, value4, value5};
}
public static final long[] array6(long value1, long value2, long value3, long value4, long value5, long value6) {
return new long[] {value1, value2, value3, value4, value5, value6};
}
public static final long[] array7(long value1, long value2, long value3, long value4, long value5, long value6, long value7) {
return new long[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final long[] cloneReplacingNullArray (long[] array) {
if (array == null) {
return LongArray.empty;
}
return array.clone();
}
public static final long[] listToArray(List<Long> list) {
int size = list.size();
if (size == 0) {
return LongArray.empty;
}
long[] resultArray = new long[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).longValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final long[] listToArrayWithFirstElement(long firstElement, List<Long> list) {
int size = list.size() + 1;
long[] resultArray = new long[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).longValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the long array and hence any modifications
* to the long array will modify the list.
*/
public static final List<Long> arrayToList(final long[] array) {
class LongList extends AbstractList<Long> implements RandomAccess {
@Override
public Long get(int index) {
return Long.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new LongList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return long[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static long[] concat(long[] array1, long[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final long[] resultArray = new long[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of long[] Objects
* @return concatenation of the long arrays in the List
*/
public static long[] concatList(List<long[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return LongArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final long[] result = new long[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final long[] currentlongArray = list.get(i);
final int currentlongArrayLength = currentlongArray.length;
System.arraycopy(currentlongArray, 0, result, copyStartPos, currentlongArrayLength);
copyStartPos += currentlongArrayLength;
}
return result;
}
public static long[] reverse(long[] array) {
int len = array.length;
if (len == 0) {
return LongArray.empty;
}
long[] resultArray = new long[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static long[] subArray(long[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return LongArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
long[] newArray = new long[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static long[] removeRange(long[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return LongArray.empty;
}
long[] newArray = new long[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static long[] replicate(int nCopies, long valueToReplicate) {
if (nCopies <= 0) {
return LongArray.empty;
}
long[] result = new long[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Long. This relies on the
* fact that the implementation of Eq Long is just java primitive long equality.
*/
public static boolean equals(long[] array1, long[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(long[] array1, long[] array2) {
return !equals(array1, array2);
}
public static int compareElem(long x, long y) {
return x < y ? -1 : (x == y ? 0 : 1);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Long. This relies on the
* fact that the implementation of Ord Long is just java primitive long comparison.
*
* Comparison using lexicographic ordering with Ord Long used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(long[] array1, long[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
int elementCompare = compareElem(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(long[] array1, long[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(long[] array1, long[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(long[] array1, long[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(long[] array1, long[] array2) {
return compare(array1, array2) > 0;
}
public static long[] max(long[] array1, long[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static long[] min(long[] array1, long[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Long is java primitive comparison on longs.
*
* @param array array to search for element in.
* @param element long to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(long[] array, long element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element long to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(long[] array, long element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(long[] array, long element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element long to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(long[] array, long element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static long[] replace(long[] array, long oldElementValue, long newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return LongArray.empty;
}
long[] newArray = new long[len];
for (int i = 0; i < len; ++i) {
long currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static long[] sort(long[] array) {
if (array.length == 0) {
return array;
}
long[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
/**
* Collection of static helper functions and fields for working with the Java float array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class FloatArray {
private FloatArray() {}
public static final float[] empty = new float[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(float[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final float[] array1(float value) {
return new float[] {value};
}
public static final float[] array2(float value1, float value2) {
return new float[] {value1, value2};
}
public static final float[] array3(float value1, float value2, float value3) {
return new float[] {value1, value2, value3};
}
public static final float[] array4(float value1, float value2, float value3, float value4) {
return new float[] {value1, value2, value3, value4};
}
public static final float[] array5(float value1, float value2, float value3, float value4, float value5) {
return new float[] {value1, value2, value3, value4, value5};
}
public static final float[] array6(float value1, float value2, float value3, float value4, float value5, float value6) {
return new float[] {value1, value2, value3, value4, value5, value6};
}
public static final float[] array7(float value1, float value2, float value3, float value4, float value5, float value6, float value7) {
return new float[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final float[] cloneReplacingNullArray (float[] array) {
if (array == null) {
return FloatArray.empty;
}
return array.clone();
}
public static final float[] listToArray(List<Float> list) {
int size = list.size();
if (size == 0) {
return FloatArray.empty;
}
float[] resultArray = new float[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).floatValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final float[] listToArrayWithFirstElement(float firstElement, List<Float> list) {
int size = list.size() + 1;
float[] resultArray = new float[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).floatValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the float array and hence any modifications
* to the float array will modify the list.
*/
public static final List<Float> arrayToList(final float[] array) {
class FloatList extends AbstractList<Float> implements RandomAccess {
@Override
public Float get(int index) {
return Float.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new FloatList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return float[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static float[] concat(float[] array1, float[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final float[] resultArray = new float[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of float[] Objects
* @return concatenation of the float arrays in the List
*/
public static float[] concatList(List<float[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return FloatArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final float[] result = new float[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final float[] currentfloatArray = list.get(i);
final int currentfloatArrayLength = currentfloatArray.length;
System.arraycopy(currentfloatArray, 0, result, copyStartPos, currentfloatArrayLength);
copyStartPos += currentfloatArrayLength;
}
return result;
}
public static float[] reverse(float[] array) {
int len = array.length;
if (len == 0) {
return FloatArray.empty;
}
float[] resultArray = new float[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static float[] subArray(float[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return FloatArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
float[] newArray = new float[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static float[] removeRange(float[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return FloatArray.empty;
}
float[] newArray = new float[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static float[] replicate(int nCopies, float valueToReplicate) {
if (nCopies <= 0) {
return FloatArray.empty;
}
float[] result = new float[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Float. This relies on the
* fact that the implementation of Eq Float is just java primitive float equality.
*/
public static boolean equals(float[] array1, float[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(float[] array1, float[] array2) {
return !equals(array1, array2);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Float. This relies on the
* fact that the implementation of Ord Float is just java primitive float comparison.
*
* Comparison using lexicographic ordering with Ord Float used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(float[] array1, float[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
//note that Float.compare handles NaN, -0 etc properly
int elementCompare = Float.compare(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(float[] array1, float[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(float[] array1, float[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(float[] array1, float[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(float[] array1, float[] array2) {
return compare(array1, array2) > 0;
}
public static float[] max(float[] array1, float[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static float[] min(float[] array1, float[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Float is java primitive comparison on floats.
*
* @param array array to search for element in.
* @param element float to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(float[] array, float element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element float to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(float[] array, float element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(float[] array, float element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element float to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(float[] array, float element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static float[] replace(float[] array, float oldElementValue, float newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return FloatArray.empty;
}
float[] newArray = new float[len];
for (int i = 0; i < len; ++i) {
float currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static float[] sort(float[] array) {
if (array.length == 0) {
return array;
}
float[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
/**
* Collection of static helper functions and fields for working with the Java double array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class DoubleArray {
private DoubleArray() {}
public static final double[] empty = new double[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(double[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final double[] array1(double value) {
return new double[] {value};
}
public static final double[] array2(double value1, double value2) {
return new double[] {value1, value2};
}
public static final double[] array3(double value1, double value2, double value3) {
return new double[] {value1, value2, value3};
}
public static final double[] array4(double value1, double value2, double value3, double value4) {
return new double[] {value1, value2, value3, value4};
}
public static final double[] array5(double value1, double value2, double value3, double value4, double value5) {
return new double[] {value1, value2, value3, value4, value5};
}
public static final double[] array6(double value1, double value2, double value3, double value4, double value5, double value6) {
return new double[] {value1, value2, value3, value4, value5, value6};
}
public static final double[] array7(double value1, double value2, double value3, double value4, double value5, double value6, double value7) {
return new double[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final double[] cloneReplacingNullArray (double[] array) {
if (array == null) {
return DoubleArray.empty;
}
return array.clone();
}
public static final double[] listToArray(List<Double> list) {
int size = list.size();
if (size == 0) {
return DoubleArray.empty;
}
double[] resultArray = new double[size];
for (int i = 0; i < size; ++i) {
resultArray[i] = list.get(i).doubleValue();
}
return resultArray;
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final double[] listToArrayWithFirstElement(double firstElement, List<Double> list) {
int size = list.size() + 1;
double[] resultArray = new double[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1).doubleValue();
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the double array and hence any modifications
* to the double array will modify the list.
*/
public static final List<Double> arrayToList(final double[] array) {
class DoubleList extends AbstractList<Double> implements RandomAccess {
@Override
public Double get(int index) {
return Double.valueOf(array[index]);
}
@Override
public int size() {
return array.length;
}
}
return new DoubleList();
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return double[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static double[] concat(double[] array1, double[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final double[] resultArray = new double[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of double[] Objects
* @return concatenation of the double arrays in the List
*/
public static double[] concatList(List<double[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return DoubleArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final double[] result = new double[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final double[] currentdoubleArray = list.get(i);
final int currentdoubleArrayLength = currentdoubleArray.length;
System.arraycopy(currentdoubleArray, 0, result, copyStartPos, currentdoubleArrayLength);
copyStartPos += currentdoubleArrayLength;
}
return result;
}
public static double[] reverse(double[] array) {
int len = array.length;
if (len == 0) {
return DoubleArray.empty;
}
double[] resultArray = new double[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static double[] subArray(double[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return DoubleArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
double[] newArray = new double[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static double[] removeRange(double[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return DoubleArray.empty;
}
double[] newArray = new double[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static double[] replicate(int nCopies, double valueToReplicate) {
if (nCopies <= 0) {
return DoubleArray.empty;
}
double[] result = new double[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
/**
* Support for defining the Eq a => Eq (Array a) instance when a is in fact Double. This relies on the
* fact that the implementation of Eq Double is just java primitive double equality.
*/
public static boolean equals(double[] array1, double[] array2) {
return Arrays.equals(array1, array2);
}
public static boolean notEquals(double[] array1, double[] array2) {
return !equals(array1, array2);
}
/**
* Support for defining the Ord a => Ord (Array a) instance when a is in fact Double. This relies on the
* fact that the implementation of Ord Double is just java primitive double comparison.
*
* Comparison using lexicographic ordering with Ord Double used on elements.
* @param array1
* @param array2
* @return -1, 0, or 1.
*/
public static int compare(double[] array1, double[] array2) {
if (array1 == array2) {
return 0;
}
int n = Math.min(array1.length, array2.length);
for (int i = 0; i < n; ++i) {
//note that Double.compare handles NaN, -0 etc properly
int elementCompare = Double.compare(array1[i], array2[i]);
if (elementCompare != 0) {
return elementCompare;
}
}
return compareInt(array1.length, array2.length);
}
public static boolean lessThan(double[] array1, double[] array2) {
return compare(array1, array2) < 0;
}
public static boolean lessThanEquals(double[] array1, double[] array2) {
return compare(array1, array2) <= 0;
}
public static boolean greaterThanEquals(double[] array1, double[] array2) {
return compare(array1, array2) >= 0;
}
public static boolean greaterThan(double[] array1, double[] array2) {
return compare(array1, array2) > 0;
}
public static double[] max(double[] array1, double[] array2) {
return lessThanEquals(array1, array2) ? array2 : array1;
}
public static double[] min(double[] array1, double[] array2) {
return lessThanEquals(array1, array2) ? array1 : array2;
}
/**
* Note: this method relies on the fact that we know that Eq Double is java primitive comparison on doubles.
*
* @param array array to search for element in.
* @param element double to search for.
* @return the (0-based) index of the first occurrence of element in the array or -1 if element does not occur.
*/
public static int indexOf(double[] array, double element) {
return indexOf(array, element, 0);
}
/**
* @param array array to search for element in.
* @param element double to search for.
* @param fromIndex the (0-based) index to inclusively start the search from. There are no invalid values of fromIndex.
* If fromIndex < 0, 0 is assumed. If fromIndex >= length.array -1 will be returned.
* @return the (0-based) index of the first occurrence of element in the array with index >= fromIndex or -1 if
* element does not occur.
*/
public static int indexOf(double[] array, double element, int fromIndex) {
for (int i = (fromIndex < 0 ? 0 : fromIndex), len = array.length; i < len; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static int lastIndexOf(double[] array, double element) {
return lastIndexOf(array, element, array.length - 1);
}
/**
* @param array array to search for element in.
* @param element double to search for.
* @param fromIndex There are no invalid values for fromIndex. If fromIndex < 0, then -1 is always returned.
* @return the 0-based index of the last occurrence of element within array whose index is less than or equal to fromIndex
* or -1 if element does not occur.
*/
public static int lastIndexOf(double[] array, double element, int fromIndex) {
if (fromIndex < 0) {
return -1;
}
int actualFromIndex = Math.min(fromIndex, array.length -1);
for (int i = actualFromIndex; i >= 0; --i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
public static double[] replace(double[] array, double oldElementValue, double newElementValue) {
if (oldElementValue == newElementValue) {
return array;
}
int len = array.length;
if (len == 0) {
return DoubleArray.empty;
}
double[] newArray = new double[len];
for (int i = 0; i < len; ++i) {
double currentVal = array[i];
newArray[i] = (currentVal == oldElementValue) ? newElementValue : currentVal;
}
return newArray;
}
public static double[] sort(double[] array) {
if (array.length == 0) {
return array;
}
double[] newArray = array.clone();
Arrays.sort(newArray);
return newArray;
}
}
/**
* Collection of static helper functions and fields for working with the Java Object array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class ObjectArray {
private ObjectArray() {}
public static final Object[] empty = new Object[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(Object[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final Object[] array1(Object value) {
return new Object[] {value};
}
public static final Object[] array2(Object value1, Object value2) {
return new Object[] {value1, value2};
}
public static final Object[] array3(Object value1, Object value2, Object value3) {
return new Object[] {value1, value2, value3};
}
public static final Object[] array4(Object value1, Object value2, Object value3, Object value4) {
return new Object[] {value1, value2, value3, value4};
}
public static final Object[] array5(Object value1, Object value2, Object value3, Object value4, Object value5) {
return new Object[] {value1, value2, value3, value4, value5};
}
public static final Object[] array6(Object value1, Object value2, Object value3, Object value4, Object value5, Object value6) {
return new Object[] {value1, value2, value3, value4, value5, value6};
}
public static final Object[] array7(Object value1, Object value2, Object value3, Object value4, Object value5, Object value6, Object value7) {
return new Object[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final Object[] cloneReplacingNullArray (Object[] array) {
if (array == null) {
return ObjectArray.empty;
}
return array.clone();
}
public static final Object[] listToArray(List<Object> list) {
return list.toArray(ObjectArray.empty);
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final Object[] listToArrayWithFirstElement(Object firstElement, List<Object> list) {
int size = list.size() + 1;
Object[] resultArray = new Object[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1);
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the Object array and hence any modifications
* to the Object array will modify the list.
*/
public static final List<Object> arrayToList(final Object[] array) {
return Arrays.asList(array);
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return Object[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static Object[] concat(Object[] array1, Object[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final Object[] resultArray = new Object[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of Object[] Objects
* @return concatenation of the Object arrays in the List
*/
public static Object[] concatList(List<Object[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return ObjectArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final Object[] result = new Object[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final Object[] currentObjectArray = list.get(i);
final int currentObjectArrayLength = currentObjectArray.length;
System.arraycopy(currentObjectArray, 0, result, copyStartPos, currentObjectArrayLength);
copyStartPos += currentObjectArrayLength;
}
return result;
}
public static Object[] reverse(Object[] array) {
int len = array.length;
if (len == 0) {
return ObjectArray.empty;
}
Object[] resultArray = new Object[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static Object[] subArray(Object[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return ObjectArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
Object[] newArray = new Object[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static Object[] removeRange(Object[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return ObjectArray.empty;
}
Object[] newArray = new Object[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static Object[] replicate(int nCopies, Object valueToReplicate) {
if (nCopies <= 0) {
return ObjectArray.empty;
}
Object[] result = new Object[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
}
/**
* Collection of static helper functions and fields for working with the Java CalValue array type.
*
* Note, that this class is primarily intended to support the Array.cal module. In particular, most
* of the operations below do not do destructive updates but rather make copies. Also, we can assume (in
* most cases) that the array is not a null array.
*
* @author Bo Ilic
*/
public static final class CalValueArray {
private CalValueArray() {}
public static final CalValue[] empty = new CalValue[0];
/**
* @param array
* @return representation of the array for debugging purposes.
*/
public static final String toString(CalValue[] array) {
if (array == null) {
return "null";
}
int len = array.length;
if (len == 0) {
return "[]";
}
StringBuilder result = new StringBuilder("[");
result.append(array[0]);
for (int i = 1; i < len; ++i) {
result.append(", ");
result.append(array[i]);
}
result.append("]");
return result.toString();
}
public static final CalValue[] array1(CalValue value) {
return new CalValue[] {value};
}
public static final CalValue[] array2(CalValue value1, CalValue value2) {
return new CalValue[] {value1, value2};
}
public static final CalValue[] array3(CalValue value1, CalValue value2, CalValue value3) {
return new CalValue[] {value1, value2, value3};
}
public static final CalValue[] array4(CalValue value1, CalValue value2, CalValue value3, CalValue value4) {
return new CalValue[] {value1, value2, value3, value4};
}
public static final CalValue[] array5(CalValue value1, CalValue value2, CalValue value3, CalValue value4, CalValue value5) {
return new CalValue[] {value1, value2, value3, value4, value5};
}
public static final CalValue[] array6(CalValue value1, CalValue value2, CalValue value3, CalValue value4, CalValue value5, CalValue value6) {
return new CalValue[] {value1, value2, value3, value4, value5, value6};
}
public static final CalValue[] array7(CalValue value1, CalValue value2, CalValue value3, CalValue value4, CalValue value5, CalValue value6, CalValue value7) {
return new CalValue[] {value1, value2, value3, value4, value5, value6, value7};
}
/**
* Clones the array, replacing a null array with a zero-length array.
* @param array may be null
* @return will not be null
*/
public static final CalValue[] cloneReplacingNullArray (CalValue[] array) {
if (array == null) {
return CalValueArray.empty;
}
return array.clone();
}
public static final CalValue[] listToArray(List<CalValue> list) {
return list.toArray(CalValueArray.empty);
}
/**
* @param firstElement the first element of the array to be constructed.
* @param list the remainder of the elements of the array.
* @return the array.
*/
public static final CalValue[] listToArrayWithFirstElement(CalValue firstElement, List<CalValue> list) {
int size = list.size() + 1;
CalValue[] resultArray = new CalValue[size];
resultArray[0] = firstElement;
for (int i = 1; i < size; ++i) {
resultArray[i] = list.get(i-1);
}
return resultArray;
}
/**
* @param array
* @return the returned List is backed by the CalValue array and hence any modifications
* to the CalValue array will modify the list.
*/
public static final List<CalValue> arrayToList(final CalValue[] array) {
return Arrays.asList(array);
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param array1
* @param array2
* @return CalValue[] the concatenation of array1 with array2.
* the function return array2 if array1 is empty, and vice-versa.
* @throws NullPointerException if either array1 or array2 are null.
*/
public static CalValue[] concat(CalValue[] array1, CalValue[] array2) {
int length1 = array1.length;
if (length1 == 0) {
return array2;
}
final int length2 = array2.length;
if (length2 == 0) {
return array1;
}
final CalValue[] resultArray = new CalValue[length1 + length2];
System.arraycopy(array1, 0, resultArray, 0, length1);
System.arraycopy(array2, 0, resultArray, length1, length2);
return resultArray;
}
/**
* Note: in certain circumstances, this function does not return a copy of
* the argument arrays, and hence should not be used in situations where
* the argument arrays may be mutated.
*
* @param list of CalValue[] Objects
* @return concatenation of the CalValue arrays in the List
*/
public static CalValue[] concatList(List<CalValue[]> list) {
final int nArrays = list.size();
switch (nArrays) {
case 0:
return CalValueArray.empty;
case 1:
return list.get(0);
case 2:
return concat(list.get(0), list.get(1));
default:
break;
}
int resultSize = 0;
for (int i = 0; i < nArrays; ++i) {
resultSize += list.get(i).length;
}
final CalValue[] result = new CalValue[resultSize];
int copyStartPos = 0;
for (int i = 0; i < nArrays; ++i) {
final CalValue[] currentCalValueArray = list.get(i);
final int currentCalValueArrayLength = currentCalValueArray.length;
System.arraycopy(currentCalValueArray, 0, result, copyStartPos, currentCalValueArrayLength);
copyStartPos += currentCalValueArrayLength;
}
return result;
}
public static CalValue[] reverse(CalValue[] array) {
int len = array.length;
if (len == 0) {
return CalValueArray.empty;
}
CalValue[] resultArray = new CalValue[len];
int lastIndex = len - 1;
for (int i = 0; i < len; ++i) {
resultArray[i] = array[lastIndex - i];
}
return resultArray;
}
/**
* @param array
* @param fromIndex inclusive 0-based index
* @param toIndex exclusive 0-based index
* @return copy of the array from fromIndex (inclusive) to toIndex (exclusive).
*/
public static CalValue[] subArray(CalValue[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int newArrayLength = toIndex - fromIndex;
if (newArrayLength == 0) {
return CalValueArray.empty;
}
if (newArrayLength == sourceArrayLength) {
return array;
}
CalValue[] newArray = new CalValue[newArrayLength];
System.arraycopy(array, fromIndex, newArray, 0, toIndex - fromIndex);
return newArray;
}
/**
* Efficiently removes a range of elements from an array.
* The returned array has (toIndex - fromIndex) fewer elements.
*
* @param array
* @param fromIndex inclusive index of the array to start removal from
* @param toIndex exclusive index of the array to stop removal at
* @return a copy (if necessary) of array with indices from fromIndex to toIndex removed
*/
public static CalValue[] removeRange(CalValue[] array, int fromIndex, int toIndex) {
int sourceArrayLength = array.length;
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex(" + fromIndex + ") < 0.");
}
if (toIndex > sourceArrayLength) {
throw new IndexOutOfBoundsException("toIndex(" + toIndex + ") > array.length(" + sourceArrayLength + ").");
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ").");
}
int nElementsRemoved = toIndex - fromIndex;
if (nElementsRemoved == 0) {
return array;
}
if (nElementsRemoved == sourceArrayLength) {
return CalValueArray.empty;
}
CalValue[] newArray = new CalValue[sourceArrayLength - nElementsRemoved];
if (fromIndex > 0) {
System.arraycopy(array, 0, newArray, 0, fromIndex);
}
if (toIndex < sourceArrayLength) {
System.arraycopy(array, toIndex, newArray, fromIndex, sourceArrayLength - toIndex);
}
return newArray;
}
public static CalValue[] replicate(int nCopies, CalValue valueToReplicate) {
if (nCopies <= 0) {
return CalValueArray.empty;
}
CalValue[] result = new CalValue[nCopies];
Arrays.fill(result, valueToReplicate);
return result;
}
}
//END AUTOMATICALLY GENERATED CODE
////////////////////////////////////////////////////////////////////////////////////
}