/*
 * set.cpp
 */

#include <iostream> 
 
using namespace std;

class Set {
	int * data;
	int size;
public:
	Set();
	Set(Set& s);
	~Set();
	void add(int elem);
	bool remove(int elem);
	bool find(int elem);
	friend ostream& operator<<(ostream& output_stream, Set& s);
	Set& operator+=(int elem) {
		add(elem);
		return *this; // typeof(this) = Set *
	};
	Set& operator-=(int elem) {
		remove(elem);
		return *this; // typeof(this) = Set *
	};
	Set operator+(Set & rhs);
};

Set::Set() : size(0)
{
}

Set::Set(Set& s)
{
	size = s.size;
	data = new int[size];
	for (int i = 0; i < size;i++) {
		data[i] = s.data[i];
	}
}

Set::~Set()
{
	if (size > 0)
		delete [] data;
}


void Set::add(int elem)
{
	if (find(elem))
		return;
		
	int * new_data = new int[size + 1];
	for (int i = 0; i < size;i++) {
		new_data[i] = data[i];
	}
	new_data[size] = elem;
	
	if (size > 0)
		delete [] data;
	data = new_data;
	size++;
}

bool Set::remove(int elem)
{
	int i;
	for (i = 0; i < size;i++) {
		if (data[i] == elem)
			break;
	}
	
	if (i == size)
		return false;
		
	size--;
	if (size > 0) {
		for (int j = i; j < size;j++) {
			data[j] = data[j + 1];
		}
	
		int * new_data = new int[size];
		for (int i = 0; i < size;i++) {
			new_data[i] = data[i];
		}
	
		delete [] data;
		data = new_data;
	}
	else
		delete [] data;
	return true;
}

bool Set::find(int elem)
{
	for (int i = 0; i < size;i++) {
		if (data[i] == elem)
			return true;
	}
	return false;
}

Set Set::operator+(Set & rhs)
{
	Set result(rhs);
	for (int i = 0; i < size;i++) {
		result.add(data[i]);
	}
	return result;
}

ostream& operator<<(ostream& output_stream, Set & s)
{
	output_stream << "-------------------------" << endl;
	for (int i = 0;i < s.size;i++) {
		output_stream << i << ":" << s.data[i] << endl;
	}
	return output_stream;
}

int main(int argc, char **argv)
{
	Set s;
	
	s += 20; // s = s + 20;
	s += 2;
	s += 50;
	s += 30;
	s += 50;
	
	cout << "S: " << s << endl;
	
	s -= 50;
	s -= 1;
	
	cout << "S: " << s << endl;
	
	Set s1 = s;
	
	cout << "S1: " << s1 << endl;
	
	s1 -= 20;
	cout << "S: " << s << endl;
	cout << "S1: " << s1 << endl;
	
	Set s2;
	s2 += 10;
	s2 += 15;
	s2 += 30;
	cout << "S2: " << s2 << endl;
	
	Set s3 = s1 + s2;
	cout << "S3: " << s3 << endl;
	
	return 0;
}

