lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
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