/*
 * Autor: Daniel Michalik, 30.11.2004
 * Verwendung des Codes nur mit explizitem Einverstaendnis des Autors
 *
 * Keinerlei Garantie fuer Korrektheit des Codes. Benutzung auf eigene Gefahr. 
 */

#include <string>
#include <iostream>
#include <fstream>
#include <set>
#include <iterator>

namespace std {
	/* Ueberladen der stream-Operatoren fuer pair, Ordnungsrelation 
	 * ist bereits korrekt durch die STL implementiert */
	ostream& operator<< (ostream& os, const pair<double,double>& p) {
		os << p.first << " " << p.second;
		return os;
	}
	istream& operator>> (istream& is, pair<double,double>& p) {
		is >> p.first >> p.second;
		return is;
	}
}

/* Boese, aber wirksam */
using namespace std;
/* Besser waere es ein Konstrukt dieser Art zu verwenden:
 * using std::cout;
 * using std::string;
 * usw.
 */

/* Template, dass mit allen drei moeglichen Datentypen funktioniert */
template <class T> class Intersect {
	private:
		set<T> A;
		set<T> B;
		T temp;
	public:
		void intersectiere() { 
			ifstream file1("file1.txt");
			if (file1.fail()) {
				  cerr << "file1.txt nicht gefunden." << endl; exit(-1);
			}
			while(file1>> temp) {
				A.insert(temp);
			}
			file1.close();

			ifstream file2("file2.txt");
			if (file2.fail()) {
				  cerr << "file2.txt nicht gefunden." << endl; exit(-1);
			}
			while(file2>> temp) {
				B.insert(temp);
			}
			file2.close();

			set_intersection(A.begin(), A.end(), B.begin(), B.end(),ostream_iterator < T >(cout, " "));
		}
};

int main(int argc, char* argv[]) {
	/* Aufruf je nach Parameter mit passendem Datentyp */
	if(argc == 1) {
		Intersect <string> i;
		i.intersectiere();
	} else if (strcmp(argv[1], "-n") == 0) {
		Intersect <int> i;
		i.intersectiere();
	} else if (strcmp(argv[1], "-v") == 0) {
		Intersect <pair <double,double> > i;
		//                             ^ wichtiges Leerzeichen!
		i.intersectiere();
	}
}

/* Jetzt erstmal einen Kaffee :-) */

