#include<iostream>
using namespace std;

//typedef int Datentyp[3]; // Datentyp ist für den Compiler von nun an ein Typ für ein
// Array aus 3 int-Werten
// aufgrund der Problematik Array als Parameter (s.u.) verstecken wir das Array in einem struct
struct Datentyp
{
	int arr[3];
};
// Datentyp ist nun ein Typ (ein Kästchen), der ein Array mit 3 int-Werten enthält

bool operator ==(const Datentyp a, const Datentyp b)
{
	return ((a.arr[0] == b.arr[0]) && (a.arr[1] == b.arr[1]) && (a.arr[2] == b.arr[2]));
	// wertet sich genau dann zu wahr aus, wenn jede der drei Elemente jeweils gleich sind
}

// Ausgabe für selbstdefinierte Datentypen ... (nehmen Sie das einfach als Kochrezept)
ostream& operator << (ostream& os, const Datentyp a)
// wir werden hier für den Parameter os das cout benutzen
{
	os << '(' << a.arr[0] << ',' << a.arr[1] << ',' << a.arr[2] << ')';
	return os; // muss hier noch über return zurückgegeben werden, damit
	// im Anschluss noch andere Werte mit << ... folgen können
}

struct Mengentyp
{
	Datentyp content[100];
	int nrOfValues;
};

// Auftretenes Problem: wird ein Array als Parameter übergeben, dann übergibt C/C++
// nur einen Verweis auf den entsprechenden Speicherbereich. Dies führt ggf. zu
// Problemen bei der Deklaration der Variablen/Parameter (Stichwort const)

// Abhilfe bei Arrays: man verstecke das Array in einem struct (wie oben)

void addToSet(const Datentyp value, Mengentyp & set)
// es wird davon ausgegangen, dass value noch nicht in set vorhanden ist
{
	set.content[set.nrOfValues]=value;
	set.nrOfValues++; // erhöht den Wert der Variablen nrOfValues um 1
	// Problematik, dass das set nur 100 Werte umfassen darf, wird hier zunächst ausgeblendet
}

bool isInSet(const Datentyp value, const Mengentyp set) // testet, ob Wert value in der Menge set ist
{
	int index = 0;
	for ( ; index < set.nrOfValues; index = index+1)
	{
		if (value == set.content[index]) // der Vergleich von zwei selbst definierten
			// Datentypen ist C/C++ nicht bekannt (kann es auch nicht sein)
			// wir müssen dem Compiler mitteilen, was wir hier unter == verstehen wollen (s.o.)
		{
			return true;
		}
	}
	return false;
}

void printSet(const Mengentyp set) // gibt die Werte der Menge set aus
{
	if (set.nrOfValues == 0)
	{
		cout << "Die Menge ist leer" << endl;
	}
	else
	{
		cout << "Die Menge umfasst die Werte " << set.content[0];
		int index;
		for (index=1; index < set.nrOfValues; index = index+1)
		{
			cout << ", " << set.content[index];
		}
		cout << endl;
	}
}

int main(void)
{
	Datentyp value; // einzulesener Wert
	Mengentyp set; // Menge mit maximal 100 Werte vom Typ Datentyp
	set.nrOfValues = 0; // zu Beginn 0 Werte in der Menge set

	cout << "Gib einen erstes 3er-Tupel: ";
	cin >> value.arr[0] >> value.arr[1] >> value.arr[2];

	while (value.arr[0] != 0)  
	{
		if (!(isInSet(value, set)))
		{
			addToSet(value, set);
			printSet(set);
		}
		else
		{
			cout << value << " ist bereits in der Menge vorhanden" << endl;
		}

		cout << "Gib naechstes 3er-Tupel ein (Abbruch mit (0,.,.)): ";
		cin >> value.arr[0] >> value.arr[1] >> value.arr[2];
	}

	return 0;
}








/*
ostream& operator << (ostream& os, const Bruch&a) {
os << ’(’ << a.z << ’/’ << a.n << ’)’;
return os;
}
*/

