/*
  libuta - a C++ widget library based on SDL (Simple Direct Layer)
  Copyright (C) 1999-2002  Karsten Laux

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, SA.
*/
// written by Karsten Laux, May 1999  

#ifndef _SHARED_H_
#define _SHARED_H_


namespace uta {

///shared data class
template <class T> class Shared
{
  ///
  Shared() :
    refcount_(0)
    {
      data_ = new T();
      refcount_ ++;
    }

  /// 
  Shared<T>* copy() 
    { 
      refcount_++;
      return this; 
    };

  /// remove instance
  void remove()
    {
      refcount_--;
      if(refcount_ == 0)
	delete this;
    }

  /// readonly access
  const T& operator() (void)
    {
      return *data_;
    }

  /// 
  Shared<T>& operator=(const Shared<T>& a)
    {      
      if (this != &a)
	{
	  if(refcount_ > 1)
	    {
	      //more than one instance is referring to this,
	      //so we need to split
	      Shared<T>* b = new Shared<T>();
	      //copy...
	      *(b->data_) = *(a.data_);
	      //we lose one referrer
	      refcount_--;
	      return *b;
	    }
	  else
	    {
	      //only one referrer, so we may savely do this:
	      //simply copying
	      *(data_) = *(a.data_);
	    }
	}
      else
	{
	  return *this;
	}
    }
  
 protected:
  ///
  ~Shared() { delete data_; }
  ///
  T* data_;
  ///
  int refcount_;

};
  

}



#endif
