35 #if __GNUC__ > 3 && __GNUC_MINOR__ > 6
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
41 #pragma clang diagnostic push
42 #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
66template<
typename T >
class shared_ptr;
67template<
typename T >
class weak_ptr;
68template<
typename T >
class enable_shared_from_this;
69template<
typename T >
class enable_shared_from_this2;
77 :
public std::exception
80 inline virtual char const *
what()
const throw();
87 return "bad_weak_ptr";
98class abstract_ctrl_block
109 inline
void add_ref();
110 inline
bool add_ref_lock();
111 inline
void weak_add_ref() throw();
112 virtual
void * get_deleter( std::type_info const & ti ) = 0;
113 inline
void release() throw();
114 inline
void weak_release() throw();
115 virtual
void dispose() throw() = 0;
116 inline virtual
void destroy() throw();
119 inline
long use_count() const throw();
131 assert( n_shared_ptrs == 0 || n_weak_ptrs >= 1 );
134abstract_ctrl_block::abstract_ctrl_block()
157 return n_shared_ptrs ? ++n_shared_ptrs :
false;
171 if( 0 == --n_shared_ptrs )
179 if( 0 == --n_weak_ptrs )
186 assert( n_weak_ptrs == 0 );
194 return n_shared_ptrs;
205template<
typename P >
207 :
public abstract_ctrl_block
216 inline
void * operator new ( std::
size_t );
217 inline
void operator delete (
void * );
229template< typename P >
235template<
typename P >
239template<
typename P >
246template<
typename P >
253template<
typename P >
255 ctrl_block_p<P>::operator
new ( std::size_t )
257 return std::allocator<this_type>().allocate( 1 );
260template<
typename P >
262 ctrl_block_p<P>::operator
delete (
void * p )
264 std::allocator<this_type>().deallocate(
static_cast<this_type*
>(p), 1 );
273 typedef ctrl_block_pd<P,D> this_type;
280 inline
void * operator new ( std::
size_t );
281 inline
void operator delete (
void * );
284 inline virtual
void * get_deleter( std::type_info const & );
285 inline virtual
void dispose() throw();
295template< typename P, typename
D >
302template<
typename P,
typename D >
306template<
typename P,
typename D >
308 ctrl_block_pd<P,D>::dispose() throw()
310 deleter( owned_ptr );
313template<
typename P,
typename D >
315 ctrl_block_pd<P,D>::get_deleter( std::type_info
const & ti )
317 return ti ==
typeid(
D) ? &
reinterpret_cast<char&
>( deleter ) : 0;
320template<
typename P,
typename D >
322 ctrl_block_pd<P,D>::operator
new ( std::size_t )
324 return std::allocator<this_type>().allocate( 1 );
327template<
typename P,
typename D >
329 ctrl_block_pd<P,D>::operator
delete (
void * p )
331 std::allocator<this_type>().deallocate(
static_cast<this_type*
>(p), 1 );
339 :
public abstract_ctrl_block
341 typedef ctrl_block_pda<P,D,A> this_type;
348 inline virtual
void * get_deleter( std::type_info const & );
349 inline virtual
void dispose() throw();
350 inline virtual
void destroy() throw();
361template< typename P, typename
D, typename A >
369template<
typename P,
typename D,
typename A >
373template<
typename P,
typename D,
typename A >
375 ctrl_block_pda<P,D,A>::dispose() throw()
377 deleter( owned_ptr );
380template<
typename P,
typename D,
typename A >
382 ctrl_block_pda<P,D,A>::destroy() throw()
384 typename A::template rebind< this_type >::other this_allocator( allocator );
386 this_allocator.destroy(
this );
387 this_allocator.deallocate(
this, 1 );
390template<
typename P,
typename D,
typename A >
392 ctrl_block_pda<P,D,A>::get_deleter( std::type_info
const & ti )
394 return ti ==
typeid(
D ) ? &
reinterpret_cast<char&
>( deleter ) : 0;
402class shared_ctrl_handle;
403class weak_ctrl_handle;
405struct sp_nothrow_tag { };
407class shared_ctrl_handle
409 friend class weak_ctrl_handle;
413 template< typename P >
416 template< typename P, typename
D >
418 template< typename P, typename
D, typename A >
420 template< typename P >
437 inline
void * get_deleter( std::type_info const & ) const;
438 inline
bool unique() const throw();
439 inline
bool empty() const throw();
440 inline
long use_count() const throw();
460template<
typename P >
461 shared_ctrl_handle::shared_ctrl_handle( P * p )
475template<
typename P,
typename D >
482 acb_ptr =
new ctrl_block_pd<P,D>(p, d);
490template<
typename P,
typename D,
typename A >
494 typedef ctrl_block_pda<P,D,A>
496 typedef typename A::template rebind<ctrl_block>::other
497 ctrl_block_allocator;
498 ctrl_block_allocator cba(
a );
502 acb_ptr = cba.allocate( 1 );
503 new(
static_cast<void*
>(acb_ptr) ) ctrl_block(p, d,
a);
509 cba.deallocate(
static_cast<ctrl_block*
>( acb_ptr ), 1 );
514template<
typename P >
516 : acb_ptr( new ctrl_block_p<P>( p.get() ) )
530 abstract_ctrl_block * tmp = other.acb_ptr;
531 other.acb_ptr = acb_ptr;
536 : acb_ptr( other.acb_ptr )
545 abstract_ctrl_block * tmp = other.acb_ptr;
549 if( tmp != 0 ) tmp->add_ref();
550 if( acb_ptr != 0 ) acb_ptr->release();
578 return acb_ptr == 0 ? 0L : acb_ptr->
use_count();
582 operator == ( shared_ctrl_handle
const & lhs, shared_ctrl_handle
const & rhs )
584 return lhs.acb_ptr == rhs.acb_ptr;
588 operator < ( shared_ctrl_handle
const & lhs, shared_ctrl_handle
const & rhs )
590 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
593class weak_ctrl_handle
634 : acb_ptr( other.acb_ptr )
649 abstract_ctrl_block * tmp = other.acb_ptr;
650 other.acb_ptr = acb_ptr;
655 : acb_ptr( other.acb_ptr )
664 abstract_ctrl_block * tmp = other.acb_ptr;
668 if( tmp != 0 ) tmp->weak_add_ref();
679 abstract_ctrl_block * tmp = other.acb_ptr;
683 if( tmp != 0 ) tmp->weak_add_ref();
700 return acb_ptr == 0 ? 0L : acb_ptr->
use_count();
706 return lhs.acb_ptr == rhs.acb_ptr;
712 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
716 : acb_ptr( other.acb_ptr )
719 throw bad_weak_ptr();
724 : acb_ptr( other.acb_ptr )
735struct static_cast_tag { };
736struct const_cast_tag { };
737struct dynamic_cast_tag { };
738struct polymorphic_cast_tag { };
745template<
typename T >
746 struct shared_ptr_traits
752 struct shared_ptr_traits<void>
758 struct shared_ptr_traits<void const>
764 struct shared_ptr_traits<void volatile>
770 struct shared_ptr_traits<void const volatile>
780template<
typename X,
typename Y,
typename T >
784 , enable_shared_from_this<T>
const * pe
788 pe->_internal_accept_owner( ppx,
const_cast<Y*
>( py ) );
791template<
typename X,
typename Y,
typename T >
795 , enable_shared_from_this2<T>
const * pe
799 pe->_internal_accept_owner( ppx,
const_cast<Y*
>( py ) );
813template<
typename P >
827 template< typename P2 >
830 template< typename P2, typename
D >
832 template< typename P2, typename
D, typename A >
840 template< typename P2 >
843 template< typename P2 >
845 template< typename P2 >
847 template< typename P2 >
849 template< typename P2 >
851 template< typename P2 >
853 template< typename P2 >
855 template< typename P2 >
858 template< typename AP >
863 template< typename P2 >
868 template< typename P2 >
870 template< typename P2 >
872 template< typename AP >
878 template< typename P2 >
880 template< typename P2, typename
D >
882 template< typename P2, typename
D, typename A >
884 template< typename P2 >
888 inline operator
bool () const throw();
889 inline reference operator * () const throw();
890 inline P * operator -> () const throw();
893 inline P *
get() const throw();
898 template< typename P2 >
906 sp::shared_ctrl_handle pn;
910template< typename P, typename P2 >
912template< typename P, typename P2 >
914template< typename P, typename P2 >
917template< typename P >
920template< typename P, typename P2 >
922template< typename P, typename P2 >
924template< typename P, typename P2 >
927template< typename P >
929template< typename
D, typename P >
932template< typename C, typename T, typename P >
933 inline std::basic_ostream<C,T> & operator << ( std::basic_ostream<C,T> &
937template< typename P >
943template<
typename P >
944template<
typename P2 >
952template<
typename P >
953template<
typename P2,
typename D >
961template<
typename P >
962template<
typename P2,
typename D,
typename A >
970template<
typename P >
974 std::swap( px, other.px );
978template<
typename P >
982 this_type( other ).swap( *
this );
986template<
typename P >
987template<
typename P2 >
995template<
typename P >
996template<
typename P2 >
1001 , pn( other.pn, sp::sp_nothrow_tag() )
1007template<
typename P >
1008template<
typename P2 >
1016template<
typename P >
1017template<
typename P2 >
1019 , sp::static_cast_tag
1021 : px( static_cast<element_type*>( other.px ) )
1025template<
typename P >
1026template<
typename P2 >
1028 , sp::const_cast_tag
1030 : px( const_cast<element_type*>( other.px ) )
1034template<
typename P >
1035template<
typename P2 >
1037 , sp::dynamic_cast_tag
1039 : px( dynamic_cast<element_type*>( other.px ) )
1043 pn = sp::shared_ctrl_handle();
1046template<
typename P >
1047template<
typename P2 >
1049 , sp::polymorphic_cast_tag
1051 : px( dynamic_cast<element_type*>( other.px ) )
1055 throw std::bad_cast();
1058template<
typename P >
1059template<
typename P2 >
1064 P2 * tmp = other.get();
1065 pn = sp::shared_ctrl_handle( other );
1069template<
typename P >
1070template<
typename AP >
1072 ,
typename enable_if_auto_ptr<AP,void*>::type
1077 typename AP::element_type * tmp = other.get();
1078 pn = sp::shared_ctrl_handle( other );
1082template<
typename P >
1083template<
typename P2 >
1085 ,
typename enable_if_ptr_convertible<P2,P,void*>::type
1091template<
typename P >
1092template<
typename P2 >
1096 this_type( other ).swap( *
this );
1100template<
typename P >
1101template<
typename P2 >
1105 this_type( other ).swap( *
this );
1109template<
typename P >
1110template<
typename AP >
1111 typename enable_if_auto_ptr< AP, shared_ptr<P> & >::type
1114 this_type( other ).swap( *
this );
1118template<
typename P >
1122 this_type().swap( *
this );
1125template<
typename P >
1126template<
typename P2 >
1130 assert( p == 0 || p != px );
1131 this_type( p ).swap( *
this );
1134template<
typename P >
1135template<
typename P2,
typename D >
1139 this_type( p, d ).swap( *
this );
1142template<
typename P >
1143template<
typename P2,
typename D,
typename A >
1147 this_type( p, d,
a ).swap( *
this );
1150template<
typename P >
1151template<
typename P2 >
1155 this_type( other, p ).swap( *
this );
1158template<
typename P >
1159 shared_ptr<P>::operator bool ()
const throw()
1164template<
typename P >
1173template<
typename P >
1181template<
typename P >
1188template<
typename P >
1195template<
typename P >
1199 return pn.use_count();
1202template<
typename P >
1203template<
typename P2 >
1210template<
typename P >
1214 return pn.get_deleter( ti );
1217template<
typename P >
1221 return px == other.px && pn == other.pn;
1224template<
typename P,
typename P2 >
1226 operator == ( shared_ptr<P>
const &
a, shared_ptr<P2>
const &
b )
1228 return a.get() ==
b.get();
1231template<
typename P,
typename P2 >
1233 operator != ( shared_ptr<P>
const &
a, shared_ptr<P2>
const &
b )
1235 return a.get() !=
b.get();
1238template<
typename P,
typename P2 >
1240 operator < ( shared_ptr<P>
const &
a, shared_ptr<P2>
const &
b )
1242 return a._internal_less(
b);
1245template<
typename P >
1247 swap( shared_ptr<P> &
a, shared_ptr<P> &
b )
1252template<
typename P,
typename P2 >
1256 return shared_ptr<P>( other, sp::static_cast_tag() );
1259template<
typename P,
typename P2 >
1263 return shared_ptr<P>( other, sp::const_cast_tag() );
1266template<
typename P,
typename P2 >
1270 return shared_ptr<P>( other, sp::dynamic_cast_tag() );
1273template<
typename P >
1280template<
typename D,
typename P >
1284 return static_cast<D*
>( p._internal_get_deleter(
typeid(
D)) );
1287template<
typename C,
typename T,
typename P >
1288 std::basic_ostream<C,T> &
1289 operator << ( std::basic_ostream<C,T> & os, shared_ptr<P>
const & p )
1300template<
typename P >
1306 template<
typename >
friend class weak_ptr;
1316 template< typename P2 >
1321 template< typename P2 >
1326 template< typename P2 >
1328 template< typename P2 >
1340 template< typename P2 >
1345 sp::weak_ctrl_handle pn;
1349template< typename P, typename P2 >
1352template< typename P >
1355template< typename P >
1361template<
typename P >
1362template<
typename P2 >
1366 : px( r.lock().get() )
1370template<
typename P >
1371template<
typename P2 >
1373 ,
typename enable_if_ptr_convertible<P2,P,void*>::type
1379template<
typename P >
1380template<
typename P2 >
1384 px = r.lock().get();
1389template<
typename P >
1390template<
typename P2 >
1399template<
typename P >
1406template<
typename P >
1413template<
typename P >
1420template<
typename P >
1427template<
typename P >
1431 this_type().swap(*
this);
1434template<
typename P >
1438 std::swap(px, other.px);
1442template<
typename P >
1450template<
typename P >
1451template<
typename P2 >
1458template<
typename P,
typename P2 >
1462 return a._internal_less(
b);
1465template<
typename P >
1477struct do_nothing_deleter {
1478 inline void operator () (
void const * )
const;
1490 #if __GNUC__ > 3 && __GNUC_MINOR__ > 6
1491 #pragma GCC diagnostic pop
1495 #pragma clang diagnostic pop
1509template<
typename T >
1510 class enable_shared_from_this
1513 enable_shared_from_this()
1516 ~enable_shared_from_this()
1519 enable_shared_from_this( enable_shared_from_this
const & )
1522 enable_shared_from_this &
1523 operator = ( enable_shared_from_this
const & )
1532 shared_ptr<T> p( weak_this_ );
1533 assert( p.get() ==
this );
1538 shared_from_this()
const
1540 shared_ptr<T const> p( weak_this_ );
1541 assert( p.get() ==
this );
1548 template<
typename X,
typename Y >
1550 _internal_accept_owner( shared_ptr<X>
const * ppx,
Y * py )
const
1552 if( weak_this_.expired() )
1553 weak_this_ = shared_ptr<T>( *ppx, py );
1557 mutable weak_ptr<T> weak_this_;
1566class esft2_deleter_wrapper
1569 shared_ptr<void> deleter_;
1572 esft2_deleter_wrapper()
1575 template<
typename T >
1577 set_deleter( shared_ptr<T>
const & deleter )
1582 template<
typename T >
1586 assert( deleter_.use_count() <= 1 );
1593template<
typename T >
1594 class enable_shared_from_this2
1598 enable_shared_from_this2()
1601 enable_shared_from_this2( enable_shared_from_this2
const & )
1604 enable_shared_from_this2 & operator = ( enable_shared_from_this2
const & )
1609 ~enable_shared_from_this2()
1611 assert( shared_this_.use_count() <= 1 );
1615 mutable weak_ptr<T> weak_this_;
1616 mutable shared_ptr<T> shared_this_;
1624 return shared_ptr<T>( weak_this_ );
1628 shared_from_this()
const
1631 return shared_ptr<T>( weak_this_ );
1636 void init_weak_once()
const
1638 if( weak_this_._empty() )
1640 shared_this_.reset(
static_cast< T*
>( 0 )
1641 , detail::esft2_deleter_wrapper()
1643 weak_this_ = shared_this_;
1650 template<
typename X,
typename Y >
1652 _internal_accept_owner( shared_ptr<X> * ppx,
Y * py )
const
1656 if( weak_this_.use_count() == 0 )
1657 weak_this_ = shared_ptr<T>( *ppx, py );
1658 else if( shared_this_.use_count() != 0 )
1660 assert( ppx->unique() );
1662 detail::esft2_deleter_wrapper * pd
1663 = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
1666 pd->set_deleter( *ppx );
1668 ppx->reset( shared_this_, ppx->get() );
1669 shared_this_.reset();
virtual char const * what() const
virtual char const * what() const
bool _internal_less(shared_ptr< P2 > const &) const
reference operator*() const
bool _internal_equiv(shared_ptr const &) const
shared_ptr & operator=(shared_ptr const &)
void * _internal_get_deleter(std::type_info const &) const
void swap(shared_ptr< P > &)
void class_invariant() const
virtual void * get_deleter(std::type_info const &ti)=0
virtual ~abstract_ctrl_block()
virtual void * get_deleter(std::type_info const &)
ctrl_block_pda(P *, D, A)
void swap(shared_ctrl_handle &)
void * get_deleter(std::type_info const &) const
shared_ctrl_handle & operator=(shared_ctrl_handle const &)
void swap(weak_ctrl_handle &)
friend bool operator==(weak_ctrl_handle const &, weak_ctrl_handle const &)
friend bool operator<(weak_ctrl_handle const &, weak_ctrl_handle const &)
friend class shared_ctrl_handle
weak_ctrl_handle & operator=(shared_ctrl_handle const &)
void swap(this_type &other)
bool _internal_less(weak_ptr< P2 > const &rhs) const
weak_ptr & operator=(weak_ptr< P2 > const &r)
shared_ptr< P > lock() const
void _internal_assign(P *px2, sp::shared_ctrl_handle const &pn2)
bool operator==(shared_ctrl_handle const &lhs, shared_ctrl_handle const &rhs)
void sp_enable_shared_from_this(shared_ptr< X > const *ppx, Y const *py, enable_shared_from_this< T > const *pe)
bool operator<(shared_ctrl_handle const &lhs, shared_ctrl_handle const &rhs)
shared_ptr< P > dynamic_pointer_cast(shared_ptr< P2 > const &)
P * get_pointer(shared_ptr< P > const &)
bool operator!=(const HepRotation &r, const HepLorentzRotation <)
void swap(shared_ptr< P > &, shared_ptr< P > &)
shared_ptr< P > static_pointer_cast(shared_ptr< P2 > const &)
std::ostream & operator<<(std::ostream &os, const HepAxisAngle &aa)
shared_ptr< P > const_pointer_cast(shared_ptr< P2 > const &)
bool operator==(const HepRotation &r, const HepLorentzRotation <)
bool operator<(const HepRotation &r, const HepLorentzRotation <)
D * get_deleter(shared_ptr< P > const &)
void operator()(void const *) const