AutoPtr.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. //
  2. // AutoPtr.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/AutoPtr.h#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Core
  8. // Module: AutoPtr
  9. //
  10. // Definition of the AutoPtr template class.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_AutoPtr_INCLUDED
  18. #define Foundation_AutoPtr_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/Exception.h"
  21. #include <algorithm>
  22. namespace Poco {
  23. template <class C>
  24. class AutoPtr
  25. /// AutoPtr is a "smart" pointer for classes implementing
  26. /// reference counting based garbage collection.
  27. /// To be usable with the AutoPtr template, a class must
  28. /// implement the following behaviour:
  29. /// A class must maintain a reference count.
  30. /// The constructors of the object initialize the reference
  31. /// count to one.
  32. /// The class must implement a public duplicate() method:
  33. /// void duplicate();
  34. /// that increments the reference count by one.
  35. /// The class must implement a public release() method:
  36. /// void release()
  37. /// that decrements the reference count by one, and,
  38. /// if the reference count reaches zero, deletes the
  39. /// object.
  40. ///
  41. /// AutoPtr works in the following way:
  42. /// If an AutoPtr is assigned an ordinary pointer to
  43. /// an object (via the constructor or the assignment operator),
  44. /// it takes ownership of the object and the object's reference
  45. /// count remains unchanged.
  46. /// If the AutoPtr is assigned another AutoPtr, the
  47. /// object's reference count is incremented by one by
  48. /// calling duplicate() on its object.
  49. /// The destructor of AutoPtr calls release() on its
  50. /// object.
  51. /// AutoPtr supports dereferencing with both the ->
  52. /// and the * operator. An attempt to dereference a null
  53. /// AutoPtr results in a NullPointerException being thrown.
  54. /// AutoPtr also implements all relational operators.
  55. /// Note that AutoPtr allows casting of its encapsulated data types.
  56. {
  57. public:
  58. AutoPtr(): _ptr(0)
  59. {
  60. }
  61. AutoPtr(C* ptr): _ptr(ptr)
  62. {
  63. }
  64. AutoPtr(C* ptr, bool shared): _ptr(ptr)
  65. {
  66. if (shared && _ptr) _ptr->duplicate();
  67. }
  68. AutoPtr(const AutoPtr& ptr): _ptr(ptr._ptr)
  69. {
  70. if (_ptr) _ptr->duplicate();
  71. }
  72. template <class Other>
  73. AutoPtr(const AutoPtr<Other>& ptr): _ptr(const_cast<Other*>(ptr.get()))
  74. {
  75. if (_ptr) _ptr->duplicate();
  76. }
  77. ~AutoPtr()
  78. {
  79. if (_ptr) _ptr->release();
  80. }
  81. AutoPtr& assign(C* ptr)
  82. {
  83. if (_ptr != ptr)
  84. {
  85. if (_ptr) _ptr->release();
  86. _ptr = ptr;
  87. }
  88. return *this;
  89. }
  90. AutoPtr& assign(C* ptr, bool shared)
  91. {
  92. if (_ptr != ptr)
  93. {
  94. if (_ptr) _ptr->release();
  95. _ptr = ptr;
  96. if (shared && _ptr) _ptr->duplicate();
  97. }
  98. return *this;
  99. }
  100. AutoPtr& assign(const AutoPtr& ptr)
  101. {
  102. if (&ptr != this)
  103. {
  104. if (_ptr) _ptr->release();
  105. _ptr = ptr._ptr;
  106. if (_ptr) _ptr->duplicate();
  107. }
  108. return *this;
  109. }
  110. template <class Other>
  111. AutoPtr& assign(const AutoPtr<Other>& ptr)
  112. {
  113. if (ptr.get() != _ptr)
  114. {
  115. if (_ptr) _ptr->release();
  116. _ptr = const_cast<Other*>(ptr.get());
  117. if (_ptr) _ptr->duplicate();
  118. }
  119. return *this;
  120. }
  121. AutoPtr& operator = (C* ptr)
  122. {
  123. return assign(ptr);
  124. }
  125. AutoPtr& operator = (const AutoPtr& ptr)
  126. {
  127. return assign(ptr);
  128. }
  129. template <class Other>
  130. AutoPtr& operator = (const AutoPtr<Other>& ptr)
  131. {
  132. return assign<Other>(ptr);
  133. }
  134. void swap(AutoPtr& ptr)
  135. {
  136. std::swap(_ptr, ptr._ptr);
  137. }
  138. template <class Other>
  139. AutoPtr<Other> cast() const
  140. /// Casts the AutoPtr via a dynamic cast to the given type.
  141. /// Returns an AutoPtr containing NULL if the cast fails.
  142. /// Example: (assume class Sub: public Super)
  143. /// AutoPtr<Super> super(new Sub());
  144. /// AutoPtr<Sub> sub = super.cast<Sub>();
  145. /// poco_assert (sub.get());
  146. {
  147. Other* pOther = dynamic_cast<Other*>(_ptr);
  148. return AutoPtr<Other>(pOther, true);
  149. }
  150. template <class Other>
  151. AutoPtr<Other> unsafeCast() const
  152. /// Casts the AutoPtr via a static cast to the given type.
  153. /// Example: (assume class Sub: public Super)
  154. /// AutoPtr<Super> super(new Sub());
  155. /// AutoPtr<Sub> sub = super.unsafeCast<Sub>();
  156. /// poco_assert (sub.get());
  157. {
  158. Other* pOther = static_cast<Other*>(_ptr);
  159. return AutoPtr<Other>(pOther, true);
  160. }
  161. C* operator -> ()
  162. {
  163. if (_ptr)
  164. return _ptr;
  165. else
  166. throw NullPointerException();
  167. }
  168. const C* operator -> () const
  169. {
  170. if (_ptr)
  171. return _ptr;
  172. else
  173. throw NullPointerException();
  174. }
  175. C& operator * ()
  176. {
  177. if (_ptr)
  178. return *_ptr;
  179. else
  180. throw NullPointerException();
  181. }
  182. const C& operator * () const
  183. {
  184. if (_ptr)
  185. return *_ptr;
  186. else
  187. throw NullPointerException();
  188. }
  189. C* get()
  190. {
  191. return _ptr;
  192. }
  193. const C* get() const
  194. {
  195. return _ptr;
  196. }
  197. operator C* ()
  198. {
  199. return _ptr;
  200. }
  201. operator const C* () const
  202. {
  203. return _ptr;
  204. }
  205. bool operator ! () const
  206. {
  207. return _ptr == 0;
  208. }
  209. bool isNull() const
  210. {
  211. return _ptr == 0;
  212. }
  213. C* duplicate()
  214. {
  215. if (_ptr) _ptr->duplicate();
  216. return _ptr;
  217. }
  218. bool operator == (const AutoPtr& ptr) const
  219. {
  220. return _ptr == ptr._ptr;
  221. }
  222. bool operator == (const C* ptr) const
  223. {
  224. return _ptr == ptr;
  225. }
  226. bool operator == (C* ptr) const
  227. {
  228. return _ptr == ptr;
  229. }
  230. bool operator != (const AutoPtr& ptr) const
  231. {
  232. return _ptr != ptr._ptr;
  233. }
  234. bool operator != (const C* ptr) const
  235. {
  236. return _ptr != ptr;
  237. }
  238. bool operator != (C* ptr) const
  239. {
  240. return _ptr != ptr;
  241. }
  242. bool operator < (const AutoPtr& ptr) const
  243. {
  244. return _ptr < ptr._ptr;
  245. }
  246. bool operator < (const C* ptr) const
  247. {
  248. return _ptr < ptr;
  249. }
  250. bool operator < (C* ptr) const
  251. {
  252. return _ptr < ptr;
  253. }
  254. bool operator <= (const AutoPtr& ptr) const
  255. {
  256. return _ptr <= ptr._ptr;
  257. }
  258. bool operator <= (const C* ptr) const
  259. {
  260. return _ptr <= ptr;
  261. }
  262. bool operator <= (C* ptr) const
  263. {
  264. return _ptr <= ptr;
  265. }
  266. bool operator > (const AutoPtr& ptr) const
  267. {
  268. return _ptr > ptr._ptr;
  269. }
  270. bool operator > (const C* ptr) const
  271. {
  272. return _ptr > ptr;
  273. }
  274. bool operator > (C* ptr) const
  275. {
  276. return _ptr > ptr;
  277. }
  278. bool operator >= (const AutoPtr& ptr) const
  279. {
  280. return _ptr >= ptr._ptr;
  281. }
  282. bool operator >= (const C* ptr) const
  283. {
  284. return _ptr >= ptr;
  285. }
  286. bool operator >= (C* ptr) const
  287. {
  288. return _ptr >= ptr;
  289. }
  290. private:
  291. C* _ptr;
  292. };
  293. template <class C>
  294. inline void swap(AutoPtr<C>& p1, AutoPtr<C>& p2)
  295. {
  296. p1.swap(p2);
  297. }
  298. } // namespace Poco
  299. #endif // Foundation_AutoPtr_INCLUDED