You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
4.1 KiB

  1. #ifndef INCLUDED_AI_BOOST_SHARED_ARRAY
  2. #define INCLUDED_AI_BOOST_SHARED_ARRAY
  3. #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
  4. // ------------------------------
  5. // Internal stub
  6. namespace boost {
  7. namespace array_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_array, not threadsafe because no
  51. // atomic reference counter is in use.
  52. // ------------------------------
  53. template <class T>
  54. class shared_array
  55. {
  56. template <typename TT> friend class shared_array;
  57. template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
  58. template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
  59. template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b);
  60. public:
  61. typedef T element_type;
  62. public:
  63. // provide a default constructor
  64. shared_array()
  65. : ptr()
  66. , ctr(NULL)
  67. {
  68. }
  69. // construction from an existing object of type T
  70. explicit shared_array(T* ptr)
  71. : ptr(ptr)
  72. , ctr(ptr ? new array_detail::controller() : NULL)
  73. {
  74. }
  75. shared_array(const shared_array& r)
  76. : ptr(r.ptr)
  77. , ctr(r.ctr ? r.ctr->incref() : NULL)
  78. {
  79. }
  80. template <typename Y>
  81. shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
  82. : ptr(r.ptr)
  83. , ctr(r.ctr ? r.ctr->incref() : NULL)
  84. {
  85. }
  86. // automatic destruction of the wrapped object when all
  87. // references are freed.
  88. ~shared_array() {
  89. if (ctr) {
  90. ctr = ctr->decref(ptr);
  91. }
  92. }
  93. shared_array& operator=(const shared_array& r) {
  94. if (this == &r) {
  95. return *this;
  96. }
  97. if (ctr) {
  98. ctr->decref(ptr);
  99. }
  100. ptr = r.ptr;
  101. ctr = ptr?r.ctr->incref():NULL;
  102. return *this;
  103. }
  104. template <typename Y>
  105. shared_array& operator=(const shared_array<Y>& r) {
  106. if (this == &r) {
  107. return *this;
  108. }
  109. if (ctr) {
  110. ctr->decref(ptr);
  111. }
  112. ptr = r.ptr;
  113. ctr = ptr?r.ctr->incref():NULL;
  114. return *this;
  115. }
  116. // pointer access
  117. inline operator T*() {
  118. return ptr;
  119. }
  120. inline T* operator-> () const {
  121. return ptr;
  122. }
  123. // standard semantics
  124. inline T* get() {
  125. return ptr;
  126. }
  127. T& operator[] (std::ptrdiff_t index) const {
  128. return ptr[index];
  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 array_detail::controller():NULL;
  148. }
  149. void swap(shared_array & b) {
  150. std::swap(ptr, b.ptr);
  151. std::swap(ctr, b.ctr);
  152. }
  153. private:
  154. // encapsulated object pointer
  155. T* ptr;
  156. // control block
  157. array_detail::controller* ctr;
  158. };
  159. template<class T>
  160. inline void swap(shared_array<T> & a, shared_array<T> & b)
  161. {
  162. a.swap(b);
  163. }
  164. template<class T>
  165. bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
  166. return a.ptr == b.ptr;
  167. }
  168. template<class T>
  169. bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
  170. return a.ptr != b.ptr;
  171. }
  172. template<class T>
  173. bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
  174. return a.ptr < b.ptr;
  175. }
  176. } // end of namespace boost
  177. #else
  178. # error "shared_array.h was already included"
  179. #endif
  180. #endif // INCLUDED_AI_BOOST_SHARED_ARRAY