/* * 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: */