2
0

shared_ptr.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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;
  91. }
  92. ctr->decref(ptr);
  93. ctr = r.ctr->incref();
  94. ptr = r.ptr;
  95. }
  96. // automatic destruction of the wrapped object when all
  97. // references are freed.
  98. ~shared_ptr() {
  99. ctr = ctr->decref(ptr);
  100. }
  101. // pointer access
  102. inline operator T*() {
  103. return ptr;
  104. }
  105. inline T* operator-> () {
  106. return ptr;
  107. }
  108. // standard semantics
  109. inline T* get() {
  110. return ptr;
  111. }
  112. inline operator bool () const {
  113. return ptr != NULL;
  114. }
  115. inline bool unique() const {
  116. return use_count() == 1;
  117. }
  118. inline long use_count() const {
  119. return ctr->get();
  120. }
  121. inline void reset (T* t = 0) {
  122. ctr = ctr->decref(ptr);
  123. ptr = t;
  124. if(ptr) {
  125. ctr = new detail::controller(ptr);
  126. }
  127. }
  128. void swap(shared_ptr & b) {
  129. std::swap(ptr, b.ptr);
  130. std::swap(ctr, b.ctr);
  131. }
  132. private:
  133. // encapsulated object pointer
  134. T* ptr;
  135. // control block
  136. detail::controller* ctr;
  137. };
  138. template<class T>
  139. inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
  140. {
  141. a.swap(b);
  142. }
  143. template<class T>
  144. bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
  145. return a.ptr == b.ptr;
  146. }
  147. template<class T>
  148. bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
  149. return a.ptr != b.ptr;
  150. }
  151. template<class T>
  152. bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
  153. return a.ptr < b.ptr;
  154. }
  155. } // end of namespace boost
  156. #else
  157. # error "shared_ptr.h was already included"
  158. #endif
  159. #endif // INCLUDED_AI_BOOST_SCOPED_PTR