001/* 002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package org.eclipse.golo.runtime; 012 013import java.util.NoSuchElementException; 014import java.util.Objects; 015import gololang.Tuple; 016import static java.util.Arrays.copyOfRange; 017import static java.util.Arrays.copyOf; 018 019public final class ArrayHelper { 020 021 private ArrayHelper() { 022 throw new UnsupportedOperationException("Don't instantiate utility classes"); 023 } 024 025 public static Object head(Object[] array) { 026 if (array.length == 0) { 027 return null; 028 } 029 return array[0]; 030 } 031 032 public static Object[] tail(Object[] array) { 033 if (array.length >= 1) { 034 return copyOfRange(array, 1, array.length); 035 } 036 return new Object[0]; 037 } 038 039 public static Object first(Object[] array) { 040 if (array.length == 0) { 041 throw new NoSuchElementException("Empty array"); 042 } 043 return array[0]; 044 } 045 046 public static Object last(Object[] array) { 047 if (array.length == 0) { 048 throw new NoSuchElementException("Empty array"); 049 } 050 return array[array.length - 1]; 051 } 052 053 public static boolean isEmpty(Object[] array) { 054 return array.length == 0; 055 } 056 057 public static boolean contains(Object[] array, Object elt) { 058 for (Object o : array) { 059 if (Objects.deepEquals(o, elt)) { 060 return true; 061 } 062 } 063 return false; 064 } 065 066 public static int indexOf(Object[] array, Object elt) { 067 for (int i = 0; i < array.length; i++) { 068 if (Objects.deepEquals(array[i], elt)) { 069 return i; 070 } 071 } 072 return -1; 073 } 074 075 public static Object[] nullify(Object[] array, Object[] toSkip) { 076 if (array.length != toSkip.length) { 077 throw new IllegalArgumentException("Both array must have the same length"); 078 } 079 for (int i = 0; i < array.length; i++) { 080 if (Boolean.valueOf(true).equals(toSkip[i])) { // cast + check for null all in one 081 array[i] = null; 082 } 083 } 084 return array; 085 } 086 087 public static Object[] newStyleDestruct(Object[] array, int number, boolean substruct, Object[] toSkip) { 088 if (number < array.length && !substruct) { 089 throw InvalidDestructuringException.notEnoughValues(number, array.length, substruct); 090 } 091 if (number == array.length && !substruct) { 092 return nullify(copyOf(array, number), toSkip); 093 } 094 if (number <= array.length && substruct) { 095 Object[] destruct = new Object[number]; 096 System.arraycopy(array, 0, destruct, 0, number - 1); 097 if (Boolean.valueOf(false).equals(toSkip[number - 1])) { 098 destruct[number - 1] = copyOfRange(array, number - 1, array.length); 099 } 100 return nullify(destruct, toSkip); 101 } 102 if (number == array.length + 1 && substruct) { 103 Object[] destruct = copyOf(array, number); 104 if (Boolean.valueOf(false).equals(toSkip[number - 1])) { 105 destruct[number - 1] = new Object[0]; 106 } 107 return nullify(destruct, toSkip); 108 } 109 throw InvalidDestructuringException.tooManyValues(number); 110 } 111}