template<typename T>
class Array {
T* data;
int size;
public:
Array () {
this->data = new T[0];
this->size = 0;
}
Array (T* data, int size) {
this->data = data;
this->size = size;
}
Array (Array<T> data) {
this->data = data.data;
this->size = data.size;
}
T add (T value) {
return this->add(new T[] { value }, 1);
}
T add (T value, int index) {
return this->add(new T[] { value }, 1, index);
}
T add (Array<T> value) {
return this->add(value.data, value.size);
}
T add (Array<T> value, int index) {
return this->add(value.data, value.size, index);
}
T add (T* value, int len) {
this->expand(len);
this->set(value, this->size, len);
this->size += len;
return value;
}
T add (T* value, int len, int index) {
this->expand(len);
int size = this->size - index;
Array<T> after = this->get(index, size);
this->set(after.data, index + len, size);
this->set(value, index, len);
this->size++;
return value;
}
Array<T> operator + (T value) {
this->clone().add(value);
return *this;
}
Array<T> operator + (Array<T> value) {
this->clone().add(value);
return *this;
}
Array<T> operator += (T value) {
this->add(value);
return *this;
}
Array<T> operator += (Array<T> value) {
this->add(value);
return *this;
}
T remove (int index) {
if (index < 0) return NULL;
if (index >= this->size) return NULL;
T value = this->data[index];
if (index != this->size - 1) {
int size = this->size - index;
T* after = this->get(index, size);
this->set(after, index - 1, size);
}
this->data[this->size - 1] = NULL;
this->size--;
return value;
}
T remove (T value) {
return this->remove(this->indexOf(value));
}
Array<T> remove (Array<T> value) {
return this->remove(value.data, value.size);
}
Array<T> remove (T* value, int len) {
Array<T> array = Array<T>();
for (int i = 0; i < len; i++) {
if (this->remove(value[i]) != NULL)
array.add(value[i]);
}
return array;
}
Array<T> operator - (int index) {
this->clone().remove(index);
return *this;
}
Array<T> operator - (T value) {
this->clone().remove(value);
return *this;
}
Array<T> operator - (Array<T> value) {
this->clone().remove(value);
return *this;
}
Array<T> operator -= (int index) {
this->remove(index);
return *this;
}
Array<T> operator -= (T value) {
this->remove(value);
return *this;
}
Array<T> operator -= (Array<T> value) {
this->remove(value);
return *this;
}
Array<T> retain (Array<T> value) {
return this->retain(value.data, value.size);
}
Array<T> retain (T* value, int len) {
Array<T> array = Array<T>();
for (int i = 0; i < len; i++) {
if (this->indexOf(value[i]) != -1)
array.add(value[i]);
}
this->data = array.data;
this->size = array.size;
return array;
}
Array<T> operator * (Array<T> value) {
this->clone().retain(value);
return *this;
}
Array<T> operator *= (Array<T> value) {
this->retain(value);
return *this;
}
int compare (Array<T> value) {
if (this->size != value.size) return this->size - value.size;
for (int i = 0; i < this->size; i++)
if (this->data[i] != value.data[i])
return i;
return 0;
}
bool operator == (Array<T> value) {
return this->compare(value) == 0;
}
bool operator != (Array<T> value) {
return this->compare(value) != 0;
}
T* operator & () {
return this->data;
}
Array<T> operator << (T value) {
this->add(value);
return *this;
}
Array<T> operator << (Array<T> value) {
this->add(value);
return *this;
}
T operator >> (T* value) {
value = this->get(0);
return *value;
}
Array<T> operator >> (Array<T>* value) {
value = this->clone();
return *value;
}
T operator [] (int target) {
return this->get(target);
}
int operator [] (T target) {
return this->indexOf(target);
}
int indexOf (T target) {
for (int i = 0; i < this->size; i++)
if (this->data[i] == target)
return i;
return -1;
}
bool contains (T target) {
return this->indexOf(target) != -1;
}
bool containsAll (Array<T> target) {
if (target.size > this->size) return false;
for (int i = 0; i < target.size; i++)
if (!this->contains(target[i]))
return false;
return true;
}
bool containsAny (Array<T> target) {
for (int i = 0; i < target.size; i++)
if (this->contains(target[i]))
return true;
return false;
}
Array<T> clone () {
T nt[this->size];
for (int i = 0; i < this->size; i++)
nt[i] = this->data[i];
return Array<T>(nt, this->size);
}
T get (int index) {
if (index < 0) return NULL;
if (index >= this->size) return NULL;
return this->data[index];
}
bool isEmpty () {
return this->size == 0;
}
Array<T> reverse () {
T nt[this->size];
for (int i = 0; i < this->size; i++)
nt[this->size - 1 - i] = this->data[i];
this->data = nt;
return this;
}
T replace (T value, int index) {
T old = this.get(index);
if (old) this->data[index] = value;
return old;
}
int getSize () {
return this->size;
}
Array<T> get (int index, int length) {
return new Array<T>(this->data[index], length);
}
private:
void set (T* value, int index, int length) {
for (int i = 0; i < length; i++)
this->data[index + i] = value[i];
}
}