Ptr.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. //
  2. // Copyright (c) 2008-2013 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "RefCounted.h"
  24. #include <cassert>
  25. namespace Urho3D
  26. {
  27. /// Shared pointer template class with intrusive reference counting.
  28. template <class T> class SharedPtr
  29. {
  30. public:
  31. /// Construct a null shared pointer.
  32. SharedPtr() :
  33. ptr_(0)
  34. {
  35. }
  36. /// Copy-construct from another shared pointer.
  37. SharedPtr(const SharedPtr<T>& rhs) :
  38. ptr_(rhs.ptr_)
  39. {
  40. AddRef();
  41. }
  42. /// Construct from a raw pointer.
  43. explicit SharedPtr(T* ptr) :
  44. ptr_(ptr)
  45. {
  46. AddRef();
  47. }
  48. /// Destruct. Release the object reference.
  49. ~SharedPtr()
  50. {
  51. ReleaseRef();
  52. }
  53. /// Assign from another shared pointer.
  54. SharedPtr<T>& operator = (const SharedPtr<T>& rhs)
  55. {
  56. if (ptr_ == rhs.ptr_)
  57. return *this;
  58. ReleaseRef();
  59. ptr_ = rhs.ptr_;
  60. AddRef();
  61. return *this;
  62. }
  63. /// Assign from a raw pointer.
  64. SharedPtr<T>& operator = (T* ptr)
  65. {
  66. if (ptr_ == ptr)
  67. return *this;
  68. ReleaseRef();
  69. ptr_ = ptr;
  70. AddRef();
  71. return *this;
  72. }
  73. /// Point to the object.
  74. T* operator -> () const { assert(ptr_); return ptr_; }
  75. /// Dereference the object.
  76. T& operator * () const { assert(ptr_); return *ptr_; }
  77. /// Subscript the object if applicable.
  78. T& operator [] (const int index) { assert(ptr_); return ptr_[index]; }
  79. /// Test for less than with another shared pointer.
  80. bool operator < (const SharedPtr<T>& rhs) const { return ptr_ < rhs.ptr_; }
  81. /// Test for equality with another shared pointer.
  82. bool operator == (const SharedPtr<T>& rhs) const { return ptr_ == rhs.ptr_; }
  83. /// Test for inequality with another shared pointer.
  84. bool operator != (const SharedPtr<T>& rhs) const { return ptr_ != rhs.ptr_; }
  85. /// Return true if the pointer is not null.
  86. operator bool () const { return ptr_ != 0; }
  87. /// Convert to a raw pointer.
  88. operator T* () const { return ptr_; }
  89. /// Reset to null and release the object reference.
  90. void Reset() { ReleaseRef(); }
  91. /// Perform a static cast from a shared pointer of another type.
  92. template <class U> void StaticCast(const SharedPtr<U>& rhs)
  93. {
  94. ReleaseRef();
  95. ptr_ = static_cast<T*>(rhs.Get());
  96. AddRef();
  97. }
  98. /// Perform a dynamic cast from a shared pointer of another type.
  99. template <class U> void DynamicCast(const SharedPtr<U>& rhs)
  100. {
  101. ReleaseRef();
  102. ptr_ = dynamic_cast<T*>(rhs.Get());
  103. AddRef();
  104. }
  105. /// Check if the pointer is null.
  106. bool Null() const { return ptr_ == 0; }
  107. /// Check if the pointer is not null.
  108. bool NotNull() const { return ptr_ != 0; }
  109. /// Return the raw pointer.
  110. T* Get() const { return ptr_; }
  111. /// Return the object's reference count, or 0 if the pointer is null.
  112. int Refs() const { return ptr_ ? ptr_->Refs() : 0; }
  113. /// Return the object's weak reference count, or 0 if the pointer is null.
  114. int WeakRefs() const { return ptr_ ? ptr_->WeakRefs() : 0; }
  115. /// Return pointer to the RefCount structure.
  116. RefCount* RefCountPtr() const { return ptr_ ? ptr_->RefCountPtr() : 0; }
  117. /// Return hash value for HashSet & HashMap.
  118. unsigned ToHash() const { return ((unsigned)ptr_) / sizeof(T); }
  119. private:
  120. /// Prevent direct assignment from a shared pointer of another type.
  121. template <class U> SharedPtr<T>& operator = (const SharedPtr<U>& rhs);
  122. /// Add a reference to the object pointed to.
  123. void AddRef()
  124. {
  125. if (ptr_)
  126. ptr_->AddRef();
  127. }
  128. /// Release the object reference and delete it if necessary.
  129. void ReleaseRef()
  130. {
  131. if (ptr_)
  132. {
  133. ptr_->ReleaseRef();
  134. ptr_ = 0;
  135. }
  136. }
  137. /// Pointer to the object.
  138. T* ptr_;
  139. };
  140. /// Perform a static cast from one shared pointer type to another.
  141. template <class T, class U> SharedPtr<T> StaticCast(const SharedPtr<U>& ptr)
  142. {
  143. SharedPtr<T> ret;
  144. ret.StaticCast(ptr);
  145. return ret;
  146. }
  147. /// Perform a dynamic cast from one weak pointer type to another.
  148. template <class T, class U> SharedPtr<T> DynamicCast(const SharedPtr<U>& ptr)
  149. {
  150. SharedPtr<T> ret;
  151. ret.DynamicCast(ptr);
  152. return ret;
  153. }
  154. /// Weak pointer template class with intrusive reference counting. Does not keep the object pointed to alive.
  155. template <class T> class WeakPtr
  156. {
  157. public:
  158. /// Construct a null weak pointer.
  159. WeakPtr() :
  160. ptr_(0),
  161. refCount_(0)
  162. {
  163. }
  164. /// Copy-construct from another weak pointer.
  165. WeakPtr(const WeakPtr<T>& rhs) :
  166. ptr_(rhs.ptr_),
  167. refCount_(rhs.refCount_)
  168. {
  169. AddRef();
  170. }
  171. /// Construct from a shared pointer.
  172. WeakPtr(const SharedPtr<T>& rhs) :
  173. ptr_(rhs.Get()),
  174. refCount_(rhs.RefCountPtr())
  175. {
  176. AddRef();
  177. }
  178. /// Construct from a raw pointer.
  179. explicit WeakPtr(T* ptr) :
  180. ptr_(ptr),
  181. refCount_(ptr ? ptr->RefCountPtr() : 0)
  182. {
  183. AddRef();
  184. }
  185. /// Destruct. Release the weak reference to the object.
  186. ~WeakPtr()
  187. {
  188. ReleaseRef();
  189. }
  190. /// Assign from a shared pointer.
  191. WeakPtr<T>& operator = (const SharedPtr<T>& rhs)
  192. {
  193. if (ptr_ == rhs.Get() && refCount_ == rhs.RefCountPtr())
  194. return *this;
  195. ReleaseRef();
  196. ptr_ = rhs.Get();
  197. refCount_ = rhs.RefCountPtr();
  198. AddRef();
  199. return *this;
  200. }
  201. /// Assign from a weak pointer.
  202. WeakPtr<T>& operator = (const WeakPtr<T>& rhs)
  203. {
  204. if (ptr_ == rhs.ptr_ && refCount_ == rhs.refCount_)
  205. return *this;
  206. ReleaseRef();
  207. ptr_ = rhs.ptr_;
  208. refCount_ = rhs.refCount_;
  209. AddRef();
  210. return *this;
  211. }
  212. /// Assign from a raw pointer.
  213. WeakPtr<T>& operator = (T* ptr)
  214. {
  215. RefCount* refCount = ptr ? ptr->RefCountPtr() : 0;
  216. if (ptr_ == ptr && refCount_ == refCount)
  217. return *this;
  218. ReleaseRef();
  219. ptr_ = ptr;
  220. refCount_ = refCount;
  221. AddRef();
  222. return *this;
  223. }
  224. /// Convert to a shared pointer. If expired, return a null shared pointer.
  225. SharedPtr<T> Lock() const
  226. {
  227. if (Expired())
  228. return SharedPtr<T>();
  229. else
  230. return SharedPtr<T>(ptr_);
  231. }
  232. /// Return raw pointer. If expired, return null.
  233. T* Get() const
  234. {
  235. if (Expired())
  236. return 0;
  237. else
  238. return ptr_;
  239. }
  240. /// Point to the object.
  241. T* operator -> () const
  242. {
  243. T* rawPtr = Get();
  244. assert(rawPtr);
  245. return rawPtr;
  246. }
  247. /// Dereference the object.
  248. T& operator * () const
  249. {
  250. T* rawPtr = Get();
  251. assert(rawPtr);
  252. return *rawPtr;
  253. }
  254. /// Subscript the object if applicable.
  255. T& operator [] (const int index)
  256. {
  257. T* rawPtr = Get();
  258. assert(rawPtr);
  259. return (*rawPtr)[index];
  260. }
  261. /// Test for equality with another weak pointer.
  262. bool operator == (const WeakPtr<T>& rhs) const { return ptr_ == rhs.ptr_ && refCount_ == rhs.refCount_; }
  263. /// Test for inequality with another weak pointer.
  264. bool operator != (const WeakPtr<T>& rhs) const { return ptr_ != rhs.ptr_ || refCount_ != rhs.refCount_; }
  265. /// Test for less than with another weak pointer.
  266. bool operator < (const SharedPtr<T>& rhs) const { return ptr_ < rhs.ptr_; }
  267. /// Return true if points to an object which is not expired.
  268. operator bool () const { return !Expired(); }
  269. /// Convert to a raw pointer, null if the object is expired.
  270. operator T* () const { return Get(); }
  271. /// Reset to null and release the weak reference.
  272. void Reset() { ReleaseRef(); }
  273. /// Perform a static cast from a weak pointer of another type.
  274. template <class U> void StaticCast(const WeakPtr<U>& rhs)
  275. {
  276. ReleaseRef();
  277. ptr_ = static_cast<T*>(rhs.Get());
  278. refCount_ = rhs.refCount_;
  279. AddRef();
  280. }
  281. /// Perform a dynamic cast from a weak pointer of another type.
  282. template <class U> void DynamicCast(const WeakPtr<U>& rhs)
  283. {
  284. ReleaseRef();
  285. ptr_ = dynamic_cast<T*>(rhs.Get());
  286. if (ptr_)
  287. {
  288. refCount_ = rhs.refCount_;
  289. AddRef();
  290. }
  291. else
  292. refCount_ = 0;
  293. }
  294. /// Check if the pointer is null.
  295. bool Null() const { return refCount_ == 0; }
  296. /// Check if the pointer is not null.
  297. bool NotNull() const { return refCount_ != 0; }
  298. /// Return the object's reference count, or 0 if null pointer or if object has expired.
  299. int Refs() const { return (refCount_ && refCount_->refs_ >= 0) ? refCount_->refs_ : 0; }
  300. /// Return the object's weak reference count.
  301. int WeakRefs() const
  302. {
  303. if (!Expired())
  304. return ptr_->WeakRefs();
  305. else
  306. return refCount_ ? refCount_->weakRefs_ : 0;
  307. }
  308. /// Return whether the object has expired. If null pointer, always return true.
  309. bool Expired() const { return refCount_ ? refCount_->refs_ < 0 : true; }
  310. /// Return pointer to the RefCount structure.
  311. RefCount* RefCountPtr() const { return refCount_; }
  312. /// Return hash value for HashSet & HashMap.
  313. unsigned ToHash() const { return ((unsigned)ptr_) / sizeof(T); }
  314. private:
  315. /// Prevent direct assignment from a weak pointer of different type.
  316. template <class U> WeakPtr<T>& operator = (const WeakPtr<U>& rhs);
  317. /// Add a weak reference to the object pointed to.
  318. void AddRef()
  319. {
  320. if (refCount_)
  321. {
  322. assert(refCount_->weakRefs_ >= 0);
  323. ++(refCount_->weakRefs_);
  324. }
  325. }
  326. /// Release the weak reference. Delete the Refcount structure if necessary.
  327. void ReleaseRef()
  328. {
  329. if (refCount_)
  330. {
  331. assert(refCount_->weakRefs_ > 0);
  332. --(refCount_->weakRefs_);
  333. if (Expired() && !refCount_->weakRefs_)
  334. delete refCount_;
  335. }
  336. ptr_ = 0;
  337. refCount_ = 0;
  338. }
  339. /// Pointer to the object.
  340. T* ptr_;
  341. /// Pointer to the RefCount structure.
  342. RefCount* refCount_;
  343. };
  344. /// Perform a static cast from one weak pointer type to another.
  345. template <class T, class U> WeakPtr<T> StaticCast(const WeakPtr<U>& ptr)
  346. {
  347. WeakPtr<T> ret;
  348. ret.StaticCast(ptr);
  349. return ret;
  350. }
  351. /// Perform a dynamic cast from one weak pointer type to another.
  352. template <class T, class U> WeakPtr<T> DynamicCast(const WeakPtr<U>& ptr)
  353. {
  354. WeakPtr<T> ret;
  355. ret.DynamicCast(ptr);
  356. return ret;
  357. }
  358. }