00001 #ifndef GLW_BOOKKEEPING_H 00002 #define GLW_BOOKKEEPING_H 00003 00004 #include "./common.h" 00005 00006 namespace glw 00007 { 00008 00009 namespace detail 00010 { 00011 00012 struct NoType { }; 00013 template <typename T> struct DefaultDeleter { void operator () (T * t) { delete t; } }; 00014 00015 template <typename T> struct BaseOf { typedef NoType Type; }; 00016 00017 template <typename T, typename B> struct RootOfType { typedef typename RootOfType<B, typename BaseOf<B>::Type>::Type Type; }; 00018 template <typename T> struct RootOfType<T, NoType> { typedef T Type; }; 00019 template <typename T> struct RootOf { typedef typename RootOfType<T, typename BaseOf<T>::Type>::Type Type; }; 00020 00021 template <typename T, typename B> struct DeleterOfType { typedef typename DeleterOfType<B, typename BaseOf<B>::Type>::Type Type; }; 00022 template <typename T> struct DeleterOfType<T, NoType> { typedef DefaultDeleter<T> Type; }; 00023 template <typename T> struct DeleterOf { typedef typename DeleterOfType<T, typename BaseOf<T>::Type>::Type Type; }; 00024 00025 template <typename TObject, typename TDeleter, typename TBaseObject> 00026 class RefCountedObject : public RefCountedObject<TBaseObject, TDeleter, typename BaseOf<TBaseObject>::Type> 00027 { 00028 public: 00029 00030 typedef RefCountedObject<TBaseObject, TDeleter, typename BaseOf<TBaseObject>::Type> BaseType; 00031 typedef RefCountedObject<TObject, TDeleter, TBaseObject> ThisType; 00032 typedef TObject ObjectType; 00033 typedef TDeleter DeleterType; 00034 typedef TBaseObject BaseObjectType; 00035 00036 RefCountedObject(ObjectType * object, const DeleterType & deleter) 00037 : BaseType(object, deleter) 00038 { 00039 ; 00040 } 00041 00042 const ObjectType * object(void) const 00043 { 00044 return static_cast<const ObjectType *>(BaseType::object()); 00045 } 00046 00047 ObjectType * object(void) 00048 { 00049 return static_cast<ObjectType *>(BaseType::object()); 00050 } 00051 }; 00052 00053 template <typename TObject, typename TDeleter> 00054 class RefCountedObject<TObject, TDeleter, NoType> 00055 { 00056 public: 00057 00058 typedef void BaseType; 00059 typedef RefCountedObject<TObject, TDeleter, NoType> ThisType; 00060 typedef TObject ObjectType; 00061 typedef TDeleter DeleterType; 00062 typedef NoType BaseObjectType; 00063 00064 RefCountedObject(ObjectType * object, const DeleterType & deleter) 00065 : m_object (object) 00066 , m_refCount (0) 00067 , m_deleter (deleter) 00068 { 00069 GLW_ASSERT(this->m_object != 0); 00070 } 00071 00072 ~RefCountedObject(void) 00073 { 00074 this->destroyObject(); 00075 } 00076 00077 bool isNull(void) const 00078 { 00079 return (this->m_object == 0); 00080 } 00081 00082 void setNull(bool deleteObject) 00083 { 00084 if (deleteObject) 00085 { 00086 this->destroyObject(); 00087 } 00088 this->m_object = 0; 00089 } 00090 00091 const ObjectType * object(void) const 00092 { 00093 return this->m_object; 00094 } 00095 00096 ObjectType * object(void) 00097 { 00098 return this->m_object; 00099 } 00100 00101 const DeleterType & deleter(void) const 00102 { 00103 return this->m_deleter; 00104 } 00105 00106 DeleterType & deleter(void) 00107 { 00108 return this->m_deleter; 00109 } 00110 00111 void ref(void) 00112 { 00113 this->m_refCount++; 00114 } 00115 00116 void unref(void) 00117 { 00118 GLW_ASSERT(this->m_refCount > 0); 00119 this->m_refCount--; 00120 if (this->m_refCount == 0) 00121 { 00122 delete this; 00123 } 00124 } 00125 00126 int refCount(void) const 00127 { 00128 return this->m_refCount; 00129 } 00130 00131 private: 00132 00133 ObjectType * m_object; 00134 int m_refCount; 00135 DeleterType m_deleter; 00136 00137 RefCountedObject(const ThisType & other); 00138 ThisType & operator = (const ThisType & other); 00139 00140 void destroyObject(void) 00141 { 00142 if (this->m_object == 0) return; 00143 this->m_deleter(this->m_object); 00144 this->m_object = 0; 00145 } 00146 }; 00147 00148 template <typename T> struct RefCountedObjectTraits { typedef RefCountedObject<T, typename DeleterOf<T>::Type, typename BaseOf<T>::Type> Type; }; 00149 00150 template <typename TObject, typename TDeleter, typename TBaseObject> 00151 class ObjectSharedPointer : public ObjectSharedPointer<TBaseObject, TDeleter, typename BaseOf<TBaseObject>::Type> 00152 { 00153 public: 00154 00155 typedef ObjectSharedPointer<TBaseObject, TDeleter, typename BaseOf<TBaseObject>::Type> BaseType; 00156 typedef ObjectSharedPointer<TObject, TDeleter, TBaseObject> ThisType; 00157 typedef TObject ObjectType; 00158 typedef TDeleter DeleterType; 00159 typedef TBaseObject BaseObjectType; 00160 typedef RefCountedObject<ObjectType, DeleterType, BaseObjectType> RefCountedObjectType; 00161 00162 ObjectSharedPointer(void) 00163 : BaseType() 00164 { 00165 ; 00166 } 00167 00168 ObjectSharedPointer(const ThisType & other) 00169 : BaseType(other) 00170 { 00171 ; 00172 } 00173 00174 ObjectSharedPointer(RefCountedObjectType * refObject) 00175 : BaseType(refObject) 00176 { 00177 ; 00178 } 00179 00180 const ObjectType & operator * (void) const 00181 { 00182 return (*(this->object())); 00183 } 00184 00185 ObjectType & operator * (void) 00186 { 00187 return (*(this->object())); 00188 } 00189 00190 const ObjectType * operator -> (void) const 00191 { 00192 return this->object(); 00193 } 00194 00195 ObjectType * operator -> (void) 00196 { 00197 return this->object(); 00198 } 00199 00200 protected: 00201 00202 const ObjectType * object(void) const 00203 { 00204 return static_cast<const ObjectType *>(BaseType::object()); 00205 } 00206 00207 ObjectType * object(void) 00208 { 00209 return static_cast<ObjectType *>(BaseType::object()); 00210 } 00211 00212 RefCountedObjectType * refObject(void) const 00213 { 00214 return static_cast<RefCountedObjectType *>(BaseType::refObject()); 00215 } 00216 }; 00217 00218 template <typename TObject, typename TDeleter> 00219 class ObjectSharedPointer<TObject, TDeleter, NoType> 00220 { 00221 public: 00222 00223 typedef void BaseType; 00224 typedef ObjectSharedPointer<TObject, TDeleter, NoType> ThisType; 00225 typedef TObject ObjectType; 00226 typedef TDeleter DeleterType; 00227 typedef NoType BaseObjectType; 00228 typedef RefCountedObject<ObjectType, DeleterType, NoType> RefCountedObjectType; 00229 00230 ObjectSharedPointer(void) 00231 : m_refObject(0) 00232 { 00233 ; 00234 } 00235 00236 ObjectSharedPointer(const ThisType & other) 00237 : m_refObject(0) 00238 { 00239 this->attach(other.refObject()); 00240 } 00241 00242 ObjectSharedPointer(RefCountedObjectType * refObject) 00243 : m_refObject(0) 00244 { 00245 this->attach(refObject); 00246 } 00247 00248 ~ObjectSharedPointer(void) 00249 { 00250 this->detach(); 00251 } 00252 00253 bool isNull(void) const 00254 { 00255 if (this->m_refObject == 0) return true; 00256 return this->m_refObject->isNull(); 00257 } 00258 00259 void setNull(void) 00260 { 00261 this->detach(); 00262 } 00263 00264 const ObjectType & operator * (void) const 00265 { 00266 return (*(this->object())); 00267 } 00268 00269 ObjectType & operator * (void) 00270 { 00271 return (*(this->object())); 00272 } 00273 00274 const ObjectType * operator -> (void) const 00275 { 00276 return this->object(); 00277 } 00278 00279 ObjectType * operator -> (void) 00280 { 00281 return this->object(); 00282 } 00283 00284 operator bool (void) const 00285 { 00286 return (!this->isNull()); 00287 } 00288 00289 ThisType & operator = (const ThisType & other) 00290 { 00291 this->attach(other.refObject()); 00292 return (*this); 00293 } 00294 00295 protected: 00296 00297 const ObjectType * object(void) const 00298 { 00299 GLW_ASSERT(!this->isNull()); 00300 return this->m_refObject->object(); 00301 } 00302 00303 ObjectType * object(void) 00304 { 00305 GLW_ASSERT(!this->isNull()); 00306 return this->m_refObject->object(); 00307 } 00308 00309 RefCountedObjectType * refObject(void) const 00310 { 00311 return this->m_refObject; 00312 } 00313 00314 private: 00315 00316 RefCountedObjectType * m_refObject; 00317 00318 void attach(RefCountedObjectType * reObject) 00319 { 00320 this->detach(); 00321 this->m_refObject = reObject; 00322 if (this->m_refObject != 0) 00323 { 00324 this->m_refObject->ref(); 00325 } 00326 } 00327 00328 void detach(void) 00329 { 00330 if (this->m_refObject == 0) return; 00331 this->m_refObject->unref(); 00332 this->m_refObject = 0; 00333 } 00334 }; 00335 00336 template <typename T> struct ObjectSharedPointerTraits { typedef ObjectSharedPointer<T, typename DeleterOf<typename RootOf<T>::Type>::Type, typename BaseOf<T>::Type> Type; }; 00337 00338 }; 00339 00340 }; 00341 00342 #endif // GLW_BOOKKEEPING_H