This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 7th, 2011  |  syntax: None  |  size: 10.43 KB  |  views: 44  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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
clone this paste RAW Paste Data