/** -*- C++ -*-
 **
 **  KAI C++ Compiler
 **
 **  Copyright (C) 1996-2001 Intel Corp. All rights reserved.
 **/
/**
 **  Lib++  : The Modena C++ Standard Library,
 **           Version 2.4, October 1997
 **
 **  Copyright (c) 1995-1997 Modena Software Inc.
 **/
#ifndef  __KAI_UTILITY
#define  __KAI_UTILITY

#include <mcompile.h>

/* ADR removed Modena's gratuitous #include of <iosfwd> from here. */

namespace std {

// Subclause 20.2.1 -- Operators

namespace rel_ops {

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

}  /* namespace rel_ops */

// Section 20.2.2 -- Pair

template <class T1, class T2>
struct pair {

    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;

    pair() : first (), second () {}
    pair(const T1& a, const T2& b) : first (a), second (b) {}

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

};

template <class T1, class T2>
inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { return x.first==y.first && x.second==y.second; }
template <class T1, class T2>
inline 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> inline bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(x == y); }
template <class T1, class T2> inline bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y) { return (y < x); }
template <class T1, class T2> inline bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(x < y); }
template <class T1, class T2> inline bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(y < x); }

template <class T1, class T2> inline pair<T1, T2> make_pair(const T1& x, const T2& y) { return pair<T1, T2> (x, y); }


#if KAI_NONSTD_UTILITY

// struct triple -- For Implementation Of Hash Tables
template <class T1, class T2, class T3>
struct triple {
    T1 first;
    T2 second;
    T3 third;
    triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
};

template <class T1, class T2, class T3>
inline bool operator==(const triple<T1, T2, T3>& x, const triple<T1, T2, T3>& y)
{ return x.first == y.first && x.second == y.second && x.third == y.third; }

template <class T1, class T2, class T3>
inline bool operator<(const triple<T1, T2, T3>& x, const triple<T1, T2, T3>& y)
{
    return x.first < y.first ||
           (! (y.first < x.first) && (x.second < y.second ||
          (! y.second < x.second) && (x.third < y.third)));
}

template <class T1, class T2, class T3>
inline triple<T1, T2, T3> make_triple(const T1& x, const T2& y, const T3& z) { return triple<T1, T2, T3>(x, y, z); }

// Section 20.2.2.3 -- Restrictor

template <class T>
class restrictor {
protected:
    T value;
public:
    restrictor (const T& x) : value (x) {}
    template <class TT>
    friend bool operator==(const restrictor<TT>& x, const restrictor<TT>& y);
    template <class TT>
    friend bool operator<(const restrictor<TT>& x, const restrictor<TT>& y);
    template <class TT>
    friend bool operator!=(const restrictor<TT>& x, const restrictor<TT>& y);
    template <class TT>
    friend bool operator>(const restrictor<TT>& x, const restrictor<TT>& y);
    template <class TT>
    friend bool operator>=(const restrictor<TT>& x, const restrictor<TT>& y);
    template <class TT>
    friend bool operator<=(const restrictor<TT>& x, const restrictor<TT>& y);
};

template <class T>
inline bool operator==(const restrictor<T>& x, const restrictor<T>& y) { return (x.value == y.value); }
template <class T>
inline bool operator<(const restrictor<T>& x, const restrictor<T>& y) { return (x.value < y.value); }
template <class T>
inline bool operator!=(const restrictor<T>& x, const restrictor<T>& y) { return !(x.value == y.value); }
template <class T>
inline bool operator>(const restrictor<T>& x, const restrictor<T>& y) { return (y.value < x.value); }
template <class T>
inline bool operator>=(const restrictor<T>& x, const restrictor<T>& y) { return !(x.value < y.value); }
template <class T>
inline bool operator<=(const restrictor<T>& x, const restrictor<T>& y) { return !(y.value < x.value); }

#endif /* KAI_NONSTD_UTILITY */

} // namespace std

#endif /* __KAI_UTILITY */

