#ifndef _DARK_PTR_H_
#define _DARK_PTR_H_
 
//modified auto_ptr that makes the pointer mutable, so as to be
//able to have a copy constructor with a const RHS argument,
//so that it can be used in containers (who really want to see
//standard copy constructors, so... Give 'em what they want!)
 
template< class T > class dark_ptr;
 
template< class T > struct dark_ptr_ref
{
   dark_ptr< T > const & ref;
   dark_ptr_ref( dark_ptr< T > const & other ): ref( other ){}
};
 
template< class T > class dark_ptr
{
   mutable T *ptr;
public:
   typedef T element_type;
   explicit dark_ptr( T *Ptr =0 ) //no throw
   : ptr( Ptr )
   {}
   dark_ptr( dark_ptr< T > const & other ) //no throw
   : ptr( other.dark_release() )
   {}
   dark_ptr( dark_ptr_ref< T > const other ) //no throw
   : ptr( other.ref.dark_release() )
   {}
   template< class U >
   operator dark_ptr< U >() //no throw
   {
      return dark_ptr< U >( *this );
   }
   template< class U >
   operator dark_ptr_ref< U >() //no throw
   {
      return dark_ptr_ref< U >( *this );
   }
   template< class U >
   dark_ptr< T >& operator=( dark_ptr< U > const & other ) //no throw
   {
      reset( other.dark_release() );
      return *this;
   }
   template< class U >
   dark_ptr( dark_ptr< U > const & other ) //no throw
   : ptr( other.dark_release() )
   {}
   dark_ptr< T >& operator=( dark_ptr< T > const & other ) //no throw
   {
      reset( other.dark_release() );
      return *this;
   }
   dark_ptr< T >& operator=( dark_ptr_ref< T > const & other ) //no throw
   {
      reset( other.ref.dark_release() );
      return *this;
   }
   ~dark_ptr()
   {
      //testing for zero for performance reasons (the most
      //popular compiler takes 11 instructions to delete 0)
      if( ptr ) delete ptr;
   }
   T * dark_release() const //no throw
   {
      T *ptemp = ptr;
      ptr = 0;
      return ptemp;
   }
   void reset( T * Ptr =0 )
   {
      assert( ! ptr || ptr != Ptr );
      //testing for zero for performance reasons (the most
      //popular compiler takes 11 instructions to delete 0)
      if( ptr && ptr != Ptr ) delete ptr;
      ptr = Ptr;
   }
   T * get() const //no throw
   {
      return ptr;
   }
   T & operator*() const //no throw
   {
      return *ptr;
   }
   T * operator->() const //no throw
   {
      return &**this;
   }
   void swap( dark_ptr< T > & other ) //no throw
   {
      T * ptmp = other.ptr;
      other.ptr = ptr;
      ptr = ptmp;
   }
   operator bool () const //no throw
   {
      return ptr != 0;
   }
   bool operator! () const //no throw
   {
      return ptr == 0;
   }
private:
   template < const int I > bool operator==( const int I ) const; //dont exist
   template < const int I > bool operator!=( const int I ) const; //dont exist
public:
   template <> bool operator==< 0 >( const int I ) const //no throw
   {
      return ptr == 0;
   }
   template <> bool operator!=< 0 >( const int I ) const //no throw
   {
      return ptr != 0;
   }
};
 
template< class T > inline void swap( dark_ptr< T > & a, dark_ptr< T > & b ) //no throw
{
    a.swap(b);
}
template< class T > inline T * get_pointer( dark_ptr< T > const & p ) //no throw
{
    return p.get();
}
 
#endif
 
code/root/inc/dark_ptr.h.txt · Last modified: 2006/10/09 23:39 by chuck_starchaser