lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
weak_resource_ptr.h
00001 /*****************************************************/
00002 /* lean Smart                   (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_SMART_WEAK_RESOURCE_PTR
00006 #define LEAN_SMART_WEAK_RESOURCE_PTR
00007 
00008 #include "../cpp0x.h"
00009 #include "ref_counter.h"
00010 #include "resource_ptr.h"
00011 
00012 namespace lean
00013 {
00014 namespace smart
00015 {
00016 
00018 template <class Resource>
00019 class weak_resource_ptr
00020 {
00021 private:
00022     Resource *m_resource;
00023 
00024     typedef typename Resource::ref_counter_type ref_counter_type;
00025     ref_counter_type m_refCounter;
00026 
00027 public:
00029     typedef Resource resource_type;
00031     typedef Resource* value_type;
00032 
00034     weak_resource_ptr(resource_type *resource = nullptr)
00035         : m_resource(resource),
00036         m_refCounter( (resource) ? resource->ref_counter() : ref_counter_type::null() ) { };
00038     template <class Resource2>
00039     weak_resource_ptr(Resource2 *resource)
00040         : m_resource(resource),
00041         m_refCounter( (m_resource) ? m_resource->ref_counter() : ref_counter_type::null() ) { };
00042     
00044     weak_resource_ptr(const weak_resource_ptr &right)
00045         : m_resource(right.m_resource),
00046         m_refCounter(right.m_refCounter) { };
00048     template <class Resource2>
00049     weak_resource_ptr(const weak_resource_ptr<Resource2> &right)
00050         : m_resource(right.m_resource),
00051         m_refCounter(right.m_refCounter) { };
00052 
00053 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00054 
00055     template <class Resource2>
00056     weak_resource_ptr(weak_resource_ptr<Resource2> &&right)
00057         : m_resource(right.m_resource),
00058         m_refCounter(::std::move(right.m_refCounter))
00059     {
00060         right.m_resource = nullptr;
00061     }
00062 #endif
00063 
00065     weak_resource_ptr& operator =(resource_type *resource)
00066     {
00067         if (m_resource != resource)
00068         {
00069             m_resource = resource;
00070             m_refCounter = (resource) ? resource->ref_counter() : ref_counter_type::null();
00071         }
00072 
00073         return *this;
00074     }
00075     
00077     weak_resource_ptr& operator =(const weak_resource_ptr &right)
00078     {
00079         if (m_resource != right.m_resource)
00080         {
00081             m_resource = right.m_resource;
00082             m_refCounter = right.m_refCounter;
00083         }
00084 
00085         return *this;
00086     }
00088     template <class Resource2>
00089     weak_resource_ptr& operator =(const weak_resource_ptr<Resource2> &right)
00090     {
00091         if (m_resource != right.m_resource)
00092         {
00093             m_resource = right.m_resource;
00094             m_refCounter = right.m_refCounter;
00095         }
00096 
00097         return *this;
00098     }
00099 
00100 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00101 
00102     template <class Resource2>
00103     weak_resource_ptr& operator =(weak_resource_ptr<Resource2> &&right)
00104     {
00105         if (m_resource != right.m_resource)
00106         {
00107             m_resource = right.m_resource;
00108             right.m_resource = nullptr;
00109 
00110             m_refCounter = ::std::move(right.m_refCounter);
00111         }
00112 
00113         return *this;
00114     }
00115 #endif
00116 
00118     LEAN_INLINE bool check() const
00119     {
00120         return (m_resource && m_refCounter.valid());
00121     }
00123     LEAN_INLINE resource_type* get(void) const
00124     {
00125         return (check()) ? m_resource : nullptr;
00126     }
00128     LEAN_INLINE resource_ptr<resource_type> lock() const
00129     {
00130         return resource_ptr<resource_type>(m_resource, m_refCounter);
00131     }
00133     LEAN_INLINE resource_type* get_unchecked(void) const { return m_resource; };
00134 
00136     LEAN_INLINE resource_type& operator *() const { return *get_unchecked(); };
00138     LEAN_INLINE resource_type* operator ->() const { return get_unchecked(); };
00139 
00141     LEAN_INLINE operator resource_type*() const { return get_unchecked(); };
00142     // WARNING: Meaning unclear, should enforce explicit method calls
00143     // However, this would require overloads for pointer comparison, ordering etc.
00144 
00146     LEAN_INLINE operator resource_ptr<resource_type>() const { return lock(); };
00147 };
00148 
00149 } // namespace
00150 
00151 using smart::weak_resource_ptr;
00152 
00153 } // namespace
00154 
00155 #endif