Listing 1: Header file for smart pointers implementation

// Copyright (c) 1996-1997 Vladimir Batov
//
// Permission to use, copy, modify, distribute and sell this
// software and its documentation for any purpose is hereby
// granted without fee, provided that the above copyright notice
// appear in all copies and that both that copyright notice and
// this permission notice appear in supporting documentation.
// I make no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or
// implied warranty.

// Handle<T> requires T class to have T::T() and
// T::T(const T&) constructors.

#ifndef BATOV_HANDLE_H
#define BATOV_HANDLE_H

typedef unsigned int uint;

class HandleError
{
   public:

      ~HandleError () {}
       HandleError () : _error(_allocate()) {}
       HandleError (uint err) : _error(err) {}
   operator   uint () const { return _error; }
   bool operator== (const HandleError& e) const
      { return _error == e._error; }

   static HandleError no_error;
   static HandleError  unknown;

   private:

   uint _error;
   uint _allocate();
};

template<class T/*, class Allocator = MemoryAllocator
                    When supported*/>
class Handle
{
   public:

   typedef HandleError Error;

   private:

   class Counted
   {
      public:

     ~Counted () {}
      Counted ();
      Counted (const T&);

      void dismiss () { if (!--_num_references) delete this; }
      void     use () { ++_num_references; }

      operator         T& ()       { return  _instance; }
      operator   const T& () const { return  _instance; }
      operator         T* ()       { return &_instance; }
      operator   const T* () const { return &_instance; }
      T*       operator-> ()       { return &_instance; }
      const T* operator-> () const { return &_instance; }

//    Possible memory optimization. See [6]. 
//    void*   operator new (size_t)
//       { return   _allocator.allocate(); }
//    void operator delete (void* storage)
//       { _allocator.deallocate(storage); }

      bool  is_shared () const
         { return 1 < _num_references ? true : false; }
      bool   is_error () const { return _error ? true : false; }
      Error get_error () const { return _error; }                
      void  set_error (Error);                                   

      private:

      T               _instance;
      uint _num_references : 16; // Reference counter.
                                 // (<=65535 looks enough)
      uint          _error : 16; // Error conditions flag.
                                 // (<=65535)

//    Possible memory optimization. See [6]. 
//    static MemoryAllocator _allocator;
   };

   public:

  ~Handle ();
   Handle ();
   Handle (const T&);
   Handle (const T*);
   Handle (const Handle<T>&);

   operator T& () { return _counted->operator T&(); }
   operator T* () { return _counted->operator T*(); }
   operator const T& () const { return _counted->operator T&(); }
   operator const T* () const { return _counted->operator T*(); }
   const T* operator-> () const
      { return _counted->operator ->(); }
   T* operator-> () { return _counted->operator ->(); }
   Handle<T>& operator = (const T&);
   Handle<T>& operator = (const T*);
   Handle<T>& operator = (const Handle<T>&);

   static Handle<T> error (Error =Error::unknown);
   void             set_error (Error =Error::unknown);
   Error     get_error () const { return _counted->get_error(); }
   bool      is_error () const { return _counted-> is_error(); }
   bool      is_shared () const { return _counted->is_shared(); }
   Handle<T> duplicate () const; // Convenience method to create 
                                 // a copy of a "T-Handle<T>" pair.
   private:

   Counted* _counted;

   // User has NO ACCESS TO THE ADDRESS OF A HANDLE instance
   // as such access bypasses reference counter mechanism.
   // User is forced to pass it by value (Handle) that is 
   // supervised by the mechanism.

   Handle<T>* operator& (); // Not defined to prevent usage.
};

template<class T>
inline
Handle<T>::Counted::Counted() : _num_references(0), 
                                _error(Error::no_error), 
                                _instance()
{
   // Preferred form of T instance creation.
}

template<class T>
inline
Handle<T>::Counted::Counted(const T& from)
                              : _num_references(0),
                                _error(Error::no_error),
                                _instance(from)
{
   // Should be avoided as an internal copy of 'from'
   // is created.
}

template<class T>
inline
void
Handle<T>::Counted::set_error(Error err)
{
   _error = err < Error::unknown
          ? err
          : Error::unknown;
}

template<class T>
inline
Handle<T> 
Handle<T>::error(Error num) 
{ 
   Handle<T> h; 
   h.set_error(num); 
   return h; 
}

template<class T>
inline
void         
Handle<T>::set_error(Error err) 
{ 
   _counted->set_error(err); 

}

template<class T>
inline
Handle<T>::~Handle()
{
   _counted->dismiss();
}

template<class T>
inline
Handle<T>::Handle() : _counted(new Counted())
{
   _counted->use();
}

template<class T>
inline
Handle<T>::Handle(const T& copy) : _counted(new Counted(copy))
{
   _counted->use();
}

template<class T>
inline
Handle<T>::Handle(const T* copy) 
   : _counted(copy ? new Counted(*copy) : new Counted())
{
   _counted->use();
}

template<class T>
inline
Handle<T>::Handle(const Handle<T>& ref) : _counted(ref._counted)
{
   _counted->use();
}

template<class T>
inline
Handle<T>&
Handle<T>::operator=(const T& src)  //8.
{
   if (*this != &src)
   {
      _counted->dismiss();
      _counted = new Counted(src);
      _counted->use();
   }
   return *this;
}

template<class T>
inline
Handle<T>&
Handle<T>::operator=(const T* src) //8.
{
   if (*this != src)
   {
      _counted->dismiss();
      _counted = src ? new Counted(*src) : new Counted();
      _counted->use();
   }
   return *this;
}

template<class T>
inline
Handle<T>&
Handle<T>::operator=(const Handle<T>& src)
{
   if (this->_counted != src._counted)
   {
      _counted->dismiss();
      _counted = src._counted;
      _counted->use();
   }
   return *this;
}

template<class T>
inline
Handle<T>    
Handle<T>::duplicate() const 
{ 
   return Handle<T>(operator->()); 
}

#endif // BATOV_HANDLE_H

// End of File