//=-- Object.h - Provide Object superclass for data objects --------*- C++ -*-=
//
//  This Object class is meant to be subclassed so that classes will be 
//  notified with compile time errors that they don't implement a function
//  that is needed by the template data types.  If it doesn't subclass this,
//  the object will still work, but if it does not implement these functions,
//  it will get a cryptic template error.
//
//  This files also defines the DataPair template class that is used to make 
//  tuples of primative types.  The serialization functions for DataPair are
//  defined in Serialize.h though...
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner
//=---------------------------------------------------------------------------=

#ifndef OBJECT_H
#define OBJECT_H

#ifndef MSAPI   // __declspec(dllexport)
#define MSAPI
#endif

#include <iostream.h>

class MSAPI Object {
public :
  inline virtual ~Object() {}
  //virtual int Hash() const = 0;
  virtual int Compare(const Object &L) const = 0;
  virtual ostream &print(ostream &s) const = 0;

  inline int operator==(const Object &O) const { return (Compare(O) == 0); }
  inline int operator!=(const Object &O) const { return (Compare(O) != 0); }
  inline int operator< (const Object &O) const { return (Compare(O) <  0); }
  inline int operator<=(const Object &O) const { return (Compare(O) <= 0); }
  inline int operator> (const Object &O) const { return (Compare(O) >  0); }
  inline int operator>=(const Object &O) const { return (Compare(O) >= 0); }
};

inline ostream& operator<<(ostream& strm, const Object& O) {
  return O.print(strm);
}

// Class to bind two classes together in a Primary/Secondary relationship
//
template <class Primary, class Secondary>
class MSAPI DataPair : public Object {
public :
  DataPair(Primary p, Secondary s) : P(p), S(s) { }
  DataPair() {}

  int Compare(const Object &O) const { 
    if (P > ((DataPair<Primary,Secondary> &)O).P)
      return 1;
    else if (P == ((DataPair<Primary,Secondary> &)O).P)
      return 0;
    return -1;
  }

  ostream &print(ostream &O)const {
    return O << P << ":" << S << endl;
  }

  inline Primary &GetPrimary()     { return P; }
  inline Secondary &GetSecondary() { return S; }
  inline const Primary &GetPrimary()     const { return P; }
  inline const Secondary &GetSecondary() const { return S; }
  inline void SetSecondary(Secondary &s) { S = s; }

  static int SortBySecondary(DataPair<Primary,Secondary> *A1, 
                             DataPair<Primary,Secondary> *A2) {
    return A2->S > A1->S;
  }

  Primary P;
  Secondary S;
};

#endif
