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_SCOPED_PTR 00006 #define LEAN_SMART_SCOPED_PTR 00007 00008 #include "../lean.h" 00009 #include "../tags/noncopyable.h" 00010 #include "../meta/dependent_false.h" 00011 #include "../meta/strip.h" 00012 00013 namespace lean 00014 { 00015 namespace smart 00016 { 00017 00019 template <class Type> 00020 LEAN_INLINE void release_ptr(Type *object) 00021 { 00022 if (sizeof(Type) > 0) 00023 delete object; 00024 } 00025 00027 template <class Type> 00028 LEAN_INLINE void release_array_ptr(Type *object) 00029 { 00030 if (sizeof(Type) > 0) 00031 delete[] object; 00032 } 00033 00035 template <class Type> 00036 struct generic_ptr_policy 00037 { 00039 static LEAN_INLINE void release(Type *object) 00040 { 00041 release_ptr(object); 00042 } 00043 }; 00044 template <class Type> 00045 struct generic_ptr_policy<Type[]> 00046 { 00047 static LEAN_INLINE void release(Type *object) 00048 { 00049 release_array_ptr(object); 00050 } 00051 }; 00052 00054 template <class Type> 00055 struct delete_ptr_policy 00056 { 00058 static LEAN_INLINE void release(Type *object) 00059 { 00060 if (sizeof(Type) > 0) 00061 delete object; 00062 } 00063 }; 00064 template <class Type> 00065 struct delete_ptr_policy<Type[]> 00066 { 00067 static LEAN_INLINE void release(Type *object) 00068 { 00069 if (sizeof(Type) > 0) 00070 delete[] object; 00071 } 00072 }; 00073 00075 template <class Type> 00076 struct destroy_ptr_policy 00077 { 00079 static LEAN_INLINE void release(Type *object) 00080 { 00081 if (object) 00082 object->destroy(); 00083 } 00084 }; 00085 template <class Type> 00086 struct destroy_ptr_policy<Type[]>; 00087 00089 template <class Type> 00090 struct release_ptr_policy 00091 { 00093 static LEAN_INLINE void release(Type *object) 00094 { 00095 if (object) 00096 object->release(); 00097 } 00098 }; 00099 template <class Type> 00100 struct release_ptr_policy<Type[]>; 00101 00103 template < class Type, class ReleasePolicy = generic_ptr_policy<Type> > 00104 class scoped_ptr : public noncopyable 00105 { 00106 public: 00108 typedef typename lean::strip_array<Type>::type object_type; 00110 typedef object_type* value_type; 00111 00112 private: 00113 value_type m_object; 00114 00115 public: 00117 explicit scoped_ptr(object_type *object = nullptr) 00118 : m_object( object ) { }; 00120 template <class Type2> 00121 explicit scoped_ptr(Type2 *object) 00122 : m_object( object ) { }; 00123 00124 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00125 00126 template <class Type2> 00127 scoped_ptr(scoped_ptr<Type2> &&right) 00128 : m_object( right.detatch() ) { } 00129 #endif 00130 00132 LEAN_INLINE ~scoped_ptr() 00133 { 00134 ReleasePolicy::release(m_object); 00135 } 00136 00138 LEAN_INLINE object_type* detatch() 00139 { 00140 value_type prevObject = m_object; 00141 m_object = nullptr; 00142 return prevObject; 00143 } 00144 00146 scoped_ptr& operator =(object_type *object) 00147 { 00148 // Self-assignment would be wrong 00149 if(object != m_object) 00150 { 00151 value_type prevObject = m_object; 00152 m_object = object; 00153 ReleasePolicy::release(prevObject); 00154 } 00155 00156 return *this; 00157 } 00158 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00159 00160 template <class Type2> 00161 scoped_ptr& operator =(scoped_ptr<Type2> &&right) 00162 { 00163 // Self-assignment would be wrong 00164 if (addressof(right) != static_cast<void*>(this)) 00165 { 00166 value_type prevObject = m_object; 00167 m_object = right.detatch(); 00168 ReleasePolicy::release(prevObject); 00169 } 00170 00171 return *this; 00172 } 00173 #endif 00174 00176 LEAN_INLINE object_type*const& get() const { return m_object; } 00177 00179 LEAN_INLINE object_type& operator *() const { return *get(); } 00181 LEAN_INLINE object_type* operator ->() const { return get(); } 00182 00184 LEAN_INLINE operator object_type*() const { return get(); } 00185 }; 00186 00187 } // namespace 00188 00189 using smart::scoped_ptr; 00190 00191 } // namespace 00192 00193 #endif