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}