Advertisement
Guest User

Untitled

a guest
Mar 7th, 2011
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.43 KB | None | 0 0
  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. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37.  
  38.  
  39. #ifndef Foundation_AutoPtr_INCLUDED
  40. #define Foundation_AutoPtr_INCLUDED
  41.  
  42.  
  43. #include "Poco/Foundation.h"
  44. #include "Poco/Exception.h"
  45. #include <algorithm>
  46. #include <functional> // for std::less, greater, etc
  47.  
  48. namespace Poco {
  49.  
  50.  
  51. template <class C>
  52. class AutoPtr
  53. /// AutoPtr is a "smart" pointer for classes implementing
  54. /// reference counting based garbage collection.
  55. /// To be usable with the AutoPtr template, a class must
  56. /// implement the following behaviour:
  57. /// A class must maintain a reference count.
  58. /// The constructors of the object initialize the reference
  59. /// count to one.
  60. /// The class must implement a public duplicate() method:
  61. /// void duplicate();
  62. /// that increments the reference count by one.
  63. /// The class must implement a public release() method:
  64. /// void release()
  65. /// that decrements the reference count by one, and,
  66. /// if the reference count reaches zero, deletes the
  67. /// object.
  68. ///
  69. /// AutoPtr works in the following way:
  70. /// If an AutoPtr is assigned an ordinary pointer to
  71. /// an object (via the constructor or the assignment operator),
  72. /// it takes ownership of the object and the object's reference
  73. /// count remains unchanged.
  74. /// If the AutoPtr is assigned another AutoPtr, the
  75. /// object's reference count is incremented by one by
  76. /// calling duplicate() on its object.
  77. /// The destructor of AutoPtr calls release() on its
  78. /// object.
  79. /// AutoPtr supports dereferencing with both the ->
  80. /// and the * operator. An attempt to dereference a null
  81. /// AutoPtr results in a NullPointerException being thrown.
  82. /// AutoPtr also implements all relational operators.
  83. /// Note that AutoPtr allows casting of its encapsulated data types.
  84. {
  85. public:
  86. AutoPtr(): _ptr(0)
  87. {
  88. }
  89.  
  90. AutoPtr(C* ptr): _ptr(ptr)
  91. {
  92. }
  93.  
  94. AutoPtr(C* ptr, bool shared): _ptr(ptr)
  95. {
  96. if (shared && _ptr) _ptr->duplicate();
  97. }
  98.  
  99. AutoPtr(const AutoPtr& ptr): _ptr(ptr._ptr)
  100. {
  101. if (_ptr) _ptr->duplicate();
  102. }
  103.  
  104. template <class Other>
  105. AutoPtr(const AutoPtr<Other>& ptr): _ptr(ptr.get())
  106. {
  107. if (_ptr) _ptr->duplicate();
  108. }
  109.  
  110. ~AutoPtr()
  111. {
  112. if (_ptr) _ptr->release();
  113. }
  114.  
  115. AutoPtr& assign(C* ptr)
  116. {
  117. if (_ptr != ptr)
  118. {
  119. if (_ptr) _ptr->release();
  120. _ptr = ptr;
  121. }
  122. return *this;
  123. }
  124.  
  125. AutoPtr& assign(C* ptr, bool shared)
  126. {
  127. if (_ptr != ptr)
  128. {
  129. if (_ptr) _ptr->release();
  130. _ptr = ptr;
  131. if (shared && _ptr) _ptr->duplicate();
  132. }
  133. return *this;
  134. }
  135.  
  136. AutoPtr& assign(const AutoPtr& ptr)
  137. {
  138. if (&ptr != this)
  139. {
  140. if (_ptr) _ptr->release();
  141. _ptr = ptr._ptr;
  142. if (_ptr) _ptr->duplicate();
  143. }
  144. return *this;
  145. }
  146.  
  147. template <class Other>
  148. AutoPtr& assign(const AutoPtr<Other>& ptr)
  149. {
  150. if (ptr.get() != _ptr)
  151. {
  152. if (_ptr) _ptr->release();
  153. _ptr = ptr.get();
  154. if (_ptr) _ptr->duplicate();
  155. }
  156. return *this;
  157. }
  158.  
  159. AutoPtr& operator = (C* ptr)
  160. {
  161. return assign(ptr);
  162. }
  163.  
  164. AutoPtr& operator = (const AutoPtr& ptr)
  165. {
  166. return assign(ptr);
  167. }
  168.  
  169. template <class Other>
  170. AutoPtr& operator = (const AutoPtr<Other>& ptr)
  171. {
  172. return assign<Other>(ptr);
  173. }
  174.  
  175. void swap(AutoPtr& ptr)
  176. {
  177. std::swap(_ptr, ptr._ptr);
  178. }
  179.  
  180. template <class Other>
  181. AutoPtr<Other> cast() const
  182. /// Casts the AutoPtr via a dynamic cast to the given type.
  183. /// Returns an AutoPtr containing NULL if the cast fails.
  184. /// Example: (assume class Sub: public Super)
  185. /// AutoPtr<Super> super(new Sub());
  186. /// AutoPtr<Sub> sub = super.cast<Sub>();
  187. /// poco_assert (sub.get());
  188. {
  189. Other* pOther = dynamic_cast<Other*>(_ptr);
  190. return AutoPtr<Other>(pOther, true);
  191. }
  192.  
  193. template <class Other>
  194. AutoPtr<Other> unsafeCast() const
  195. /// Casts the AutoPtr via a static cast to the given type.
  196. /// Example: (assume class Sub: public Super)
  197. /// AutoPtr<Super> super(new Sub());
  198. /// AutoPtr<Sub> sub = super.unsafeCast<Sub>();
  199. /// poco_assert (sub.get());
  200. {
  201. Other* pOther = static_cast<Other*>(_ptr);
  202. return AutoPtr<Other>(pOther, true);
  203. }
  204.  
  205. C* operator -> () const
  206. {
  207. if (_ptr)
  208. return _ptr;
  209. else
  210. throw NullPointerException();
  211. }
  212.  
  213. C& operator * () const
  214. {
  215. if (_ptr)
  216. return *_ptr;
  217. else
  218. throw NullPointerException();
  219. }
  220.  
  221. C* get() const
  222. {
  223. return _ptr;
  224. }
  225.  
  226. // This also serves as an safe implicit conversion to a boolean type
  227. operator C* () const
  228. {
  229. return _ptr;
  230. }
  231.  
  232. bool operator ! () const
  233. {
  234. return _ptr == 0;
  235. }
  236.  
  237. bool isNull() const
  238. {
  239. return _ptr == 0;
  240. }
  241.  
  242. C* duplicate() const
  243. {
  244. if (_ptr) _ptr->duplicate();
  245. return _ptr;
  246. }
  247. private:
  248. C* _ptr;
  249. };
  250.  
  251. namespace Detail {
  252. // This class will generate a compilation error if the types T and U
  253. // can not be compared, i.e. they do not have a a composite
  254. // pointer type
  255. // Intentionaly complex to reduce the likeliness of warnings
  256. template <class T, class U>
  257. struct EnsureHasCompositePointerType
  258. {
  259. static void constraints(T* a, U* b, bool& x)
  260. {
  261. // If you get a compilation error here, then you have
  262. // tried to compare two smart pointers with
  263. // unrelated types.
  264. x = a < b;
  265. }
  266. typedef void f_type(T*, U*, bool&);
  267. void no_op(f_type)
  268. {
  269. // empty on purpose
  270. }
  271. EnsureHasCompositePointerType()
  272. {
  273. // This assignment should be optimized away by the compiler
  274. void (*p)(T*, U*, bool&) = constraints;
  275. // To get rid of the warning that we do not use the
  276. // variable
  277. no_op(p);
  278. }
  279. };
  280.  
  281. // The use of EnsureHasCompositePointerType, is done to ensure that
  282. // the pointers can be compared using the normal C++ language rules.
  283. // The reason the operators are not used directly is because
  284. // they are not required to give a total ordering for objects of any
  285. // type, however the predicates, eg. std::less, are required to give
  286. // a total ordering.
  287.  
  288. template <class T, class U>
  289. bool pointerLess(T* a, U* b)
  290. {
  291. EnsureHasCompositePointerType<T, U>();
  292. return std::less<const void*>()(a, b);
  293. }
  294. template <class T, class U>
  295. bool pointerLessEq(T* a, U* b)
  296. {
  297. EnsureHasCompositePointerType<T, U>();
  298. return std::less_equal<const void*>()(a, b);
  299. }
  300. template <class T, class U>
  301. bool pointerGreater(T* a, U* b)
  302. {
  303. EnsureHasCompositePointerType<T, U>();
  304. return std::greater<const void*>()(a, b);
  305. }
  306. template <class T, class U>
  307. bool pointerGreaterEq(T* a, U* b)
  308. {
  309. EnsureHasCompositePointerType<T, U>();
  310. return std::greater_equal<const void*>()(a, b);
  311. }
  312. }
  313.  
  314. template <class C>
  315. inline void swap(AutoPtr<C>& p1, AutoPtr<C>& p2)
  316. {
  317. p1.swap(p2);
  318. }
  319.  
  320. template <class T, class U>
  321. bool operator == (const AutoPtr<T>& a, const AutoPtr<U>& b)
  322. {
  323. return a.get() == b.get();
  324. }
  325.  
  326. template <class T, class U>
  327. bool operator == (T* a, const AutoPtr<U>& b)
  328. {
  329. return a == b.get();
  330. }
  331.  
  332. template <class T, class U>
  333. bool operator == (const AutoPtr<T>& a, U* b)
  334. {
  335. return a.get() == b;
  336. }
  337.  
  338.  
  339. template <class T, class U>
  340. bool operator != (const AutoPtr<T>& a, const AutoPtr<U>& b)
  341. {
  342. return a.get() != b.get();
  343. }
  344.  
  345. template <class T, class U>
  346. bool operator != (T* a, const AutoPtr<U>& b)
  347. {
  348. return a != b.get();
  349. }
  350.  
  351. template <class T, class U>
  352. bool operator != (const AutoPtr<T>& a, U* b)
  353. {
  354. return a.get() != b;
  355. }
  356.  
  357.  
  358. template <class T, class U>
  359. bool operator < (const AutoPtr<T>& a, const AutoPtr<U>& b)
  360. {
  361. return Detail::pointerLess(a.get(), b.get());
  362. }
  363.  
  364. template <class T, class U>
  365. bool operator < (T* a, const AutoPtr<U>& b)
  366. {
  367. return Detail::pointerLess(a, b.get());
  368. }
  369.  
  370. template <class T, class U>
  371. bool operator < (const AutoPtr<T>& a, U* b)
  372. {
  373. return Detail::pointerLess(a.get(), b);
  374. }
  375.  
  376.  
  377. template <class T, class U>
  378. bool operator <= (const AutoPtr<T>& a, const AutoPtr<U>& b)
  379. {
  380. return Detail::pointerLessEq(a.get(), b.get());
  381. }
  382.  
  383. template <class T, class U>
  384. bool operator <= (T* a, const AutoPtr<U>& b)
  385. {
  386. return Detail::pointerLessEq(a, b.get());
  387. }
  388.  
  389. template <class T, class U>
  390. bool operator <= (const AutoPtr<T>& a, U* b)
  391. {
  392. return Detail::pointerLessEq(a.get(), b);
  393. }
  394.  
  395.  
  396. template <class T, class U>
  397. bool operator > (const AutoPtr<T>& a, const AutoPtr<U>& b)
  398. {
  399. return Detail::pointerGreater(a.get(), b.get());
  400. }
  401.  
  402. template <class T, class U>
  403. bool operator > (T* a, const AutoPtr<U>& b)
  404. {
  405. return Detail::pointerGreater(a, b.get());
  406. }
  407.  
  408. template <class T, class U>
  409. bool operator > (const AutoPtr<T>& a, U* b)
  410. {
  411. return Detail::pointerGreater(a.get(), b);
  412. }
  413.  
  414.  
  415. template <class T, class U>
  416. bool operator >= (const AutoPtr<T>& a, const AutoPtr<U>& b)
  417. {
  418. return Detail::pointerGreaterEq(a.get(), b.get());
  419. }
  420.  
  421. template <class T, class U>
  422. bool operator >= (T* a, const AutoPtr<U>& b)
  423. {
  424. return Detail::pointerGreaterEq(a, b.get());
  425. }
  426.  
  427. template <class T, class U>
  428. bool operator >= (const AutoPtr<T>& a, U* b)
  429. {
  430. return Detail::pointerGreaterEq(a.get(), b);
  431. }
  432.  
  433. } // namespace Poco
  434.  
  435.  
  436. #endif // Foundation_AutoPtr_INCLUDED
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement