// -*-c++-*-
/***************************************************************************
                          SmartPointer.h  -  description
                             -------------------
    begin                : Tue May 22 2001
    copyright            : (C) 2001 by Sven Reichard
    email                : reichard@math.udel.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
# ifndef SmartPointer_h
# define SmartPointer_h
# include <cassert>
namespace Alice
{
template<class T>
class SmartPointer
{
  typedef T value_type;
  value_type* contents;
  int* counter;
public:
  SmartPointer():
    contents(0), counter(new int(1))
  {
    //assert(int(counter) > 0xffff);
    //checkValidity();
  };
  SmartPointer(value_type* pointer):
    contents(pointer), counter(new int(1))
  {
    //assert(int(counter) > 0xffff);
    //checkValidity();
  };
  SmartPointer(const SmartPointer<T>& ref):
    contents(ref.contents),
    counter(ref.counter)
  {
    //assert(int(counter) > 0xffff);
    (*counter) ++;
    //checkValidity();
  };
  SmartPointer& operator= (const SmartPointer<T>& ref)
  {
    if (this == &ref)
      return *this;
    dereference();
    contents = ref.contents;
    counter = ref.counter;
    assert(int(counter) > 0xffff);
    (*counter) ++;
    //checkValidity();
    return *this;
  };
  ~SmartPointer()
  {
    dereference();
  };
  value_type& operator*() {return *contents;}
  const value_type& operator*() const {return *contents;}
  value_type* operator->() {return contents;}
  const value_type* operator->() const {return contents;}
  operator bool() const {return contents != 0;}
  void checkValidity() const
  {
    assert(int(counter) > 0xffff);
    assert(*counter >= 0);
  }
private:
  void dereference();
  
};

template<class T>
void 
SmartPointer<T>::dereference()
{
  //static int prefetch;
  if (! counter)
    return;
  //std::cout<<"dereferencing ";
  //contents->printOn(std::cout);
  //prefetch = *counter;
  (* counter) --;
  if (*counter )
    return;
  //std::cout<<" deleting ";
  delete contents;
  contents = 0;
  delete counter;
  counter = 0;
};
}; // namespace Alice
# endif // SmartPointer_h
