shared_ptr.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #ifndef INCLUDED_AI_BOOST_SHARED_PTR
  2. #define INCLUDED_AI_BOOST_SHARED_PTR
  3. #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
  4. #include <assert.h>
  5. // ------------------------------
  6. // Internal stub
  7. namespace boost {
  8. namespace detail {
  9. class controller {
  10. public:
  11. controller()
  12. : cnt(0)
  13. {}
  14. template <typename T>
  15. controller(T* ptr)
  16. : cnt(ptr?1:0)
  17. {}
  18. public:
  19. template <typename T>
  20. controller* decref(T* pt) {
  21. if (!pt) {
  22. return NULL;
  23. }
  24. if (--cnt <= 0) {
  25. delete this;
  26. delete pt;
  27. }
  28. return NULL;
  29. }
  30. controller* incref() {
  31. ++cnt;
  32. return this;
  33. }
  34. private:
  35. long cnt;
  36. };
  37. struct empty {};
  38. template <typename DEST, typename SRC>
  39. struct is_convertible_stub {
  40. struct yes {char s[1];};
  41. struct no {char s[2];};
  42. static yes foo(DEST*);
  43. static no foo(...);
  44. enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
  45. };
  46. template <bool> struct enable_if {};
  47. template <> struct enable_if<true> {
  48. typedef empty result;
  49. };
  50. template <typename DEST, typename SRC>
  51. struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
  52. };
  53. }
  54. // ------------------------------
  55. // Small replacement for boost::shared_ptr, not threadsafe because no
  56. // atomic reference counter is in use.
  57. // ------------------------------
  58. template <class T>
  59. class shared_ptr
  60. {
  61. template <typename TT> friend class shared_ptr;
  62. public:
  63. // provide a default construtctor
  64. shared_ptr()
  65. : ptr()
  66. , ctr(new detail::controller())
  67. {
  68. }
  69. // construction from an existing object of type T
  70. explicit shared_ptr(T* _ptr)
  71. : ptr(_ptr)
  72. , ctr(new detail::controller(ptr))
  73. {
  74. }
  75. shared_ptr(const shared_ptr& o)
  76. : ptr(o.ptr)
  77. , ctr(o.ctr->incref())
  78. {
  79. }
  80. template <typename Y>
  81. shared_ptr(const shared_ptr<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty())
  82. : ptr(o.ptr)
  83. , ctr(o.ctr->incref())
  84. {
  85. }
  86. // automatic destruction of the wrapped object when all
  87. // references are freed.
  88. ~shared_ptr() {
  89. ctr = ctr->decref(ptr);
  90. }
  91. // pointer access
  92. inline operator T*() {
  93. return ptr;
  94. }
  95. inline T* operator-> () {
  96. return ptr;
  97. }
  98. // standard semantics
  99. inline T* get() {
  100. return ptr;
  101. }
  102. inline operator bool () const {
  103. return ptr != NULL;
  104. }
  105. inline void reset (T* t = 0) {
  106. ctr = ctr->decref(ptr);
  107. ptr = t;
  108. if(ptr) {
  109. ctr = new detail::controller(ptr);
  110. }
  111. }
  112. void swap(shared_ptr & b) {
  113. std::swap(ptr, b.ptr);
  114. std::swap(ctr, b.ctr);
  115. }
  116. private:
  117. // encapsulated object pointer
  118. T* ptr;
  119. // control block
  120. detail::controller* ctr;
  121. };
  122. template<class T>
  123. inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
  124. {
  125. a.swap(b);
  126. }
  127. } // end of namespace boost
  128. #else
  129. # error "shared_ptr.h was already included"
  130. #endif
  131. #endif // INCLUDED_AI_BOOST_SCOPED_PTR