/*
 * Copyright (C) 2003 Momchil Velikov
 *
 * See file COPYING for license.
 */


#ifndef nonstd__smart_ptr_h
#define nonstd__smart_ptr_h 1

#include 

namespace nonstd
{
  /* Storage policies  */
  template
  class default_storage_policy
  {
  public:
    typedef T *stored_type;
    typedef T *pointer_type;
    typedef T &reference_type;

    default_storage_policy ()
      : ptr_ (0)
    {}

    default_storage_policy (const stored_type &p)
      : ptr_ (p)
    {}

    default_storage_policy (const default_storage_policy &)
    {}

    template
    default_storage_policy (const default_storage_policy &)
    {}

    pointer_type
    get_ptr () const
    {
      return ptr_;
    }

    reference_type
    get_ref () const
    {
      return *ptr_;
    }

    stored_type &
    get_impl_ref ()
    {
      return ptr_;
    }

    const stored_type &
    get_impl_ref () const
    {
      return ptr_;
    }

    void
    destroy ()
    {
      delete ptr_;
    }

    void
    swap (default_storage_policy &sp)
    {
      std::swap (ptr_, sp.ptr_);
    }

  private:
    stored_type ptr_;
  };


  /* Ownership policies.  */

  /* Non-intrusive reference count.  */
  template
  class ref_count
  {
  public:
    ref_count () : count_ (new unsigned int (1)) {}

    template friend class ref_count;

    template
    ref_count (const ref_count &rc)
      : count_ (rc.count_)
    {}

    Ptr
    duplicate (const Ptr &ptr)
    {
      ++*count_;
      return ptr;
    }

    bool
    release (const Ptr &)
    {
      if (--*count_)
        return false;

      delete count_;
      return true;
    }

    void
    swap (ref_count &rc)
    {
      std::swap (count_, rc.count_);
    }

  private:
    unsigned int *count_;
  };


  /* Intrusive reference count.  */
  template
  class intrusive_ref_count
  {
  public:
    intrusive_ref_count () {}

    template
    intrusive_ref_count (const intrusive_ref_count &)
    {}

    static Ptr
    duplicate (const Ptr &ptr)
    {
      return ptr->duplicate ();
    }

    static bool
    release (const Ptr &ptr)
    {
      if (ptr)
        return ptr->release ();
      else
        return false;
    }

    static void
    swap (intrusive_ref_count &)
    {}
  };


  template class StoragePolicy = default_storage_policy,
           template  class OwnershipPolicy = ref_count>
  class smart_ptr
    : public StoragePolicy,
      public OwnershipPolicy::pointer_type>
  {
  protected:
    typedef StoragePolicy SP;
    typedef OwnershipPolicy OP;

  public:
    smart_ptr () {}

    smart_ptr (const typename SP::stored_type &p)
      : SP (p)
    {}

    smart_ptr (const smart_ptr &sp)
      : SP (sp), OP (sp)
    {
      SP::get_impl_ref () = OP::duplicate (sp.get_impl_ref ());
    }

    template class SP1,
             template  class OP1>
    smart_ptr (const smart_ptr &sp)
      : SP (sp), OP (sp)
    {
      SP::get_impl_ref () = duplicate (sp.get_impl_ref ());
    }

    ~smart_ptr ()
    {
      if (OP::release (SP::get_impl_ref ()))
        SP::destroy ();
    }

    smart_ptr &
    operator= (const smart_ptr &sp)
    {
      smart_ptr tmp (sp);
      tmp.swap (*this);
      return *this;
    }

    template class SP1,
             template  class OP1>
    smart_ptr &
    operator= (const smart_ptr &sp)
    {
      smart_ptr tmp (sp);
      tmp.swap (*this);
      return *this;
    }

    typename SP::pointer_type
    operator-> () const
    {
      return SP::get_ptr ();
    }

    typename SP::reference_type
    operator* () const
    {
      return SP::get_ref ();
    }

  protected:
    void
    swap (smart_ptr &sp)
    {
      SP::swap (sp);
      OP::swap (sp);
    }
  };
}

#endif /* nonstd__smart_ptr_h */

/*
 * Local variables:
 * mode: C++
 * indent-tabs-mode: nil
 * arch-tag: 92d98e78-dd24-45d8-a1a5-d3310b85faf0
 * End:
 */

    Source: geocities.com/siliconvalley/pines/4802

               ( geocities.com/siliconvalley/pines)                   ( geocities.com/siliconvalley)