2
0

shared_ptr.hpp 3.8 KB

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