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.
 
 
 
 
 
 

449 lines
11 KiB

  1. #ifndef BOOSTER_SMART_PTR_SHARED_PTR_HPP_INCLUDED
  2. #define BOOSTER_SMART_PTR_SHARED_PTR_HPP_INCLUDED
  3. //
  4. // shared_ptr.hpp
  5. //
  6. // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
  7. // Copyright (c) 2001-2008 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. // See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
  14. //
  15. #include <booster/config.h> // for broken compiler workarounds
  16. #include <booster/auto_ptr_inc.h>
  17. #include <cassert>
  18. #include <booster/backtrace.h>
  19. #include <booster/checked_delete.h>
  20. #include <booster/smart_ptr/shared_count.h>
  21. #include <booster/smart_ptr/sp_convertible.h>
  22. #include <algorithm> // for std::swap
  23. #include <functional> // for std::less
  24. #include <typeinfo> // for std::bad_cast
  25. #include <iosfwd> // for std::basic_ostream
  26. #ifdef BOOSTER_MSVC // moved here to work around VC++ compiler crash
  27. # pragma warning(push)
  28. # pragma warning(disable:4284) // odd return type for operator->
  29. #endif
  30. namespace booster
  31. {
  32. template<class T> class shared_ptr;
  33. template<class T> class weak_ptr;
  34. template<class T> class enable_shared_from_this;
  35. template<class T> class enable_shared_from_this2;
  36. namespace detail
  37. {
  38. struct static_cast_tag {};
  39. struct const_cast_tag {};
  40. struct dynamic_cast_tag {};
  41. struct polymorphic_cast_tag {};
  42. template<class T> struct shared_ptr_traits
  43. {
  44. typedef T & reference;
  45. };
  46. template<> struct shared_ptr_traits<void>
  47. {
  48. typedef void reference;
  49. };
  50. template<> struct shared_ptr_traits<void const>
  51. {
  52. typedef void reference;
  53. };
  54. template<> struct shared_ptr_traits<void volatile>
  55. {
  56. typedef void reference;
  57. };
  58. template<> struct shared_ptr_traits<void const volatile>
  59. {
  60. typedef void reference;
  61. };
  62. // enable_shared_from_this support
  63. template< class X, class Y, class T > inline void sp_enable_shared_from_this( booster::shared_ptr<X> const * ppx, Y const * py, booster::enable_shared_from_this< T > const * pe )
  64. {
  65. if( pe != 0 )
  66. {
  67. pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
  68. }
  69. }
  70. template< class X, class Y, class T > inline void sp_enable_shared_from_this( booster::shared_ptr<X> * ppx, Y const * py, booster::enable_shared_from_this2< T > const * pe )
  71. {
  72. if( pe != 0 )
  73. {
  74. pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
  75. }
  76. }
  77. inline void sp_enable_shared_from_this( ... )
  78. {
  79. }
  80. // rvalue auto_ptr support based on a technique by Dave Abrahams
  81. template< class T, class R > struct sp_enable_if_auto_ptr
  82. {
  83. };
  84. template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
  85. {
  86. typedef R type;
  87. };
  88. } // namespace detail
  89. //
  90. // shared_ptr
  91. //
  92. // An enhanced relative of scoped_ptr with reference counted copy semantics.
  93. // The object pointed to is deleted when the last shared_ptr pointing to it
  94. // is destroyed or reset.
  95. //
  96. template<class T> class shared_ptr
  97. {
  98. private:
  99. // Borland 5.5.1 specific workaround
  100. typedef shared_ptr<T> this_type;
  101. public:
  102. typedef T element_type;
  103. typedef T value_type;
  104. typedef T * pointer;
  105. typedef typename booster::detail::shared_ptr_traits<T>::reference reference;
  106. shared_ptr(): px(0), pn() // never throws in 1.30+
  107. {
  108. }
  109. template<class Y>
  110. explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
  111. {
  112. booster::detail::sp_enable_shared_from_this( this, p, p );
  113. }
  114. //
  115. // Requirements: D's copy constructor must not throw
  116. //
  117. // shared_ptr will release p by calling d(p)
  118. //
  119. template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
  120. {
  121. booster::detail::sp_enable_shared_from_this( this, p, p );
  122. }
  123. // As above, but with allocator. A's copy constructor shall not throw.
  124. template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
  125. {
  126. booster::detail::sp_enable_shared_from_this( this, p, p );
  127. }
  128. // generated copy constructor, destructor are fine
  129. template<class Y>
  130. explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
  131. {
  132. // it is now safe to copy r.px, as pn(r.pn) did not throw
  133. px = r.px;
  134. }
  135. template<class Y>
  136. shared_ptr( weak_ptr<Y> const & r, booster::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, booster::detail::sp_nothrow_tag() ) // never throws
  137. {
  138. if( !pn.empty() )
  139. {
  140. px = r.px;
  141. }
  142. }
  143. template<class Y>
  144. shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
  145. : px( r.px ), pn( r.pn ) // never throws
  146. {
  147. }
  148. // aliasing
  149. template< class Y >
  150. shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
  151. {
  152. }
  153. template<class Y>
  154. shared_ptr(shared_ptr<Y> const & r, booster::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
  155. {
  156. }
  157. template<class Y>
  158. shared_ptr(shared_ptr<Y> const & r, booster::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
  159. {
  160. }
  161. template<class Y>
  162. shared_ptr(shared_ptr<Y> const & r, booster::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
  163. {
  164. if(px == 0) // need to allocate new counter -- the cast failed
  165. {
  166. pn = booster::detail::shared_count();
  167. }
  168. }
  169. template<class Y>
  170. shared_ptr(shared_ptr<Y> const & r, booster::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
  171. {
  172. if(px == 0)
  173. {
  174. throw booster::bad_cast();
  175. }
  176. }
  177. template<class Y>
  178. explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
  179. {
  180. Y * tmp = r.get();
  181. pn = booster::detail::shared_count(r);
  182. booster::detail::sp_enable_shared_from_this( this, tmp, tmp );
  183. }
  184. template<class Ap>
  185. explicit shared_ptr( Ap r, typename booster::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
  186. {
  187. typename Ap::element_type * tmp = r.get();
  188. pn = booster::detail::shared_count( r );
  189. booster::detail::sp_enable_shared_from_this( this, tmp, tmp );
  190. }
  191. // assignment
  192. shared_ptr & operator=( shared_ptr const & r ) // never throws
  193. {
  194. this_type(r).swap(*this);
  195. return *this;
  196. }
  197. template<class Y>
  198. shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
  199. {
  200. this_type(r).swap(*this);
  201. return *this;
  202. }
  203. template<class Y>
  204. shared_ptr & operator=( std::auto_ptr<Y> & r )
  205. {
  206. this_type(r).swap(*this);
  207. return *this;
  208. }
  209. template<class Ap>
  210. typename booster::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
  211. {
  212. this_type( r ).swap( *this );
  213. return *this;
  214. }
  215. // Move support
  216. void reset() // never throws in 1.30+
  217. {
  218. this_type().swap(*this);
  219. }
  220. template<class Y> void reset(Y * p) // Y must be complete
  221. {
  222. assert(p == 0 || p != px); // catch self-reset errors
  223. this_type(p).swap(*this);
  224. }
  225. template<class Y, class D> void reset( Y * p, D d )
  226. {
  227. this_type( p, d ).swap( *this );
  228. }
  229. template<class Y, class D, class A> void reset( Y * p, D d, A a )
  230. {
  231. this_type( p, d, a ).swap( *this );
  232. }
  233. template<class Y> void reset( shared_ptr<Y> const & r, T * p )
  234. {
  235. this_type( r, p ).swap( *this );
  236. }
  237. reference operator* () const // never throws
  238. {
  239. assert(px != 0);
  240. return *px;
  241. }
  242. T * operator-> () const // never throws
  243. {
  244. assert(px != 0);
  245. return px;
  246. }
  247. T * get() const // never throws
  248. {
  249. return px;
  250. }
  251. // implicit conversion to "bool"
  252. #include <booster/smart_ptr/operator_bool.h>
  253. bool unique() const // never throws
  254. {
  255. return pn.unique();
  256. }
  257. long use_count() const // never throws
  258. {
  259. return pn.use_count();
  260. }
  261. void swap(shared_ptr<T> & other) // never throws
  262. {
  263. std::swap(px, other.px);
  264. pn.swap(other.pn);
  265. }
  266. template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
  267. {
  268. return pn < rhs.pn;
  269. }
  270. void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
  271. {
  272. return pn.get_deleter( ti );
  273. }
  274. bool _internal_equiv( shared_ptr const & r ) const
  275. {
  276. return px == r.px && pn == r.pn;
  277. }
  278. // Tasteless as this may seem, making all members public allows member templates
  279. // to work in the absence of member template friends. (Matthew Langston)
  280. private:
  281. template<class Y> friend class shared_ptr;
  282. template<class Y> friend class weak_ptr;
  283. T * px; // contained pointer
  284. booster::detail::shared_count pn; // reference counter
  285. }; // shared_ptr
  286. template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
  287. {
  288. return a.get() == b.get();
  289. }
  290. template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
  291. {
  292. return a.get() != b.get();
  293. }
  294. template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
  295. {
  296. return a._internal_less(b);
  297. }
  298. template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
  299. {
  300. a.swap(b);
  301. }
  302. template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
  303. {
  304. return shared_ptr<T>(r, booster::detail::static_cast_tag());
  305. }
  306. template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
  307. {
  308. return shared_ptr<T>(r, booster::detail::const_cast_tag());
  309. }
  310. template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
  311. {
  312. return shared_ptr<T>(r, booster::detail::dynamic_cast_tag());
  313. }
  314. // shared_*_cast names are deprecated. Use *_pointer_cast instead.
  315. template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
  316. {
  317. return shared_ptr<T>(r, booster::detail::static_cast_tag());
  318. }
  319. template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
  320. {
  321. return shared_ptr<T>(r, booster::detail::dynamic_cast_tag());
  322. }
  323. template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
  324. {
  325. return shared_ptr<T>(r, booster::detail::polymorphic_cast_tag());
  326. }
  327. template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
  328. {
  329. assert(dynamic_cast<T *>(r.get()) == r.get());
  330. return shared_static_cast<T>(r);
  331. }
  332. // get_pointer() enables boost::mem_fn to recognize shared_ptr
  333. template<class T> inline T * get_pointer(shared_ptr<T> const & p)
  334. {
  335. return p.get();
  336. }
  337. // operator<<
  338. template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
  339. {
  340. os << p.get();
  341. return os;
  342. }
  343. // get_deleter
  344. template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
  345. {
  346. return static_cast<D *>(p._internal_get_deleter(BOOSTER_SP_TYPEID(D)));
  347. }
  348. } // namespace boost
  349. #ifdef BOOSTER_MSVC
  350. # pragma warning(pop)
  351. #endif
  352. #endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED