/*
* Copyright 2015 S. Webber
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.oakgp;
import static org.oakgp.util.Utils.copyOf;
import java.util.Arrays;
import java.util.List;
import org.oakgp.node.Node;
/**
* Represents the arguments of a function.
* <p>
* Immutable.
*/
public final class Arguments {
private final Node[] args;
private final int hashCode;
/**
* Returns a new {@code Arguments} which contains the specified values.
* <p>
* Note: {@code Arguments} is immutable - so subsequent changes to {@code args} will not be reflected in the returned {@code Arguments}.
*
* @param args
* the values to be stored in the {@code Arguments}
* @return a new {@code Arguments} which contains the values specified by {@code args}
*/
public static Arguments createArguments(List<? extends Node> args) {
return new Arguments(args.toArray(new Node[args.size()]));
}
/**
* Returns a new {@code Arguments} which contains the specified values.
* <p>
* Note: {@code Arguments} is immutable - so subsequent changes to {@code args} will not be reflected in the returned {@code Arguments}.
*
* @param args
* the values to be stored in the {@code Arguments}
* @return a new {@code Arguments} which contains the values specified by {@code args}
*/
public static Arguments createArguments(Node... args) {
return new Arguments(copyOf(args));
}
/** @see #createArguments(Node...) */
private Arguments(Node[] args) {
this.args = args;
this.hashCode = Arrays.hashCode(args);
}
/**
* Returns the {@code Node} at the specified position in this {@code Arguments}.
*
* @param index
* index of the element to return
* @return the {@code Node} at the specified position in this {@code Arguments}
* @throws ArrayIndexOutOfBoundsException
* if the index is out of range (<tt>index < 0 || index >= getArgCount()</tt>)
*/
public Node getArg(int index) {
return args[index];
}
/** Returns the first argument in this {@code Arguments}. */
public Node firstArg() {
return args[0];
}
/** Returns the second argument in this {@code Arguments}. */
public Node secondArg() {
return args[1];
}
/** Returns the third argument in this {@code Arguments}. */
public Node thirdArg() {
return args[2];
}
/**
* Returns the number of elements in this {@code Arguments}.
*
* @return the number of elements in this {@code Arguments}
*/
public int getArgCount() {
return args.length;
}
/**
* Returns a new {@code Arguments} resulting from replacing the existing {@code Node} at position {@code index} with {@code replacement}.
*
* @param index
* the index of the {@code Node} that needs to be replaced.
* @param replacement
* the new {@code Node} that needs to be store.
* @return A new {@code Arguments} derived from this {@code Arguments} by replacing the element at position {@code index} with {@code replacement}.
*/
public Arguments replaceAt(int index, Node replacement) {
Node[] clone = copyOf(args);
clone[index] = replacement;
return new Arguments(clone);
}
/**
* Returns a new {@code Arguments} resulting from switching the node located at index {@code index1} with the node located at index {@code index2}.
*
* @param index1
* the index in this {@code Arguments} of the first {@code Node} to be swapped.
* @param index2
* the index in this {@code Arguments} of the second {@code Node} to be swapped.
* @return A new {@code Arguments} resulting from switching the node located at index {@code index1} with the node located at index {@code index2}.
*/
public Arguments swap(int index1, int index2) {
Node[] clone = copyOf(args);
clone[index1] = args[index2];
clone[index2] = args[index1];
return new Arguments(clone);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object o) {
return o instanceof Arguments && Arrays.equals(this.args, ((Arguments) o).args);
}
@Override
public String toString() {
return Arrays.toString(args);
}
}