
/******************************************************************************
* MODULE     : once.gen.h
* DESCRIPTION: objects which are stored only once in memory
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license and comes WITHOUT
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
* If you don't have this file, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/

#include <tree.gen.h>

#module once (T)
#import tree
#define test<T>

class once_rep<T>: concrete_struct {
  T* ref;
public:
  inline once_rep<T> (T x): ref (new T (x)) {}
  inline ~once_rep<T> () { delete ref; }
  friend class once<T>;
};

class once<T> {
  once_rep<T>* rep;
public:
  once<T> ();
  once<T> (T x);
  ~once<T> ();
  once<T>& operator = (once<T> x);
#ifdef test<string>
  once<T> (char* s);
#endif
  inline once<T> (const once<T>& x): rep(x.rep) { rep->ref_count++; }
  inline operator T () { return *(rep->ref); }
  inline operator tree () { return ((tree) (*(rep->ref))); }
  inline bool operator == (once<T> x) { return rep == x.rep; }
  inline bool operator != (once<T> x) { return rep != x.rep; }
  inline bool operator == (T x) { return (*(rep->ref)) == x; }
  inline bool operator != (T x) { return (*(rep->ref)) != x; }
#ifdef test<string>
  inline bool operator == (char* s) { return (*(rep->ref)) == s; }
  inline bool operator != (char* s) { return (*(rep->ref)) != s; }
#endif
  inline friend int hash (once<T> x) { return ((int) ((pointer) x.rep)) >> 2; }
  inline friend ostream& operator << (ostream& out, once<T> x) {
    return out << ((T) x); }
};

#undef test<T>
#endmodule // once (T)

#module identifier
#import once (string)
typedef once<string> identifier;
#endmodule // identifier
