ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
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.
 
 
 
 
 
 

290 lines
6.0 KiB

  1. #ifndef BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
  2. #define BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
  3. //
  4. // detail/shared_count.hpp
  5. //
  6. // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
  7. // Copyright 2004-2005 Peter Dimov
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. //
  13. #ifdef __BORLANDC__
  14. # pragma warn -8027 // Functions containing try are not expanded inline
  15. #endif
  16. #include <booster/config.h>
  17. #include <booster/checked_delete.h>
  18. #include <booster/bad_weak_ptr.h>
  19. #include <booster/smart_ptr/sp_counted_base.h>
  20. #include <booster/smart_ptr/sp_counted_impl.h>
  21. #include <booster/auto_ptr_inc.h>
  22. #include <functional> // std::less
  23. #include <new> // std::bad_alloc
  24. namespace booster
  25. {
  26. namespace detail
  27. {
  28. struct sp_nothrow_tag {};
  29. class weak_count;
  30. class shared_count
  31. {
  32. private:
  33. sp_counted_base * pi_;
  34. friend class weak_count;
  35. public:
  36. shared_count(): pi_(0) // nothrow
  37. {
  38. }
  39. template<class Y> explicit shared_count( Y * p ): pi_( 0 )
  40. {
  41. try
  42. {
  43. pi_ = new sp_counted_impl_p<Y>( p );
  44. }
  45. catch(...)
  46. {
  47. booster::checked_delete( p );
  48. throw;
  49. }
  50. }
  51. template<class P, class D> shared_count( P p, D d ): pi_(0)
  52. {
  53. try
  54. {
  55. pi_ = new sp_counted_impl_pd<P, D>(p, d);
  56. }
  57. catch(...)
  58. {
  59. d(p); // delete p
  60. throw;
  61. }
  62. }
  63. template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
  64. {
  65. typedef sp_counted_impl_pda<P, D, A> impl_type;
  66. typedef typename A::template rebind< impl_type >::other A2;
  67. A2 a2( a );
  68. try
  69. {
  70. pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
  71. new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
  72. }
  73. catch(...)
  74. {
  75. d( p );
  76. if( pi_ != 0 )
  77. {
  78. a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
  79. }
  80. throw;
  81. }
  82. }
  83. // auto_ptr<Y> is special cased to provide the strong guarantee
  84. template<class Y>
  85. explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
  86. {
  87. r.release();
  88. }
  89. ~shared_count() // nothrow
  90. {
  91. if( pi_ != 0 ) pi_->release();
  92. }
  93. shared_count(shared_count const & r): pi_(r.pi_) // nothrow
  94. {
  95. if( pi_ != 0 ) pi_->add_ref_copy();
  96. }
  97. explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
  98. shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
  99. shared_count & operator= (shared_count const & r) // nothrow
  100. {
  101. sp_counted_base * tmp = r.pi_;
  102. if( tmp != pi_ )
  103. {
  104. if( tmp != 0 ) tmp->add_ref_copy();
  105. if( pi_ != 0 ) pi_->release();
  106. pi_ = tmp;
  107. }
  108. return *this;
  109. }
  110. void swap(shared_count & r) // nothrow
  111. {
  112. sp_counted_base * tmp = r.pi_;
  113. r.pi_ = pi_;
  114. pi_ = tmp;
  115. }
  116. long use_count() const // nothrow
  117. {
  118. return pi_ != 0? pi_->use_count(): 0;
  119. }
  120. bool unique() const // nothrow
  121. {
  122. return use_count() == 1;
  123. }
  124. bool empty() const // nothrow
  125. {
  126. return pi_ == 0;
  127. }
  128. friend inline bool operator==(shared_count const & a, shared_count const & b)
  129. {
  130. return a.pi_ == b.pi_;
  131. }
  132. friend inline bool operator<(shared_count const & a, shared_count const & b)
  133. {
  134. return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
  135. }
  136. void * get_deleter( sp_typeinfo const & ti ) const
  137. {
  138. return pi_? pi_->get_deleter( ti ): 0;
  139. }
  140. };
  141. class weak_count
  142. {
  143. private:
  144. sp_counted_base * pi_;
  145. friend class shared_count;
  146. public:
  147. weak_count(): pi_(0) // nothrow
  148. {
  149. }
  150. weak_count(shared_count const & r): pi_(r.pi_) // nothrow
  151. {
  152. if(pi_ != 0) pi_->weak_add_ref();
  153. }
  154. weak_count(weak_count const & r): pi_(r.pi_) // nothrow
  155. {
  156. if(pi_ != 0) pi_->weak_add_ref();
  157. }
  158. ~weak_count() // nothrow
  159. {
  160. if(pi_ != 0) pi_->weak_release();
  161. }
  162. weak_count & operator= (shared_count const & r) // nothrow
  163. {
  164. sp_counted_base * tmp = r.pi_;
  165. if( tmp != pi_ )
  166. {
  167. if(tmp != 0) tmp->weak_add_ref();
  168. if(pi_ != 0) pi_->weak_release();
  169. pi_ = tmp;
  170. }
  171. return *this;
  172. }
  173. weak_count & operator= (weak_count const & r) // nothrow
  174. {
  175. sp_counted_base * tmp = r.pi_;
  176. if( tmp != pi_ )
  177. {
  178. if(tmp != 0) tmp->weak_add_ref();
  179. if(pi_ != 0) pi_->weak_release();
  180. pi_ = tmp;
  181. }
  182. return *this;
  183. }
  184. void swap(weak_count & r) // nothrow
  185. {
  186. sp_counted_base * tmp = r.pi_;
  187. r.pi_ = pi_;
  188. pi_ = tmp;
  189. }
  190. long use_count() const // nothrow
  191. {
  192. return pi_ != 0? pi_->use_count(): 0;
  193. }
  194. bool empty() const // nothrow
  195. {
  196. return pi_ == 0;
  197. }
  198. friend inline bool operator==(weak_count const & a, weak_count const & b)
  199. {
  200. return a.pi_ == b.pi_;
  201. }
  202. friend inline bool operator<(weak_count const & a, weak_count const & b)
  203. {
  204. return std::less<sp_counted_base *>()(a.pi_, b.pi_);
  205. }
  206. };
  207. inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
  208. {
  209. if( pi_ == 0 || !pi_->add_ref_lock() )
  210. {
  211. throw booster::bad_weak_ptr();
  212. }
  213. }
  214. inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
  215. {
  216. if( pi_ != 0 && !pi_->add_ref_lock() )
  217. {
  218. pi_ = 0;
  219. }
  220. }
  221. } // namespace detail
  222. } // namespace boost
  223. #ifdef __BORLANDC__
  224. # pragma warn .8027 // Functions containing try are not expanded inline
  225. #endif
  226. #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED