MorphicArray.java
package edu.udel.cis.vsl.tass.morph;
import java.util.Arrays;
import java.util.Iterator;
public class MorphicArray<T extends Morphic> extends MorphicObject implements
Iterable<T> {
private Morphic[] data;
/**
* Construct new component array with this length. All elements initially
* null.
*/
MorphicArray(int length) {
data = new Morphic[length];
}
MorphicArray(MorphicArray<T> oldArray) {
data = Arrays.copyOf(oldArray.data, oldArray.data.length);
}
Morphic[] data() {
return data;
}
public int length() {
return data.length;
}
@SuppressWarnings("unchecked")
public T get(int index) {
if (index >= data.length) {
throw new ArrayIndexOutOfBoundsException(index);
}
return (T) data[index];
}
public void set(int index, T element) {
assert !isCommitted();
if (index >= data.length) {
throw new ArrayIndexOutOfBoundsException(index);
}
data[index] = element;
}
@Override
protected boolean computeEquals(Morphic component) {
if (component instanceof MorphicArray<?>) {
MorphicArray<?> that = (MorphicArray<?>) component;
return Arrays.equals(data, that.data);
}
return false;
}
@Override
protected int computeHashCode() {
return Arrays.hashCode(data);
}
@SuppressWarnings("unchecked")
void canonicalizeChildren(MorphicFactoryIF<? super T> elementFactory) {
for (int i = 0; i < data.length; i++) {
T datum = (T) data[i];
if (datum != null) {
T newDatum = (T) elementFactory.canonic(datum);
if (datum != newDatum)
data[i] = newDatum;
}
}
}
@Override
protected void commitChildren() {
for (Morphic datum : data) {
if (datum != null)
datum.commit();
}
}
@Override
public Iterator<T> iterator() {
return new MorphicArrayIterator<T>(data);
}
@Override
public String toString() {
String result = "[";
int length = data.length;
for (int i = 0; i < length; i++) {
if (i > 0)
result += ", ";
result += data[i];
}
result += "]";
return result;
}
class MorphicArrayIterator<S extends Morphic> implements Iterator<S> {
Morphic[] data;
int index = 0;
MorphicArrayIterator(Morphic[] data) {
this.data = data;
}
@Override
public boolean hasNext() {
return index < data.length;
}
@SuppressWarnings("unchecked")
@Override
public S next() {
S result = (S) data[index];
index++;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}