Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

258 rader
4.8 KiB

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