shared_ptr.hpp 2.8 KB

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