shared_ptr.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
  2. #define BOOST_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 <boost/config.hpp> // for broken compiler workarounds
  16. #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
  17. #include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
  18. #else
  19. // In order to avoid circular dependencies with Boost.TR1
  20. // we make sure that our include of <memory> doesn't try to
  21. // pull in the TR1 headers: that's why we use this header
  22. // rather than including <memory> directly:
  23. #include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
  24. #include <boost/assert.hpp>
  25. #include <boost/checked_delete.hpp>
  26. #include <boost/throw_exception.hpp>
  27. #include <boost/smart_ptr/detail/shared_count.hpp>
  28. #include <boost/detail/workaround.hpp>
  29. #include <boost/smart_ptr/detail/sp_convertible.hpp>
  30. #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
  31. #include <boost/smart_ptr/detail/spinlock_pool.hpp>
  32. #include <boost/memory_order.hpp>
  33. #endif
  34. #include <algorithm> // for std::swap
  35. #include <functional> // for std::less
  36. #include <typeinfo> // for std::bad_cast
  37. #if !defined(BOOST_NO_IOSTREAM)
  38. #if !defined(BOOST_NO_IOSFWD)
  39. #include <iosfwd> // for std::basic_ostream
  40. #else
  41. #include <ostream>
  42. #endif
  43. #endif
  44. #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
  45. # pragma warning(push)
  46. # pragma warning(disable:4284) // odd return type for operator->
  47. #endif
  48. namespace boost
  49. {
  50. template<class T> class shared_ptr;
  51. template<class T> class weak_ptr;
  52. template<class T> class enable_shared_from_this;
  53. template<class T> class enable_shared_from_this2;
  54. namespace detail
  55. {
  56. struct static_cast_tag {};
  57. struct const_cast_tag {};
  58. struct dynamic_cast_tag {};
  59. struct polymorphic_cast_tag {};
  60. template<class T> struct shared_ptr_traits
  61. {
  62. typedef T & reference;
  63. };
  64. template<> struct shared_ptr_traits<void>
  65. {
  66. typedef void reference;
  67. };
  68. #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
  69. template<> struct shared_ptr_traits<void const>
  70. {
  71. typedef void reference;
  72. };
  73. template<> struct shared_ptr_traits<void volatile>
  74. {
  75. typedef void reference;
  76. };
  77. template<> struct shared_ptr_traits<void const volatile>
  78. {
  79. typedef void reference;
  80. };
  81. #endif
  82. // enable_shared_from_this support
  83. template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
  84. {
  85. if( pe != 0 )
  86. {
  87. pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
  88. }
  89. }
  90. template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
  91. {
  92. if( pe != 0 )
  93. {
  94. pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
  95. }
  96. }
  97. #ifdef _MANAGED
  98. // Avoid C4793, ... causes native code generation
  99. struct sp_any_pointer
  100. {
  101. template<class T> sp_any_pointer( T* ) {}
  102. };
  103. inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
  104. {
  105. }
  106. #else // _MANAGED
  107. inline void sp_enable_shared_from_this( ... )
  108. {
  109. }
  110. #endif // _MANAGED
  111. #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
  112. // rvalue auto_ptr support based on a technique by Dave Abrahams
  113. template< class T, class R > struct sp_enable_if_auto_ptr
  114. {
  115. };
  116. template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
  117. {
  118. typedef R type;
  119. };
  120. #endif
  121. } // namespace detail
  122. //
  123. // shared_ptr
  124. //
  125. // An enhanced relative of scoped_ptr with reference counted copy semantics.
  126. // The object pointed to is deleted when the last shared_ptr pointing to it
  127. // is destroyed or reset.
  128. //
  129. template<class T> class shared_ptr
  130. {
  131. private:
  132. // Borland 5.5.1 specific workaround
  133. typedef shared_ptr<T> this_type;
  134. public:
  135. typedef T element_type;
  136. typedef T value_type;
  137. typedef T * pointer;
  138. typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
  139. shared_ptr(): px(0), pn() // never throws in 1.30+
  140. {
  141. }
  142. template<class Y>
  143. explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
  144. {
  145. boost::detail::sp_enable_shared_from_this( this, p, p );
  146. }
  147. //
  148. // Requirements: D's copy constructor must not throw
  149. //
  150. // shared_ptr will release p by calling d(p)
  151. //
  152. template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
  153. {
  154. boost::detail::sp_enable_shared_from_this( this, p, p );
  155. }
  156. // As above, but with allocator. A's copy constructor shall not throw.
  157. template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
  158. {
  159. boost::detail::sp_enable_shared_from_this( this, p, p );
  160. }
  161. // generated copy constructor, destructor are fine
  162. template<class Y>
  163. explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
  164. {
  165. // it is now safe to copy r.px, as pn(r.pn) did not throw
  166. px = r.px;
  167. }
  168. template<class Y>
  169. shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
  170. {
  171. if( !pn.empty() )
  172. {
  173. px = r.px;
  174. }
  175. }
  176. template<class Y>
  177. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
  178. shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
  179. #else
  180. shared_ptr( shared_ptr<Y> const & r )
  181. #endif
  182. : px( r.px ), pn( r.pn ) // never throws
  183. {
  184. }
  185. // aliasing
  186. template< class Y >
  187. shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
  188. {
  189. }
  190. template<class Y>
  191. shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
  192. {
  193. }
  194. template<class Y>
  195. shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
  196. {
  197. }
  198. template<class Y>
  199. shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
  200. {
  201. if(px == 0) // need to allocate new counter -- the cast failed
  202. {
  203. pn = boost::detail::shared_count();
  204. }
  205. }
  206. template<class Y>
  207. shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
  208. {
  209. if(px == 0)
  210. {
  211. boost::throw_exception(std::bad_cast());
  212. }
  213. }
  214. #ifndef BOOST_NO_AUTO_PTR
  215. template<class Y>
  216. explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
  217. {
  218. Y * tmp = r.get();
  219. pn = boost::detail::shared_count(r);
  220. boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
  221. }
  222. #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  223. template<class Ap>
  224. explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
  225. {
  226. typename Ap::element_type * tmp = r.get();
  227. pn = boost::detail::shared_count( r );
  228. boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
  229. }
  230. #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  231. #endif // BOOST_NO_AUTO_PTR
  232. // assignment
  233. shared_ptr & operator=( shared_ptr const & r ) // never throws
  234. {
  235. this_type(r).swap(*this);
  236. return *this;
  237. }
  238. #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
  239. template<class Y>
  240. shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
  241. {
  242. this_type(r).swap(*this);
  243. return *this;
  244. }
  245. #endif
  246. #ifndef BOOST_NO_AUTO_PTR
  247. template<class Y>
  248. shared_ptr & operator=( std::auto_ptr<Y> & r )
  249. {
  250. this_type(r).swap(*this);
  251. return *this;
  252. }
  253. #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  254. template<class Ap>
  255. typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
  256. {
  257. this_type( r ).swap( *this );
  258. return *this;
  259. }
  260. #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  261. #endif // BOOST_NO_AUTO_PTR
  262. // Move support
  263. #if defined( BOOST_HAS_RVALUE_REFS )
  264. shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
  265. {
  266. pn.swap( r.pn );
  267. r.px = 0;
  268. }
  269. template<class Y>
  270. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
  271. shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
  272. #else
  273. shared_ptr( shared_ptr<Y> && r )
  274. #endif
  275. : px( r.px ), pn() // never throws
  276. {
  277. pn.swap( r.pn );
  278. r.px = 0;
  279. }
  280. shared_ptr & operator=( shared_ptr && r ) // never throws
  281. {
  282. this_type( std::move( r ) ).swap( *this );
  283. return *this;
  284. }
  285. template<class Y>
  286. shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
  287. {
  288. this_type( std::move( r ) ).swap( *this );
  289. return *this;
  290. }
  291. #endif
  292. void reset() // never throws in 1.30+
  293. {
  294. this_type().swap(*this);
  295. }
  296. template<class Y> void reset(Y * p) // Y must be complete
  297. {
  298. BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
  299. this_type(p).swap(*this);
  300. }
  301. template<class Y, class D> void reset( Y * p, D d )
  302. {
  303. this_type( p, d ).swap( *this );
  304. }
  305. template<class Y, class D, class A> void reset( Y * p, D d, A a )
  306. {
  307. this_type( p, d, a ).swap( *this );
  308. }
  309. template<class Y> void reset( shared_ptr<Y> const & r, T * p )
  310. {
  311. this_type( r, p ).swap( *this );
  312. }
  313. reference operator* () const // never throws
  314. {
  315. BOOST_ASSERT(px != 0);
  316. return *px;
  317. }
  318. T * operator-> () const // never throws
  319. {
  320. BOOST_ASSERT(px != 0);
  321. return px;
  322. }
  323. T * get() const // never throws
  324. {
  325. return px;
  326. }
  327. // implicit conversion to "bool"
  328. #include <boost/smart_ptr/detail/operator_bool.hpp>
  329. bool unique() const // never throws
  330. {
  331. return pn.unique();
  332. }
  333. long use_count() const // never throws
  334. {
  335. return pn.use_count();
  336. }
  337. void swap(shared_ptr<T> & other) // never throws
  338. {
  339. std::swap(px, other.px);
  340. pn.swap(other.pn);
  341. }
  342. template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
  343. {
  344. return pn < rhs.pn;
  345. }
  346. void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
  347. {
  348. return pn.get_deleter( ti );
  349. }
  350. bool _internal_equiv( shared_ptr const & r ) const
  351. {
  352. return px == r.px && pn == r.pn;
  353. }
  354. // Tasteless as this may seem, making all members public allows member templates
  355. // to work in the absence of member template friends. (Matthew Langston)
  356. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  357. private:
  358. template<class Y> friend class shared_ptr;
  359. template<class Y> friend class weak_ptr;
  360. #endif
  361. T * px; // contained pointer
  362. boost::detail::shared_count pn; // reference counter
  363. }; // shared_ptr
  364. template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
  365. {
  366. return a.get() == b.get();
  367. }
  368. template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
  369. {
  370. return a.get() != b.get();
  371. }
  372. #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
  373. // Resolve the ambiguity between our op!= and the one in rel_ops
  374. template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
  375. {
  376. return a.get() != b.get();
  377. }
  378. #endif
  379. template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
  380. {
  381. return a._internal_less(b);
  382. }
  383. template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
  384. {
  385. a.swap(b);
  386. }
  387. template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
  388. {
  389. return shared_ptr<T>(r, boost::detail::static_cast_tag());
  390. }
  391. template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
  392. {
  393. return shared_ptr<T>(r, boost::detail::const_cast_tag());
  394. }
  395. template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
  396. {
  397. return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
  398. }
  399. // shared_*_cast names are deprecated. Use *_pointer_cast instead.
  400. template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
  401. {
  402. return shared_ptr<T>(r, boost::detail::static_cast_tag());
  403. }
  404. template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
  405. {
  406. return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
  407. }
  408. template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
  409. {
  410. return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
  411. }
  412. template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
  413. {
  414. BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
  415. return shared_static_cast<T>(r);
  416. }
  417. // get_pointer() enables boost::mem_fn to recognize shared_ptr
  418. template<class T> inline T * get_pointer(shared_ptr<T> const & p)
  419. {
  420. return p.get();
  421. }
  422. // operator<<
  423. #if !defined(BOOST_NO_IOSTREAM)
  424. #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
  425. template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
  426. {
  427. os << p.get();
  428. return os;
  429. }
  430. #else
  431. // in STLport's no-iostreams mode no iostream symbols can be used
  432. #ifndef _STLP_NO_IOSTREAMS
  433. # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
  434. // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
  435. using std::basic_ostream;
  436. template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
  437. # else
  438. template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
  439. # endif
  440. {
  441. os << p.get();
  442. return os;
  443. }
  444. #endif // _STLP_NO_IOSTREAMS
  445. #endif // __GNUC__ < 3
  446. #endif // !defined(BOOST_NO_IOSTREAM)
  447. // get_deleter
  448. #if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
  449. ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
  450. ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
  451. // g++ 2.9x doesn't allow static_cast<X const *>(void *)
  452. // apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
  453. template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
  454. {
  455. void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
  456. return const_cast<D *>(static_cast<D const *>(q));
  457. }
  458. #else
  459. template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
  460. {
  461. return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
  462. }
  463. #endif
  464. // atomic access
  465. #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
  466. template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
  467. {
  468. return false;
  469. }
  470. template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
  471. {
  472. boost::detail::spinlock_pool<2>::scoped_lock lock( p );
  473. return *p;
  474. }
  475. template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
  476. {
  477. return atomic_load( p );
  478. }
  479. template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
  480. {
  481. boost::detail::spinlock_pool<2>::scoped_lock lock( p );
  482. p->swap( r );
  483. }
  484. template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
  485. {
  486. atomic_store( p, r ); // std::move( r )
  487. }
  488. template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
  489. {
  490. boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
  491. sp.lock();
  492. p->swap( r );
  493. sp.unlock();
  494. return r; // return std::move( r )
  495. }
  496. template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
  497. {
  498. return atomic_exchange( p, r ); // std::move( r )
  499. }
  500. template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
  501. {
  502. boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
  503. sp.lock();
  504. if( p->_internal_equiv( *v ) )
  505. {
  506. p->swap( w );
  507. sp.unlock();
  508. return true;
  509. }
  510. else
  511. {
  512. shared_ptr<T> tmp( *p );
  513. sp.unlock();
  514. tmp.swap( *v );
  515. return false;
  516. }
  517. }
  518. template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
  519. {
  520. return atomic_compare_exchange( p, v, w ); // std::move( w )
  521. }
  522. #endif
  523. } // namespace boost
  524. #ifdef BOOST_MSVC
  525. # pragma warning(pop)
  526. #endif
  527. #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
  528. #endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED