
/******************************************************************************
* MODULE     : once.gen.cc
* 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 <once.gen.h>
#include <hashmap.gen.h>

#module code_once (T)
#import once (T)
#import hashmap (T, pointer)
#define test<T>

static hashmap<T,pointer> once_table (NULL);

once<T>::once<T> () {
  // cout << "Make identifier " << x << "\n";
  T x;
  rep= (once_rep<T>*) once_table[x];
  if (rep==NULL) {
    rep= new once_rep<T> (x);
    once_table (x)= (pointer) rep;    
  }
  else rep->ref_count++;
  // cout << rep->ref_count << ": " << (*rep->ref) << "\n";
  // cout << "--> " << once_table << "\n";
}

once<T>::once<T> (T x) {
  // cout << "Make identifier " << x << "\n";
  rep= (once_rep<T>*) once_table[x];
  if (rep==NULL) {
    rep= new once_rep<T> (x);
    once_table (x)= (pointer) rep;    
  }
  else rep->ref_count++;
  // cout << rep->ref_count << ": " << (*rep->ref) << "\n";
  // cout << "--> " << once_table << "\n";
}

once<T>::~once<T> () {
  if ((--rep->ref_count)==0) {
    once_table->reset (*rep->ref);
    delete rep;
  }
}

once<T>&
once<T>::operator = (once<T> x) {
  x.rep->ref_count++;
  if ((--rep->ref_count)==0) {
    once_table->reset (*rep->ref);
    delete rep;
  }
  rep=x.rep;
  return *this;
}

#ifdef test<string>
once<T>::once<T> (char* s) {
  string x (s);
  // cout << "Make identifier " << x << "\n";
  rep= (once_rep<T>*) once_table[x];
  if (rep==NULL) {
    rep= new once_rep<T> (x);
    once_table (x)= (pointer) rep;    
  }
  else rep->ref_count++;
  // cout << rep->ref_count << ": " << (*rep->ref) << "\n";
  // cout << "--> " << once_table << "\n";
}
#endif

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

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