//
// Copyright (C) 2008, 2009 Francesco Salvestrini
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#ifndef ELKLIB_LIBCXX_UTILITY
#define ELKLIB_LIBCXX_UTILITY

#include "elklib.h"

namespace ktl {
	namespace rel_ops {
		template<class T> inline bool operator!=(const T & x,
							 const T & y) {
			if (x < y || y < x) {
				return true;
			}
			return false;
		}

		template<class T> inline bool operator> (const T & x,
							 const T & y) {
			if (y < x) {
				return true;
			}
			return false;
		}

		template<class T> inline bool operator<=(const T & x,
							 const T & y) {
			if (y < x) {
				return false;
			}
			return true;
		}

		template<class T> inline bool operator>=(const T & x,
							 const T & y) {
			if (x < y) {
				return false;
			}
			return true;
		}
	}

	template <class T1, class T2> struct pair;
	template <class T1, class T2>
	bool operator==(const pair<T1,T2> & x, const pair<T1,T2> & y) {
		if ((x.first == y.first) && (x.second == y.second)) {
			return true;
		}
		return false;
	}
	template <class T1, class T2> bool
	operator< (const pair<T1,T2> & x, const pair<T1,T2> & y) {
		return ((x.first < y.first) ||
			(!(y.first < x.first) && (x.second < y.second)));
	}
	template <class T1, class T2>
	bool operator!=(const pair<T1,T2> & x, const pair<T1,T2> & y) {
		if ((x.first != y.first) || (x.second != y.second)) {
			return true;
		}
		return false;
	}
	template <class T1, class T2>
	bool operator> (const pair<T1,T2> & x, const pair<T1,T2> & y) {
		return ((x.first > y.first) ||
			(!(y.first > x.first) && (x.second > y.second)));
	}
	template <class T1, class T2>
	bool operator>=(const pair<T1,T2> & x, const pair<T1,T2> & y) {
		return ((x.first >= y.first) ||
			(!(y.first >= x.first) && (x.second >= y.second)));
	}
	template <class T1, class T2>
	bool operator<=(const pair<T1,T2> & x, const pair<T1,T2> & y) {
		return ((x.first <= y.first) ||
			(!(y.first <= x.first) && (x.second <= y.second)));
	}
	template <class T1, class T2> pair<T1,T2>
	make_pair(const T1 & x, const T2 & y) {
		return pair<T1,T2>(x, y);
	}


	template <class T1, class T2> struct pair {
		typedef T1 first_type;
		typedef T2 second_type;

		T1 first;
		T2 second;
		pair();
		pair(const T1& x, const T2& y);
		template<class U, class V> pair(const pair<U, V> & p);
	};


	template <class T1, class T2>
	pair<T1, T2>::pair() :
		first(), second() {  }

	template <class T1, class T2>
	pair<T1, T2>::pair(const T1 & x, const T2 & y) :
		first(x), second(y) {  }

	template <class T1, class T2>
	template<class U, class V> pair<T1, T2>::pair(const pair<U, V> & p) :
		first(p.first), second(p.second) {  }
}

#endif // ELKLIB_LIBCXX_UTILITY
