34 #include "CLHEP/Utility/defs.h"
35 #include "CLHEP/Utility/noncopyable.h"
36 #include "CLHEP/Utility/type_traits.h"
55 template<
typename T >
class shared_ptr;
56 template<
typename T >
class weak_ptr;
57 template<
typename T >
class enable_shared_from_this;
58 template<
typename T >
class enable_shared_from_this2;
66 :
public std::exception
69 inline virtual char const *
what()
const throw();
74 bad_weak_ptr::
what() const throw()
76 return "bad_weak_ptr";
87 class abstract_ctrl_block
91 inline void class_invariant()
const throw();
94 inline abstract_ctrl_block();
95 inline virtual ~abstract_ctrl_block() throw();
98 inline
void add_ref();
99 inline
bool add_ref_lock();
100 inline
void weak_add_ref() throw();
101 virtual
void *
get_deleter( std::type_info const & ti ) = 0;
102 inline
void release() throw();
103 inline
void weak_release() throw();
104 virtual
void dispose() throw() = 0;
105 inline virtual
void destroy() throw();
108 inline
long use_count() const throw();
118 abstract_ctrl_block::class_invariant() const throw()
120 assert( n_shared_ptrs == 0 || n_weak_ptrs >= 1 );
123 abstract_ctrl_block::abstract_ctrl_block()
130 abstract_ctrl_block::~abstract_ctrl_block() throw()
136 abstract_ctrl_block::add_ref()
143 abstract_ctrl_block::add_ref_lock()
146 return n_shared_ptrs ? ++n_shared_ptrs :
false;
150 abstract_ctrl_block::weak_add_ref() throw()
157 abstract_ctrl_block::release() throw()
160 if( 0 == --n_shared_ptrs )
161 dispose(), weak_release();
165 abstract_ctrl_block::weak_release() throw()
168 if( 0 == --n_weak_ptrs )
173 abstract_ctrl_block::destroy() throw()
175 assert( n_weak_ptrs == 0 );
180 abstract_ctrl_block::use_count()
const throw()
183 return n_shared_ptrs;
194 template<
typename P >
196 :
public abstract_ctrl_block
198 typedef ctrl_block_p<P> this_type;
201 inline explicit ctrl_block_p( P * );
202 inline ~ctrl_block_p() throw();
205 inline
void * operator new ( std::
size_t );
206 inline
void operator delete (
void * );
209 inline virtual
void *
get_deleter( std::type_info const & );
210 inline virtual
void dispose() throw();
218 template< typename P >
219 ctrl_block_p<P>::ctrl_block_p( P * p )
220 : abstract_ctrl_block( )
224 template<
typename P >
225 ctrl_block_p<P>::~ctrl_block_p() throw()
228 template<
typename P >
230 ctrl_block_p<P>::dispose() throw()
235 template<
typename P >
242 template<
typename P >
244 ctrl_block_p<P>::operator
new ( std::size_t )
246 return std::allocator<this_type>().allocate( 1 );
249 template<
typename P >
251 ctrl_block_p<P>::operator
delete (
void * p )
253 std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
260 :
public abstract_ctrl_block
262 typedef ctrl_block_pd<P,D> this_type;
265 inline ctrl_block_pd( P *,
D );
266 inline ~ctrl_block_pd() throw();
269 inline
void * operator new ( std::
size_t );
270 inline
void operator delete (
void * );
273 inline virtual
void *
get_deleter( std::type_info const & );
274 inline virtual
void dispose() throw();
284 template< typename P, typename
D >
285 ctrl_block_pd<P,
D>::ctrl_block_pd( P * p,
D d )
286 : abstract_ctrl_block( )
291 template<
typename P,
typename D >
292 ctrl_block_pd<P,D>::~ctrl_block_pd() throw()
295 template<
typename P,
typename D >
297 ctrl_block_pd<P,D>::dispose() throw()
302 template<
typename P,
typename D >
306 return ti ==
typeid(
D) ? &reinterpret_cast<char&>(
deleter ) : 0;
309 template<
typename P,
typename D >
311 ctrl_block_pd<P,D>::operator
new ( std::size_t )
313 return std::allocator<this_type>().allocate( 1 );
316 template<
typename P,
typename D >
318 ctrl_block_pd<P,D>::operator
delete (
void * p )
320 std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
328 :
public abstract_ctrl_block
330 typedef ctrl_block_pda<P,D,A> this_type;
333 inline ctrl_block_pda( P *,
D, A );
334 inline ~ctrl_block_pda() throw();
337 inline virtual
void *
get_deleter( std::type_info const & );
338 inline virtual
void dispose() throw();
339 inline virtual
void destroy() throw();
350 template< typename P, typename
D, typename A >
351 ctrl_block_pda<P,D,A>::ctrl_block_pda( P * p, D d, A
a )
352 : abstract_ctrl_block( )
358 template<
typename P,
typename D,
typename A >
359 ctrl_block_pda<P,D,A>::~ctrl_block_pda() throw()
362 template<
typename P,
typename D,
typename A >
364 ctrl_block_pda<P,D,A>::dispose() throw()
369 template<
typename P,
typename D,
typename A >
371 ctrl_block_pda<P,D,A>::destroy() throw()
373 typename A::template rebind< this_type >::other this_allocator( allocator );
375 this_allocator.destroy(
this );
376 this_allocator.deallocate(
this, 1 );
379 template<
typename P,
typename D,
typename A >
383 return ti ==
typeid(
D ) ? &reinterpret_cast<char&>(
deleter ) : 0;
391 class shared_ctrl_handle;
392 class weak_ctrl_handle;
394 struct sp_nothrow_tag { };
396 class shared_ctrl_handle
398 friend class weak_ctrl_handle;
401 inline shared_ctrl_handle() throw();
402 template< typename P >
404 shared_ctrl_handle( P * );
405 template< typename P, typename
D >
406 inline shared_ctrl_handle( P *,
D );
407 template< typename P, typename D, typename A >
408 inline shared_ctrl_handle( P *, D, A );
409 template< typename P >
411 shared_ctrl_handle( std::auto_ptr<P> & );
412 inline ~shared_ctrl_handle() throw();
415 inline
void swap( shared_ctrl_handle & ) throw();
416 inline shared_ctrl_handle( shared_ctrl_handle const & ) throw();
417 inline shared_ctrl_handle &
418 operator = ( shared_ctrl_handle const & ) throw();
422 shared_ctrl_handle( weak_ctrl_handle const & );
423 inline shared_ctrl_handle( weak_ctrl_handle const &, sp_nothrow_tag );
426 inline
void *
get_deleter( std::type_info const & ) const;
427 inline
bool unique() const throw();
428 inline
bool empty() const throw();
429 inline
long use_count() const throw();
434 operator == ( shared_ctrl_handle const &, shared_ctrl_handle const & );
437 operator < ( shared_ctrl_handle const &, shared_ctrl_handle const & );
441 abstract_ctrl_block * acb_ptr;
445 shared_ctrl_handle::shared_ctrl_handle() throw()
449 template<
typename P >
450 shared_ctrl_handle::shared_ctrl_handle( P * p )
456 acb_ptr =
new ctrl_block_p<P>(p);
464 template<
typename P,
typename D >
465 shared_ctrl_handle::shared_ctrl_handle( P * p,
D d )
471 acb_ptr =
new ctrl_block_pd<P,D>(p, d);
479 template<
typename P,
typename D,
typename A >
480 shared_ctrl_handle::shared_ctrl_handle( P * p,
D d, A
a )
483 typedef ctrl_block_pda<P,D,A>
485 typedef typename A::template rebind<ctrl_block>::other
486 ctrl_block_allocator;
487 ctrl_block_allocator cba( a );
491 acb_ptr = cba.allocate( 1 );
492 new(
static_cast<void*
>(acb_ptr) ) ctrl_block(p, d, a);
498 cba.deallocate( static_cast<ctrl_block*>( acb_ptr ), 1 );
503 template<
typename P >
504 shared_ctrl_handle::shared_ctrl_handle( std::auto_ptr<P> & p )
505 : acb_ptr( new ctrl_block_p<P>( p.get() ) )
510 shared_ctrl_handle::~shared_ctrl_handle() throw()
519 abstract_ctrl_block * tmp = other.acb_ptr;
520 other.acb_ptr = acb_ptr;
524 shared_ctrl_handle::shared_ctrl_handle( shared_ctrl_handle
const & other )
throw()
525 : acb_ptr( other.acb_ptr )
532 shared_ctrl_handle::operator = ( shared_ctrl_handle
const & other )
throw()
534 abstract_ctrl_block * tmp = other.acb_ptr;
538 if( tmp != 0 ) tmp->add_ref();
539 if( acb_ptr != 0 ) acb_ptr->release();
549 return acb_ptr ? acb_ptr->get_deleter( ti ) : 0;
553 shared_ctrl_handle::unique()
const throw()
555 return 1L == use_count();
559 shared_ctrl_handle::empty()
const throw()
565 shared_ctrl_handle::use_count()
const throw()
567 return acb_ptr == 0 ? 0L : acb_ptr->use_count();
571 operator == ( shared_ctrl_handle
const & lhs, shared_ctrl_handle
const & rhs )
573 return lhs.acb_ptr == rhs.acb_ptr;
577 operator < ( shared_ctrl_handle
const & lhs, shared_ctrl_handle
const & rhs )
579 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
582 class weak_ctrl_handle
584 friend class shared_ctrl_handle;
588 inline weak_ctrl_handle() throw();
589 inline weak_ctrl_handle( shared_ctrl_handle const & ) throw();
590 inline ~weak_ctrl_handle() throw();
593 inline
void swap( weak_ctrl_handle & ) throw();
594 inline weak_ctrl_handle( weak_ctrl_handle const & ) throw();
595 inline weak_ctrl_handle & operator = ( shared_ctrl_handle const & ) throw();
598 inline weak_ctrl_handle & operator = ( weak_ctrl_handle const & ) throw();
601 inline
bool empty() const throw();
602 inline
long use_count() const throw();
607 operator == ( weak_ctrl_handle const &, weak_ctrl_handle const & );
610 operator < ( weak_ctrl_handle const &, weak_ctrl_handle const & );
614 abstract_ctrl_block * acb_ptr;
618 weak_ctrl_handle::weak_ctrl_handle() throw()
622 weak_ctrl_handle::weak_ctrl_handle( shared_ctrl_handle
const & other )
throw()
623 : acb_ptr( other.acb_ptr )
626 acb_ptr->weak_add_ref();
629 weak_ctrl_handle::~weak_ctrl_handle() throw()
632 acb_ptr->weak_release();
638 abstract_ctrl_block * tmp = other.acb_ptr;
639 other.acb_ptr = acb_ptr;
643 weak_ctrl_handle::weak_ctrl_handle( weak_ctrl_handle
const & other )
throw()
644 : acb_ptr( other.acb_ptr )
647 acb_ptr->weak_add_ref();
651 weak_ctrl_handle::operator = ( shared_ctrl_handle
const & other )
throw()
653 abstract_ctrl_block * tmp = other.acb_ptr;
657 if( tmp != 0 ) tmp->weak_add_ref();
658 if( acb_ptr != 0 ) acb_ptr->weak_release();
666 weak_ctrl_handle::operator = ( weak_ctrl_handle
const & other )
throw()
668 abstract_ctrl_block * tmp = other.acb_ptr;
672 if( tmp != 0 ) tmp->weak_add_ref();
673 if( acb_ptr != 0 ) acb_ptr->weak_release();
681 weak_ctrl_handle::empty()
const throw()
687 weak_ctrl_handle::use_count()
const throw()
689 return acb_ptr == 0 ? 0L : acb_ptr->use_count();
693 operator == ( weak_ctrl_handle
const & lhs, weak_ctrl_handle
const & rhs )
695 return lhs.acb_ptr == rhs.acb_ptr;
699 operator < ( weak_ctrl_handle
const & lhs, weak_ctrl_handle
const & rhs )
701 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
704 shared_ctrl_handle::shared_ctrl_handle( weak_ctrl_handle
const & other )
705 : acb_ptr( other.acb_ptr )
707 if( acb_ptr == 0 || ! acb_ptr->add_ref_lock() )
708 throw bad_weak_ptr();
711 shared_ctrl_handle::shared_ctrl_handle( weak_ctrl_handle
const & other
713 : acb_ptr( other.acb_ptr )
715 if( acb_ptr != 0 && ! acb_ptr->add_ref_lock() )
724 struct static_cast_tag { };
725 struct const_cast_tag { };
726 struct dynamic_cast_tag { };
727 struct polymorphic_cast_tag { };
734 template<
typename T >
735 struct shared_ptr_traits
769 template<
typename X,
typename Y,
typename T >
773 , enable_shared_from_this<T>
const * pe
777 pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
780 template<
typename X,
typename Y,
typename T >
784 , enable_shared_from_this2<T>
const * pe
788 pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
802 template<
typename P >
805 typedef shared_ptr<P> this_type;
806 typedef typename sp::shared_ptr_traits<P>::reference reference;
808 template<
typename >
friend class shared_ptr;
809 template<
typename >
friend class weak_ptr;
816 template< typename P2 >
819 template< typename P2, typename
D >
821 template< typename P2, typename D, typename A >
829 template< typename P2 >
832 template< typename P2 >
834 template< typename P2 >
836 template< typename P2 >
838 template< typename P2 >
840 template< typename P2 >
842 template< typename P2 >
844 template< typename P2 >
847 template< typename AP >
852 template< typename P2 >
857 template< typename P2 >
859 template< typename P2 >
860 inline
shared_ptr & operator = ( std::auto_ptr<P2> & );
861 template< typename AP >
866 inline
void reset() throw();
867 template< typename P2 >
868 inline
void reset( P2 * );
869 template< typename P2, typename D >
870 inline
void reset( P2 *, D );
871 template< typename P2, typename D, typename A >
872 inline
void reset( P2 *, D, A );
873 template< typename P2 >
874 inline
void reset(
shared_ptr<P2> const &, P * );
877 inline operator
bool () const throw();
878 inline
reference operator * () const throw();
879 inline P * operator -> () const throw();
882 inline P * get() const throw();
883 inline
bool unique() const throw();
884 inline
long use_count() const throw();
887 template< typename P2 >
888 inline
bool _internal_less(
shared_ptr<P2> const & ) const;
889 inline
void * _internal_get_deleter( std::type_info const & ) const;
890 inline
bool _internal_equiv(
shared_ptr const & ) const;
895 sp::shared_ctrl_handle pn;
899 template< typename P, typename P2 >
901 template< typename P, typename P2 >
903 template< typename P, typename P2 >
906 template< typename P >
909 template< typename P, typename P2 >
911 template< typename P, typename P2 >
913 template< typename P, typename P2 >
916 template< typename P >
918 template< typename D, typename P >
921 template< typename C, typename T, typename P >
922 inline std::basic_ostream<C,T> & operator << ( std::basic_ostream<C,T> &
926 template< typename P >
932 template<
typename P >
933 template<
typename P2 >
941 template<
typename P >
942 template<
typename P2,
typename D >
943 shared_ptr<P>::shared_ptr( P2 * p,
D d )
950 template<
typename P >
951 template<
typename P2,
typename D,
typename A >
952 shared_ptr<P>::shared_ptr( P2 * p,
D d, A a )
959 template<
typename P >
967 template<
typename P >
969 shared_ptr<P>::operator = ( shared_ptr
const & other )
throw()
971 this_type( other ).swap( *
this );
975 template<
typename P >
976 template<
typename P2 >
977 shared_ptr<P>::shared_ptr( weak_ptr<P2>
const & other )
984 template<
typename P >
985 template<
typename P2 >
986 shared_ptr<P>::shared_ptr( weak_ptr<P2>
const & other
990 , pn( other.pn, sp::sp_nothrow_tag() )
996 template<
typename P >
997 template<
typename P2 >
998 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1005 template<
typename P >
1006 template<
typename P2 >
1007 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1008 , sp::static_cast_tag
1010 : px( static_cast<element_type*>( other.px ) )
1014 template<
typename P >
1015 template<
typename P2 >
1016 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1017 , sp::const_cast_tag
1019 : px( const_cast<element_type*>( other.px ) )
1023 template<
typename P >
1024 template<
typename P2 >
1025 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1026 , sp::dynamic_cast_tag
1028 : px( dynamic_cast<element_type*>( other.px ) )
1032 pn = sp::shared_ctrl_handle();
1035 template<
typename P >
1036 template<
typename P2 >
1037 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1038 , sp::polymorphic_cast_tag
1040 : px( dynamic_cast<element_type*>( other.px ) )
1044 throw std::bad_cast();
1047 template<
typename P >
1048 template<
typename P2 >
1049 shared_ptr<P>::shared_ptr( std::auto_ptr<P2> & other )
1053 P2 * tmp = other.get();
1054 pn = sp::shared_ctrl_handle( other );
1058 template<
typename P >
1059 template<
typename AP >
1060 shared_ptr<P>::shared_ptr( AP other
1061 ,
typename enable_if_auto_ptr<AP,void*>::type
1066 typename AP::element_type * tmp = other.get();
1067 pn = sp::shared_ctrl_handle( other );
1071 template<
typename P >
1072 template<
typename P2 >
1073 shared_ptr<P>::shared_ptr( shared_ptr<P2>
const & other
1074 ,
typename enable_if_ptr_convertible<P2,P,void*>::type
1080 template<
typename P >
1081 template<
typename P2 >
1083 shared_ptr<P>::operator = ( shared_ptr<P2>
const & other )
throw()
1085 this_type( other ).swap( *
this );
1089 template<
typename P >
1090 template<
typename P2 >
1092 shared_ptr<P>::operator = ( std::auto_ptr<P2> & other )
1094 this_type( other ).swap( *
this );
1098 template<
typename P >
1099 template<
typename AP >
1100 typename enable_if_auto_ptr< AP, shared_ptr<P> & >::type
1101 shared_ptr<P>::operator = ( AP other )
1103 this_type( other ).swap( *
this );
1107 template<
typename P >
1109 shared_ptr<P>::reset() throw()
1111 this_type().swap( *
this );
1114 template<
typename P >
1115 template<
typename P2 >
1117 shared_ptr<P>::reset( P2 * p )
1119 assert( p == 0 || p != px );
1120 this_type( p ).swap( *
this );
1123 template<
typename P >
1124 template<
typename P2,
typename D >
1126 shared_ptr<P>::reset( P2 * p,
D d )
1128 this_type( p, d ).swap( *
this );
1131 template<
typename P >
1132 template<
typename P2,
typename D,
typename A >
1134 shared_ptr<P>::reset( P2 * p,
D d, A a )
1136 this_type( p, d, a ).swap( *
this );
1139 template<
typename P >
1140 template<
typename P2 >
1142 shared_ptr<P>::reset( shared_ptr<P2>
const & other, P * p )
1144 this_type( other, p ).swap( *
this );
1147 template<
typename P >
1148 shared_ptr<P>::operator bool ()
const throw()
1153 template<
typename P >
1154 typename sp::shared_ptr_traits<P>::reference
1162 template<
typename P >
1164 shared_ptr<P>::operator -> ()
const throw()
1170 template<
typename P >
1172 shared_ptr<P>::get()
const throw()
1177 template<
typename P >
1179 shared_ptr<P>::unique()
const throw()
1184 template<
typename P >
1186 shared_ptr<P>::use_count()
const throw()
1188 return pn.use_count();
1191 template<
typename P >
1192 template<
typename P2 >
1194 shared_ptr<P>::_internal_less( shared_ptr<P2>
const & rhs )
const
1199 template<
typename P >
1201 shared_ptr<P>::_internal_get_deleter( std::type_info
const & ti )
const
1203 return pn.get_deleter( ti );
1206 template<
typename P >
1208 shared_ptr<P>::_internal_equiv( shared_ptr
const & other )
const
1210 return px == other.px && pn == other.pn;
1213 template<
typename P,
typename P2 >
1215 operator == ( shared_ptr<P>
const & a, shared_ptr<P2>
const &
b )
1217 return a.get() == b.get();
1220 template<
typename P,
typename P2 >
1222 operator != ( shared_ptr<P>
const & a, shared_ptr<P2>
const & b )
1224 return a.get() != b.get();
1227 template<
typename P,
typename P2 >
1229 operator < ( shared_ptr<P>
const &
a, shared_ptr<P2>
const &
b )
1231 return a._internal_less(b);
1234 template<
typename P >
1236 swap( shared_ptr<P> & a, shared_ptr<P> & b )
1241 template<
typename P,
typename P2 >
1245 return shared_ptr<P>( other, sp::static_cast_tag() );
1248 template<
typename P,
typename P2 >
1252 return shared_ptr<P>( other, sp::const_cast_tag() );
1255 template<
typename P,
typename P2 >
1259 return shared_ptr<P>( other, sp::dynamic_cast_tag() );
1262 template<
typename P >
1269 template<
typename D,
typename P >
1273 return static_cast<D*
>( p._internal_get_deleter(
typeid(
D)) );
1276 template<
typename C,
typename T,
typename P >
1277 std::basic_ostream<C,T> &
1278 operator << ( std::basic_ostream<C,T> & os, shared_ptr<P>
const & p )
1289 template<
typename P >
1292 typedef weak_ptr<P> this_type;
1294 template<
typename >
friend class shared_ptr;
1295 template<
typename >
friend class weak_ptr;
1305 template< typename P2 >
1310 template< typename P2 >
1315 template< typename P2 >
1317 template< typename P2 >
1322 inline
long use_count() const throw();
1323 inline
bool expired() const throw();
1324 inline
bool _empty() const;
1325 inline
void reset() throw();
1328 inline
void _internal_assign( P * px2, sp::shared_ctrl_handle const & pn2 );
1329 template< typename P2 >
1330 inline
bool _internal_less(
weak_ptr<P2> const & rhs ) const;
1334 sp::weak_ctrl_handle pn;
1338 template< typename P, typename P2 >
1341 template< typename P >
1344 template< typename P >
1350 template<
typename P >
1351 template<
typename P2 >
1355 : px( r.lock().get() )
1359 template<
typename P >
1360 template<
typename P2 >
1361 weak_ptr<P>::weak_ptr( shared_ptr<P2>
const & r
1362 ,
typename enable_if_ptr_convertible<P2,P,void*>::type
1368 template<
typename P >
1369 template<
typename P2 >
1371 weak_ptr<P>::operator = (weak_ptr<P2>
const & r)
throw()
1373 px = r.
lock().get();
1378 template<
typename P >
1379 template<
typename P2 >
1381 weak_ptr<P>::operator = (shared_ptr<P2>
const & r)
throw()
1388 template<
typename P >
1390 weak_ptr<P>::lock()
const throw()
1392 return shared_ptr<element_type>( *
this, sp::sp_nothrow_tag() );
1395 template<
typename P >
1397 weak_ptr<P>::use_count()
const throw()
1399 return pn.use_count();
1402 template<
typename P >
1404 weak_ptr<P>::expired()
const throw()
1406 return pn.use_count() == 0;
1409 template<
typename P >
1411 weak_ptr<P>::_empty() const
1416 template<
typename P >
1418 weak_ptr<P>::reset() throw()
1420 this_type().swap(*
this);
1423 template<
typename P >
1431 template<
typename P >
1433 weak_ptr<P>::_internal_assign( P * px2, sp::shared_ctrl_handle
const & pn2 )
1439 template<
typename P >
1440 template<
typename P2 >
1442 weak_ptr<P>::_internal_less( weak_ptr<P2>
const & rhs )
const
1447 template<
typename P,
typename P2 >
1449 operator < ( weak_ptr<P>
const &
a, weak_ptr<P2>
const &
b )
1451 return a._internal_less(b);
1454 template<
typename P >
1456 swap( weak_ptr<P> & a, weak_ptr<P> & b )
1466 struct do_nothing_deleter {
1467 inline void operator () (
void const * )
const;
1471 do_nothing_deleter::operator () (
void const * )
const
1480 #endif // CLHEP_MEMORY_H
1489 template<
typename T >
1490 class enable_shared_from_this
1493 enable_shared_from_this()
1496 ~enable_shared_from_this()
1499 enable_shared_from_this( enable_shared_from_this
const & )
1502 enable_shared_from_this &
1503 operator = ( enable_shared_from_this
const & )
1512 shared_ptr<T> p( weak_this_ );
1513 assert( p.get() == this );
1518 shared_from_this()
const
1520 shared_ptr<T const> p( weak_this_ );
1521 assert( p.get() == this );
1528 template<
typename X,
typename Y >
1530 _internal_accept_owner( shared_ptr<X>
const * ppx,
Y * py )
const
1532 if( weak_this_.expired() )
1533 weak_this_ = shared_ptr<T>( *ppx, py );
1537 mutable weak_ptr<T> weak_this_;
1546 class esft2_deleter_wrapper
1549 shared_ptr<void> deleter_;
1552 esft2_deleter_wrapper()
1555 template<
typename T >
1557 set_deleter( shared_ptr<T>
const &
deleter )
1562 template<
typename T >
1566 assert( deleter_.use_count() <= 1 );
1573 template<
typename T >
1574 class enable_shared_from_this2
1578 enable_shared_from_this2()
1581 enable_shared_from_this2( enable_shared_from_this2
const & )
1584 enable_shared_from_this2 & operator = ( enable_shared_from_this2
const & )
1589 ~enable_shared_from_this2()
1591 assert( shared_this_.use_count() <= 1 );
1595 mutable weak_ptr<T> weak_this_;
1596 mutable shared_ptr<T> shared_this_;
1604 return shared_ptr<T>( weak_this_ );
1608 shared_from_this()
const
1611 return shared_ptr<T>( weak_this_ );
1616 void init_weak_once()
const
1618 if( weak_this_._empty() )
1620 shared_this_.reset( static_cast< T* >( 0 )
1621 , detail::esft2_deleter_wrapper()
1623 weak_this_ = shared_this_;
1630 template<
typename X,
typename Y >
1632 _internal_accept_owner( shared_ptr<X> * ppx,
Y * py )
const
1636 if( weak_this_.use_count() == 0 )
1637 weak_this_ = shared_ptr<T>( *ppx, py );
1638 else if( shared_this_.use_count() != 0 )
1640 assert( ppx->unique() );
1642 detail::esft2_deleter_wrapper * pd
1643 = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
1646 pd->set_deleter( *ppx );
1648 ppx->reset( shared_this_, ppx->get() );
1649 shared_this_.reset();