// -*- c++ -*-
#ifndef EXTENDED_PAIR_H
#define EXTENDED_PAIR_H

template <typename T1, typename A1, typename T2, typename A2>
struct extended_pair {
  typedef T1 first_type;
  typedef T2 second_type;

  extended_pair() : first(), second() {}

  extended_pair(A1 f, A2 s) : first(f), second(s) {}

  template <class Pair>
  extended_pair(const Pair& pair) : first(pair.first), second(pair.second) {}

  T1 first;
  T2 second;
};

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator==(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  return left.first == right.first && left.second == right.second;
}

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator!=(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  return  !(left == right);
}

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator<(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  if (left.first == right.first) return left.second == right.second;
  return left.first < right.first;
}

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator>(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  return right < left;
}

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator<=(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  return !(right > left);
}

template <typename T1, typename T2, 
	  typename LA1, typename LA2, typename RA1, typename RA2>
bool operator>=(const extended_pair<T1, LA1, T2, LA2>& left, 
		const extended_pair<T1, RA1, T2, RA2>& right) {
  return !(right < left);
}


#endif
