/*******************************************************************************
+
+  LEDA 3.5
+
+  handle_types.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#ifndef LEDA_HANDLE_H
#define LEDA_HANDLE_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 350060
#include <LEDA/REDEFINE_NAMES.h>
#endif


//------------------------------------------------------------------------------
// handle_base/rep: base classes for handle types string, point, segment,...
//------------------------------------------------------------------------------

class handle_base;

class handle_rep  {

friend class handle_base;

#if defined(__NO_EXPLICIT_DESTRUCTION__)
friend inline void leda_explicit_destruction(handle_base*);
#endif

protected:

 leda_mutex mutex_count;

 int  count;

 handle_rep()  { count = 1; }
 virtual ~handle_rep()  {}

public:

 LEDA_MEMORY(handle_rep)

};



class handle_base {

protected:

handle_rep* PTR;

public:

 handle_base() {}
 handle_base(const handle_base& x) 
 { PTR = x.PTR;  
   PTR->mutex_count.lock();
   PTR->count++; 
   PTR->mutex_count.unlock();
  }

~handle_base() 
 { if (PTR)
   { PTR->mutex_count.lock();
     if (--PTR->count == 0)  delete PTR;
     if (PTR) PTR->mutex_count.unlock(); 
    }
  }

handle_base& operator=(const handle_base& x)
{ x.PTR->mutex_count.lock();
  x.PTR->count++;
  x.PTR->mutex_count.unlock();
  if (PTR)
  { PTR->mutex_count.lock();
    if (--PTR->count == 0)  delete PTR; // left side may be 0
    if (PTR) PTR->mutex_count.unlock();
   }
  PTR = x.PTR;
  return *this;
 }

int    refs()  const { return PTR->count; }


friend unsigned long ID_Number(const handle_base& x)
{ return (unsigned long)x.PTR; }

friend bool identical(const handle_base& x, const handle_base& y)
{ return x.PTR == y.PTR; }


#if defined(__NO_EXPLICIT_DESTRUCTION__)
friend inline void leda_explicit_destruction(handle_base* p)
{ if (p->PTR && --p->PTR->count == 0) delete p->PTR; }
#endif


 LEDA_MEMORY(handle_base)
 
};



#if LEDA_ROOT_INCL_ID == 350060
#undef LEDA_ROOT_INCL_ID
#include <LEDA/UNDEFINE_NAMES.h>
#endif

#endif
 
