Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
memory.h
Go to the documentation of this file.
1#ifndef CLHEP_MEMORY_H
2#define CLHEP_MEMORY_H
3
4// ======================================================================
5//
6// memory - memory management utilities
7//
8// Note: the following adaptation of the C++0X std::shared_ptr/weak_ptr
9// interface and semantics has been customized for the specific internal
10// needs of CLHEP/Random; it neither has nor needs the full generality
11// of its namesake.
12//
13// Author: W. E. Brown, 2010-03-19, adapted from the boost library's
14// shared_ptr and related functionality whose internal attributions bear
15// the following various notices:
16//
17// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
18// Copyright (c) 2001, 2002, 2003 Peter Dimov
19// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
20// Copyright (c) 2001-2008 Peter Dimov
21// Copyright (c) 2001-2009 Peter Dimov
22// Copyright 2002, 2009 Peter Dimov
23// Copyright 2004-2005 Peter Dimov
24// Copyright 2004-2008 Peter Dimov
25// Copyright 2005, 2006 Peter Dimov
26// Copyright 2008 Frank Mori Hess
27// Copyright 2008 Peter Dimov
28// Distributed under the Boost Software License, Version 1.0.
29// See http://www.boost.org/LICENSE_1_0.txt
30//
31// ======================================================================
32
33// don't generate unnecessary warnings
34#if defined __GNUC__
35 #if __GNUC__ > 3 && __GNUC_MINOR__ > 6
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
38 #endif
39#endif
40#ifdef __clang__
41 #pragma clang diagnostic push
42 #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
43#endif
44
45#include "CLHEP/Utility/defs.h"
48
49#include <algorithm> // for swap
50#include <cassert> // for assert macro
51#include <cstddef> // for size_t
52#include <exception> // for exception
53#include <functional> // for less
54#include <iosfwd> // for basic_ostream
55#include <memory> // for allocator, auto_ptr
56#include <typeinfo> // for bad_cast, type_info
57
58
59namespace CLHEP {
60
61
62// ----------------------------------------------------------------------
63// forward declarations
64// ----------------------------------------------------------------------
65
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;
70
71
72// ----------------------------------------------------------------------
73// bad_weak_ptr - exception thrown when a stale weak_ptr is encountered
74// ----------------------------------------------------------------------
75
77 : public std::exception
78{
79public:
80 inline virtual char const * what() const throw();
81
82}; // bad_weak_ptr
83
84char const *
85 bad_weak_ptr::what() const throw()
86{
87 return "bad_weak_ptr";
88}
89
90
91namespace sp {
92
93
94// ----------------------------------------------------------------------
95// abstract_ctrl_block - shared_ptr's counters and type-erased deleter
96// ----------------------------------------------------------------------
97
99 : public noncopyable
100{
101public:
102 inline void class_invariant() const throw();
103 // class class_invariant
104
105 inline abstract_ctrl_block();
106 inline virtual ~abstract_ctrl_block() throw();
107 // constructor and destructor
108
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();
117 // resource management functions
118
119 inline long use_count() const throw();
120 // accessor
121
122private:
123 int n_shared_ptrs;
124 int n_weak_ptrs;
125
126}; // abstract_ctrl_block
127
128void
130{
131 assert( n_shared_ptrs == 0 || n_weak_ptrs >= 1 );
132}
133
135 : n_shared_ptrs( 1 )
136 , n_weak_ptrs ( 1 )
137{
139}
140
142{
144}
145
146void
148{
150 ++n_shared_ptrs;
151}
152
153bool
155{
157 return n_shared_ptrs ? ++n_shared_ptrs : false;
158}
159
160void
162{
164 ++n_weak_ptrs;
165}
166
167void
169{
171 if( 0 == --n_shared_ptrs )
173}
174
175void
177{
179 if( 0 == --n_weak_ptrs )
180 destroy();
181}
182
183void
185{
186 assert( n_weak_ptrs == 0 );
187 delete this;
188}
189
190long
192{
194 return n_shared_ptrs;
195}
196
197
198// ----------------------------------------------------------------------
199// concrete ctrl_block_* variations:
200// ctrl_block_p : owned pointer only; no deleter, no allocator
201// ctrl_block_pd : owned pointer and deleter only; no allocator
202// ctrl_block_pda: owned pointer, deleter, and allocator
203// ----------------------------------------------------------------------
204
205template< typename P > // P is pointee type
207 : public abstract_ctrl_block
208{
210
211public:
212 inline explicit ctrl_block_p( P * );
213 inline ~ctrl_block_p() throw();
214 // constructor and destructor
215
216 inline void * operator new ( std::size_t );
217 inline void operator delete ( void * );
218 // allocation functions
219
220 inline virtual void * get_deleter( std::type_info const & );
221 inline virtual void dispose() throw();
222 // resource management functions
223
224private:
225 P * owned_ptr;
226
227}; // ctrl_block_p
228
229template< typename P >
232 , owned_ptr( p )
233{ }
234
235template< typename P >
237{ }
238
239template< typename P >
240void
242{
243 delete owned_ptr;
244}
245
246template< typename P >
247void *
248 ctrl_block_p<P>::get_deleter( std::type_info const & )
249{
250 return 0;
251}
252
253template< typename P >
254void *
255 ctrl_block_p<P>::operator new ( std::size_t )
256{
257 return std::allocator<this_type>().allocate( 1 );
258}
259
260template< typename P >
261void
262 ctrl_block_p<P>::operator delete ( void * p )
263{
264 std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
265}
266
267template< typename P // pointee type
268 , typename D // deleter type
269 >
271 : public abstract_ctrl_block
272{
274
275public:
276 inline ctrl_block_pd( P *, D );
277 inline ~ctrl_block_pd() throw();
278 // constructor and destructor
279
280 inline void * operator new ( std::size_t );
281 inline void operator delete ( void * );
282 // allocation functions
283
284 inline virtual void * get_deleter( std::type_info const & );
285 inline virtual void dispose() throw();
286 // resource management functions
287
288private:
289 P * owned_ptr;
290 D deleter; // D's copy constructor must not throw, and
291 // call to deleter( owned_ptr ) must not throw
292
293}; // ctrl_block_pd
294
295template< typename P, typename D >
298 , owned_ptr( p )
299 , deleter ( d )
300{ }
301
302template< typename P, typename D >
304{ }
305
306template< typename P, typename D >
307void
309{
310 deleter( owned_ptr );
311}
312
313template< typename P, typename D >
314void *
315 ctrl_block_pd<P,D>::get_deleter( std::type_info const & ti )
316{
317 return ti == typeid(D) ? &reinterpret_cast<char&>( deleter ) : 0;
318}
319
320template< typename P, typename D >
321void *
323{
324 return std::allocator<this_type>().allocate( 1 );
325}
326
327template< typename P, typename D >
328void
330{
331 std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
332}
333
334template< typename P // pointee type
335 , typename D // deleter type
336 , typename A // allocator type
337 >
339 : public abstract_ctrl_block
340{
342
343public:
344 inline ctrl_block_pda( P *, D, A );
345 inline ~ctrl_block_pda() throw();
346 // constructor and destructor
347
348 inline virtual void * get_deleter( std::type_info const & );
349 inline virtual void dispose() throw();
350 inline virtual void destroy() throw();
351 // resource management functions
352
353private:
354 P * owned_ptr;
355 D deleter; // D's copy constructor must not throw, and
356 // call to deleter( owned_ptr ) must not throw
357 A allocator; // A's copy constructor must not throw
358
359}; // ctrl_block_pda
360
361template< typename P, typename D, typename A >
364 , owned_ptr( p )
365 , deleter ( d )
366 , allocator( a )
367{ }
368
369template< typename P, typename D, typename A >
371{ }
372
373template< typename P, typename D, typename A >
374void
376{
377 deleter( owned_ptr );
378}
379
380template< typename P, typename D, typename A >
381void
383{
384 typename A::template rebind< this_type >::other this_allocator( allocator );
385
386 this_allocator.destroy( this ); // this->~this_type();
387 this_allocator.deallocate( this, 1 );
388}
389
390template< typename P, typename D, typename A >
391void *
392 ctrl_block_pda<P,D,A>::get_deleter( std::type_info const & ti )
393{
394 return ti == typeid( D ) ? &reinterpret_cast<char&>( deleter ) : 0;
395}
396
397
398// ----------------------------------------------------------------------
399// shared_ctrl_handle, weak_ctrl_handle - ctrl block handles
400// ----------------------------------------------------------------------
401
403class weak_ctrl_handle;
404
405struct sp_nothrow_tag { };
406
408{
409 friend class weak_ctrl_handle;
410
411public:
412 inline shared_ctrl_handle() throw();
413 template< typename P >
414 inline explicit
415 shared_ctrl_handle( P * );
416 template< typename P, typename D >
417 inline shared_ctrl_handle( P *, D );
418 template< typename P, typename D, typename A >
419 inline shared_ctrl_handle( P *, D, A );
420 template< typename P >
421 inline explicit
422 shared_ctrl_handle( std::auto_ptr<P> & );
423 inline ~shared_ctrl_handle() throw();
424 // constructors and destructor
425
426 inline void swap( shared_ctrl_handle & ) throw();
429 operator = ( shared_ctrl_handle const & ) throw();
430 // copy functions
431
432 inline explicit
435 // copy-like functions
436
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();
441 // accessors
442
443 friend inline
444 bool
446 friend inline
447 bool
449 // comparisons
450
451private:
452 abstract_ctrl_block * acb_ptr;
453
454}; // shared_ctrl_handle
455
457 : acb_ptr( 0 )
458{ }
459
460template< typename P >
462 // a fctn-try block would be slightly more efficient here,
463 // but some older compilers don't understand it
464 : acb_ptr( 0 )
465{
466 try {
467 acb_ptr = new ctrl_block_p<P>(p);
468 }
469 catch(...) {
470 delete p;
471 throw;
472 }
473}
474
475template< typename P, typename D >
477 // a fctn-try block would be slightly more efficient here,
478 // but some older compilers don't understand it
479 : acb_ptr( 0 )
480{
481 try {
482 acb_ptr = new ctrl_block_pd<P,D>(p, d);
483 }
484 catch(...) {
485 d( p );
486 throw;
487 }
488}
489
490template< typename P, typename D, typename A >
492 : acb_ptr( 0 )
493{
495 ctrl_block;
496 typedef typename A::template rebind<ctrl_block>::other
497 ctrl_block_allocator;
498 ctrl_block_allocator cba( a );
499
500 try
501 {
502 acb_ptr = cba.allocate( 1 );
503 new( static_cast<void*>(acb_ptr) ) ctrl_block(p, d, a);
504 }
505 catch(...)
506 {
507 d( p );
508 if( acb_ptr != 0 )
509 cba.deallocate( static_cast<ctrl_block*>( acb_ptr ), 1 );
510 throw;
511 }
512}
513
514template< typename P >
516 : acb_ptr( new ctrl_block_p<P>( p.get() ) )
517{
518 p.release();
519}
520
522{
523 if( acb_ptr != 0 )
524 acb_ptr->release();
525}
526
527void
529{
530 abstract_ctrl_block * tmp = other.acb_ptr;
531 other.acb_ptr = acb_ptr;
532 acb_ptr = tmp;
533}
534
536 : acb_ptr( other.acb_ptr )
537{
538 if( acb_ptr != 0 )
539 acb_ptr->add_ref();
540}
541
544{
545 abstract_ctrl_block * tmp = other.acb_ptr;
546
547 if( tmp != acb_ptr )
548 {
549 if( tmp != 0 ) tmp->add_ref();
550 if( acb_ptr != 0 ) acb_ptr->release();
551 acb_ptr = tmp;
552 }
553
554 return *this;
555}
556
557void *
558 shared_ctrl_handle::get_deleter( std::type_info const & ti ) const
559{
560 return acb_ptr ? acb_ptr->get_deleter( ti ) : 0;
561}
562
563bool
565{
566 return 1L == use_count();
567}
568
569bool
571{
572 return acb_ptr == 0;
573}
574
575long
577{
578 return acb_ptr == 0 ? 0L : acb_ptr->use_count();
579}
580
581bool
583{
584 return lhs.acb_ptr == rhs.acb_ptr;
585}
586
587bool
588 operator < ( shared_ctrl_handle const & lhs, shared_ctrl_handle const & rhs )
589{
590 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
591}
592
594{
595 friend class shared_ctrl_handle;
596
597public:
598
599 inline weak_ctrl_handle() throw();
601 inline ~weak_ctrl_handle() throw();
602 // constructors and destructor
603
604 inline void swap( weak_ctrl_handle & ) throw();
606 inline weak_ctrl_handle & operator = ( shared_ctrl_handle const & ) throw();
607 // copy functions
608
609 inline weak_ctrl_handle & operator = ( weak_ctrl_handle const & ) throw();
610 // copy-like functions
611
612 inline bool empty() const throw();
613 inline long use_count() const throw();
614 // accessors
615
616 friend inline
617 bool
618 operator == ( weak_ctrl_handle const &, weak_ctrl_handle const & );
619 friend inline
620 bool
621 operator < ( weak_ctrl_handle const &, weak_ctrl_handle const & );
622 // comparisons
623
624private:
625 abstract_ctrl_block * acb_ptr;
626
627}; // weak_ctrl_handle
628
630 : acb_ptr( 0 )
631{ }
632
634 : acb_ptr( other.acb_ptr )
635{
636 if( acb_ptr != 0 )
637 acb_ptr->weak_add_ref();
638}
639
641{
642 if( acb_ptr != 0 )
643 acb_ptr->weak_release();
644}
645
646void
648{
649 abstract_ctrl_block * tmp = other.acb_ptr;
650 other.acb_ptr = acb_ptr;
651 acb_ptr = tmp;
652}
653
655 : acb_ptr( other.acb_ptr )
656{
657 if( acb_ptr != 0 )
658 acb_ptr->weak_add_ref();
659}
660
663{
664 abstract_ctrl_block * tmp = other.acb_ptr;
665
666 if( tmp != acb_ptr )
667 {
668 if( tmp != 0 ) tmp->weak_add_ref();
669 if( acb_ptr != 0 ) acb_ptr->weak_release();
670 acb_ptr = tmp;
671}
672
673 return *this;
674}
675
678{
679 abstract_ctrl_block * tmp = other.acb_ptr;
680
681 if( tmp != acb_ptr )
682{
683 if( tmp != 0 ) tmp->weak_add_ref();
684 if( acb_ptr != 0 ) acb_ptr->weak_release();
685 acb_ptr = tmp;
686}
687
688 return *this;
689}
690
691bool
693{
694 return acb_ptr == 0;
695}
696
697long
699{
700 return acb_ptr == 0 ? 0L : acb_ptr->use_count();
701}
702
703bool
705{
706 return lhs.acb_ptr == rhs.acb_ptr;
707}
708
709bool
710 operator < ( weak_ctrl_handle const & lhs, weak_ctrl_handle const & rhs )
711{
712 return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
713}
714
716 : acb_ptr( other.acb_ptr )
717{
718 if( acb_ptr == 0 || ! acb_ptr->add_ref_lock() )
719 throw bad_weak_ptr();
720}
721
724 : acb_ptr( other.acb_ptr )
725{
726 if( acb_ptr != 0 && ! acb_ptr->add_ref_lock() )
727 acb_ptr = 0;
728}
729
730
731// ----------------------------------------------------------------------
732// cast tags
733// ----------------------------------------------------------------------
734
736struct const_cast_tag { };
739
740
741// ----------------------------------------------------------------------
742// shared_ptr_traits - specify dependent types
743// ----------------------------------------------------------------------
744
745template< typename T >
747{
748 typedef T & reference;
749};
750
751template<>
752 struct shared_ptr_traits<void>
753{
754 typedef void reference;
755};
756
757template<>
759{
760 typedef void reference;
761};
762
763template<>
764 struct shared_ptr_traits<void volatile>
765{
766 typedef void reference;
767};
768
769template<>
770 struct shared_ptr_traits<void const volatile>
771{
772 typedef void reference;
773};
774
775
776// ----------------------------------------------------------------------
777// enable_shared_from_this support
778// ----------------------------------------------------------------------
779
780template< typename X, typename Y, typename T >
781inline void
783 , Y const * py
784 , enable_shared_from_this<T> const * pe
785 )
786{
787 if( pe != 0 )
788 pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
789}
790
791template< typename X, typename Y, typename T >
792inline void
794 , Y const * py
795 , enable_shared_from_this2<T> const * pe
796 )
797{
798 if( pe != 0 )
799 pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
800}
801
802inline void
804{ }
805
806} // namespace sp
807
808
809// ----------------------------------------------------------------------
810// shared_ptr - "if you are the last person, please turn out the light"
811// ----------------------------------------------------------------------
812
813template< typename P > // pointee type
815{
816 typedef shared_ptr<P> this_type;
817 typedef typename sp::shared_ptr_traits<P>::reference reference;
818
819 template< typename > friend class shared_ptr;
820 template< typename > friend class weak_ptr;
821
822public:
823 typedef P element_type;
824 // pointee type
825
826 shared_ptr() throw();
827 template< typename P2 >
828 inline explicit
829 shared_ptr( P2 * );
830 template< typename P2, typename D >
831 inline shared_ptr( P2 *, D );
832 template< typename P2, typename D, typename A >
833 inline shared_ptr( P2 *, D, A );
834 // constructors
835
836 inline void swap( shared_ptr<P> & ) throw();
837 inline shared_ptr & operator = ( shared_ptr const & ) throw();
838 // copy functions; generated copy constructor, destructor are fine
839
840 template< typename P2 >
841 inline explicit
843 template< typename P2 >
844 inline shared_ptr( weak_ptr<P2> const &, sp::sp_nothrow_tag ) throw();
845 template< typename P2 >
846 inline shared_ptr( shared_ptr<P2> const &, P * ) throw();
847 template< typename P2 >
848 inline shared_ptr( shared_ptr<P2> const &, sp::static_cast_tag );
849 template< typename P2 >
850 inline shared_ptr( shared_ptr<P2> const &, sp::const_cast_tag );
851 template< typename P2 >
852 inline shared_ptr( shared_ptr<P2> const &, sp::dynamic_cast_tag );
853 template< typename P2 >
854 inline shared_ptr( shared_ptr<P2> const &, sp::polymorphic_cast_tag );
855 template< typename P2 >
856 inline explicit
857 shared_ptr( std::auto_ptr<P2> & );
858 template< typename AP >
859 inline explicit
861 , typename enable_if_auto_ptr<AP,void*>::type = 0
862 );
863 template< typename P2 >
864 inline
866 , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
867 ) throw();
868 template< typename P2 >
869 inline shared_ptr & operator = ( shared_ptr<P2> const & ) throw();
870 template< typename P2 >
871 inline shared_ptr & operator = ( std::auto_ptr<P2> & );
872 template< typename AP >
873 inline typename enable_if_auto_ptr< AP, shared_ptr & >::type
874 operator = ( AP );
875 // copy-like functions
876
877 inline void reset() throw();
878 template< typename P2 >
879 inline void reset( P2 * );
880 template< typename P2, typename D >
881 inline void reset( P2 *, D );
882 template< typename P2, typename D, typename A >
883 inline void reset( P2 *, D, A );
884 template< typename P2 >
885 inline void reset( shared_ptr<P2> const &, P * );
886 // reset functions
887
888 inline operator bool () const throw();
889 inline reference operator * () const throw();
890 inline P * operator -> () const throw();
891 // pointer-like behavior
892
893 inline P * get() const throw();
894 inline bool unique() const throw();
895 inline long use_count() const throw();
896 // accessors
897
898 template< typename P2 >
900 inline void * _internal_get_deleter( std::type_info const & ) const;
902 // implementation helpers -- do not use
903
904private:
905 P * px; // contained pointer
906 sp::shared_ctrl_handle pn; // control information
907
908}; // shared_ptr
909
910template< typename P, typename P2 >
911 inline bool operator == ( shared_ptr<P> const &, shared_ptr<P2> const & );
912template< typename P, typename P2 >
913 inline bool operator != ( shared_ptr<P> const &, shared_ptr<P2> const & );
914template< typename P, typename P2 >
915 inline bool operator < ( shared_ptr<P> const &, shared_ptr<P2> const & );
916
917template< typename P >
918 inline void swap( shared_ptr<P> &, shared_ptr<P> & );
919
920template< typename P, typename P2 >
922template< typename P, typename P2 >
924template< typename P, typename P2 >
926
927template< typename P >
929template< typename D, typename P >
931
932template< typename C, typename T, typename P >
933 inline std::basic_ostream<C,T> & operator << ( std::basic_ostream<C,T> &
934 , shared_ptr<P> const &
935 );
936
937template< typename P >
938 shared_ptr<P>::shared_ptr() throw()
939 : px( 0 )
940 , pn( )
941{ }
942
943template< typename P >
944template< typename P2 > // P2 must be a complete type
946 : px( p )
947 , pn( p )
948{
949 sp::sp_enable_shared_from_this( this, p, p );
950}
951
952template< typename P >
953template< typename P2, typename D > // D's copy c'tor must not throw
955 : px( p )
956 , pn( p, d )
957{
958 sp::sp_enable_shared_from_this( this, p, p );
959}
960
961template< typename P >
962template< typename P2, typename D, typename A > // D's, A's copy c'tors must not throw
963 shared_ptr<P>::shared_ptr( P2 * p, D d, A a )
964 : px( p )
965 , pn( p, d, a )
966{
967 sp::sp_enable_shared_from_this( this, p, p );
968}
969
970template< typename P >
971 void
973{
974 std::swap( px, other.px );
975 pn.swap( other.pn );
976}
977
978template< typename P >
980 shared_ptr<P>::operator = ( shared_ptr const & other ) throw()
981{
982 this_type( other ).swap( *this );
983 return *this;
984}
985
986template< typename P >
987template< typename P2 >
989 : px( 0 ) // temporarily
990 , pn( other.pn ) // may throw
991{
992 px = other.px; // safe to copy other.px, as pn(other.pn) did not throw
993}
994
995template< typename P >
996template< typename P2 >
999 ) throw()
1000 : px( 0 ) // temporarily
1001 , pn( other.pn, sp::sp_nothrow_tag() )
1002{
1003 if( ! pn.empty() )
1004 px = other.px;
1005}
1006
1007template< typename P >
1008template< typename P2 >
1010 , P * p
1011 ) throw()
1012 : px( p )
1013 , pn( other.pn )
1014{ }
1015
1016template< typename P >
1017template< typename P2 >
1020 )
1021 : px( static_cast<element_type*>( other.px ) )
1022 , pn( other.pn )
1023{ }
1024
1025template< typename P >
1026template< typename P2 >
1029 )
1030 : px( const_cast<element_type*>( other.px ) )
1031 , pn( other.pn )
1032{ }
1033
1034template< typename P >
1035template< typename P2 >
1038 )
1039 : px( dynamic_cast<element_type*>( other.px ) )
1040 , pn( other.pn )
1041{
1042 if( px == 0 ) // cast failed?
1043 pn = sp::shared_ctrl_handle(); // yes; need our own control information
1044}
1045
1046template< typename P >
1047template< typename P2 >
1050 )
1051 : px( dynamic_cast<element_type*>( other.px ) )
1052 , pn( other.pn )
1053{
1054 if( px == 0 )
1055 throw std::bad_cast();
1056}
1057
1058template< typename P >
1059template< typename P2 >
1060 shared_ptr<P>::shared_ptr( std::auto_ptr<P2> & other )
1061 : px( other.get() )
1062 , pn( ) // temporarily
1063{
1064 P2 * tmp = other.get();
1065 pn = sp::shared_ctrl_handle( other );
1066 sp::sp_enable_shared_from_this( this, tmp, tmp );
1067}
1068
1069template< typename P >
1070template< typename AP >
1073 )
1074 : px( other.get() )
1075 , pn( ) // temporarily
1076{
1077 typename AP::element_type * tmp = other.get();
1078 pn = sp::shared_ctrl_handle( other );
1079 sp::sp_enable_shared_from_this( this, tmp, tmp );
1080}
1081
1082template< typename P >
1083template< typename P2 >
1086 ) throw()
1087 : px( other.px )
1088 , pn( other.pn )
1089 { }
1090
1091template< typename P >
1092template< typename P2 >
1095{
1096 this_type( other ).swap( *this );
1097 return *this;
1098}
1099
1100template< typename P >
1101template< typename P2 >
1103 shared_ptr<P>::operator = ( std::auto_ptr<P2> & other )
1104{
1105 this_type( other ).swap( *this );
1106 return *this;
1107}
1108
1109template< typename P >
1110template< typename AP >
1111 typename enable_if_auto_ptr< AP, shared_ptr<P> & >::type
1113{
1114 this_type( other ).swap( *this );
1115 return *this;
1116}
1117
1118template< typename P >
1119 void
1121{
1122 this_type().swap( *this );
1123}
1124
1125template< typename P >
1126template< typename P2 >
1127 void
1128 shared_ptr<P>::reset( P2 * p ) // P2 must be a complete type
1129{
1130 assert( p == 0 || p != px ); // oughtn't reset oneself
1131 this_type( p ).swap( *this );
1132}
1133
1134template< typename P >
1135template< typename P2, typename D >
1136 void
1138{
1139 this_type( p, d ).swap( *this );
1140}
1141
1142template< typename P >
1143template< typename P2, typename D, typename A >
1144 void
1145 shared_ptr<P>::reset( P2 * p, D d, A a )
1146{
1147 this_type( p, d, a ).swap( *this );
1148}
1149
1150template< typename P >
1151template< typename P2 >
1152 void
1153 shared_ptr<P>::reset( shared_ptr<P2> const & other, P * p )
1154{
1155 this_type( other, p ).swap( *this );
1156}
1157
1158template< typename P >
1159 shared_ptr<P>::operator bool () const throw()
1160{
1161 return px;
1162}
1163
1164template< typename P >
1166 //typename shared_ptr<P>::reference
1168{
1169 assert( px != 0 );
1170 return *px;
1171}
1172
1173template< typename P >
1174 P *
1176{
1177 assert( px != 0 );
1178 return px;
1179}
1180
1181template< typename P >
1182 P *
1183 shared_ptr<P>::get() const throw()
1184{
1185 return px;
1186}
1187
1188template< typename P >
1189 bool
1191{
1192 return pn.unique();
1193}
1194
1195template< typename P >
1196 long
1198{
1199 return pn.use_count();
1200}
1201
1202template< typename P >
1203template< typename P2 >
1204 bool
1206{
1207 return pn < rhs.pn;
1208}
1209
1210template< typename P >
1211 void *
1212 shared_ptr<P>::_internal_get_deleter( std::type_info const & ti ) const
1213{
1214 return pn.get_deleter( ti );
1215}
1216
1217template< typename P >
1218 bool
1220{
1221 return px == other.px && pn == other.pn;
1222}
1223
1224template< typename P, typename P2 >
1225 bool
1227{
1228 return a.get() == b.get();
1229}
1230
1231template< typename P, typename P2 >
1232 bool
1234{
1235 return a.get() != b.get();
1236}
1237
1238template< typename P, typename P2 >
1239 bool
1240 operator < ( shared_ptr<P> const & a, shared_ptr<P2> const & b )
1241{
1242 return a._internal_less(b);
1243}
1244
1245template< typename P >
1246 void
1248{
1249 a.swap( b );
1250}
1251
1252template< typename P, typename P2 >
1253 shared_ptr<P>
1255{
1256 return shared_ptr<P>( other, sp::static_cast_tag() );
1257}
1258
1259template< typename P, typename P2 >
1260 shared_ptr<P>
1262{
1263 return shared_ptr<P>( other, sp::const_cast_tag() );
1264}
1265
1266template< typename P, typename P2 >
1267 shared_ptr<P>
1269{
1270 return shared_ptr<P>( other, sp::dynamic_cast_tag() );
1271}
1272
1273template< typename P >
1274 P *
1276{
1277 return p.get();
1278}
1279
1280template< typename D, typename P >
1281 D *
1283{
1284 return static_cast<D*>( p._internal_get_deleter( typeid(D)) );
1285}
1286
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 )
1290{
1291 os << p.get();
1292 return os;
1293}
1294
1295
1296// ----------------------------------------------------------------------
1297// weak_ptr - non-owning handle from which a shared_ptr can be obtained
1298// ----------------------------------------------------------------------
1299
1300template< typename P >
1302{
1303 typedef weak_ptr<P> this_type;
1304
1305 template< typename > friend class shared_ptr;
1306 template< typename > friend class weak_ptr;
1307
1308public:
1309 typedef P element_type;
1310
1311 inline weak_ptr() throw();
1312
1313 // generated copy constructor, assignment, destructor are fine
1314
1315 inline void swap( this_type & other ) throw();
1316 template< typename P2 >
1317 inline
1318 weak_ptr( weak_ptr<P2> const & r
1319 , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
1320 ) throw();
1321 template< typename P2 >
1322 inline
1323 weak_ptr( shared_ptr<P2> const & r
1324 , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
1325 ) throw();
1326 template< typename P2 >
1327 inline weak_ptr & operator = (weak_ptr<P2> const & r) throw();
1328 template< typename P2 >
1329 inline weak_ptr & operator = (shared_ptr<P2> const & r) throw();
1330 // copy-like functions
1331
1332 inline shared_ptr<P> lock() const throw();
1333 inline long use_count() const throw();
1334 inline bool expired() const throw();
1335 inline bool _empty() const; // extension, not in std::weak_ptr
1336 inline void reset() throw();
1337 // accessors
1338
1339 inline void _internal_assign( P * px2, sp::shared_ctrl_handle const & pn2 );
1340 template< typename P2 >
1341 inline bool _internal_less( weak_ptr<P2> const & rhs ) const;
1342
1343private:
1344 P * px; // contained pointer
1345 sp::weak_ctrl_handle pn; // control information
1346
1347}; // weak_ptr
1348
1349template< typename P, typename P2 >
1350 inline bool operator < ( weak_ptr<P> const & a, weak_ptr<P2> const & b );
1351
1352template< typename P >
1353 inline void swap( weak_ptr<P> & a, weak_ptr<P> & b );
1354
1355template< typename P >
1356weak_ptr<P>::weak_ptr() throw()
1357 : px( 0 )
1358 , pn( )
1359{ }
1360
1361template< typename P >
1362template< typename P2 >
1365 ) throw()
1366 : px( r.lock().get() ) // same as r.px, but doesn't risk invalidation
1367 , pn( r.pn )
1368{ }
1369
1370template< typename P >
1371template< typename P2 >
1374 ) throw()
1375 : px( r.px )
1376 , pn( r.pn )
1377{ }
1378
1379template< typename P >
1380template< typename P2 >
1381 weak_ptr<P> &
1383{
1384 px = r.lock().get();
1385 pn = r.pn;
1386 return *this;
1387}
1388
1389template< typename P >
1390template< typename P2 >
1391 weak_ptr<P> &
1393{
1394 px = r.px;
1395 pn = r.pn;
1396 return *this;
1397}
1398
1399template< typename P >
1401 weak_ptr<P>::lock() const throw()
1402{
1404}
1405
1406template< typename P >
1407 long
1409{
1410 return pn.use_count();
1411}
1412
1413template< typename P >
1414 bool
1415 weak_ptr<P>::expired() const throw()
1416{
1417 return pn.use_count() == 0;
1418}
1419
1420template< typename P >
1421 bool
1422 weak_ptr<P>::_empty() const // extension, not in std::weak_ptr
1423{
1424 return pn.empty();
1425}
1426
1427template< typename P >
1428 void
1430{
1431 this_type().swap(*this);
1432}
1433
1434template< typename P >
1435 void
1436 weak_ptr<P>::swap( this_type & other ) throw()
1437{
1438 std::swap(px, other.px);
1439 pn.swap(other.pn);
1440}
1441
1442template< typename P >
1443 void
1445{
1446 px = px2;
1447 pn = pn2;
1448}
1449
1450template< typename P >
1451template< typename P2 >
1452 bool
1454{
1455 return pn < rhs.pn;
1456}
1457
1458template< typename P, typename P2 >
1459 bool
1460 operator < ( weak_ptr<P> const & a, weak_ptr<P2> const & b )
1461{
1462 return a._internal_less(b);
1463}
1464
1465template< typename P >
1466 void
1468{
1469 a.swap(b);
1470}
1471
1472
1473// ----------------------------------------------------------------------
1474// do_nothing_deleter - for shared_ptrs not taking ownership
1475// ----------------------------------------------------------------------
1476
1478 inline void operator () ( void const * ) const;
1479};
1480
1481void
1483{ }
1484
1485
1486} // namespace CLHEP
1487
1488
1489
1490
1491#endif // CLHEP_MEMORY_H
1492//
1493// ======================================================================
1494
1495
1496#if 0
1497
1498// enable_shared_from_this.hpp
1499
1500template< typename T >
1501 class enable_shared_from_this
1502{
1503protected:
1504 enable_shared_from_this()
1505 { }
1506
1507 ~enable_shared_from_this()
1508 { }
1509
1510 enable_shared_from_this( enable_shared_from_this const & )
1511 { }
1512
1513 enable_shared_from_this &
1514 operator = ( enable_shared_from_this const & )
1515 {
1516 return *this;
1517 }
1518
1519public:
1520 shared_ptr<T>
1521 shared_from_this()
1522 {
1523 shared_ptr<T> p( weak_this_ );
1524 assert( p.get() == this );
1525 return p;
1526 }
1527
1528 shared_ptr<T const>
1529 shared_from_this() const
1530 {
1531 shared_ptr<T const> p( weak_this_ );
1532 assert( p.get() == this );
1533 return p;
1534 }
1535
1536public: // actually private, but avoids compiler template friendship issues
1537
1538 // Note: invoked automatically by shared_ptr; do not call
1539 template< typename X, typename Y >
1540 void
1541 _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
1542 {
1543 if( weak_this_.expired() )
1544 weak_this_ = shared_ptr<T>( *ppx, py );
1545 }
1546
1547private:
1548 mutable weak_ptr<T> weak_this_;
1549}; // enable_shared_from_this<>
1550
1551
1552// enable_shared_from_this2.hpp
1553
1554namespace detail
1555{
1556
1557class esft2_deleter_wrapper
1558{
1559private:
1560 shared_ptr<void> deleter_;
1561
1562public:
1563 esft2_deleter_wrapper()
1564 { }
1565
1566 template< typename T >
1567 void
1568 set_deleter( shared_ptr<T> const & deleter )
1569 {
1570 deleter_ = deleter;
1571 }
1572
1573 template< typename T >
1574 void
1575 operator () ( T* )
1576 {
1577 assert( deleter_.use_count() <= 1 );
1578 deleter_.reset();
1579 }
1580};
1581
1582} // namespace detail
1583
1584template< typename T >
1585 class enable_shared_from_this2
1586{
1587protected:
1588
1589 enable_shared_from_this2()
1590 { }
1591
1592 enable_shared_from_this2( enable_shared_from_this2 const & )
1593 { }
1594
1595 enable_shared_from_this2 & operator = ( enable_shared_from_this2 const & )
1596 {
1597 return *this;
1598 }
1599
1600 ~enable_shared_from_this2()
1601 {
1602 assert( shared_this_.use_count() <= 1 ); // ensure no dangling shared_ptrs
1603 }
1604
1605private:
1606 mutable weak_ptr<T> weak_this_;
1607 mutable shared_ptr<T> shared_this_;
1608
1609public:
1610
1611 shared_ptr<T>
1612 shared_from_this()
1613 {
1614 init_weak_once();
1615 return shared_ptr<T>( weak_this_ );
1616 }
1617
1618 shared_ptr<T const>
1619 shared_from_this() const
1620 {
1621 init_weak_once();
1622 return shared_ptr<T>( weak_this_ );
1623 }
1624
1625private:
1626
1627 void init_weak_once() const
1628 {
1629 if( weak_this_._empty() )
1630 {
1631 shared_this_.reset( static_cast< T* >( 0 )
1632 , detail::esft2_deleter_wrapper()
1633 );
1634 weak_this_ = shared_this_;
1635 }
1636 }
1637
1638public: // actually private, but avoids compiler template friendship issues
1639
1640 // Note: invoked automatically by shared_ptr; do not call
1641 template< typename X, typename Y >
1642 void
1643 _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
1644 {
1645 assert( ppx != 0 );
1646
1647 if( weak_this_.use_count() == 0 )
1648 weak_this_ = shared_ptr<T>( *ppx, py );
1649 else if( shared_this_.use_count() != 0 )
1650 {
1651 assert( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
1652
1653 detail::esft2_deleter_wrapper * pd
1654 = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
1655 assert( pd != 0 );
1656
1657 pd->set_deleter( *ppx );
1658
1659 ppx->reset( shared_this_, ppx->get() );
1660 shared_this_.reset();
1661 }
1662 }
1663}; // enable_shared_from_this2<>
1664
1665#endif // 0
virtual char const * what() const
Definition: memory.h:85
bool _internal_less(shared_ptr< P2 > const &) const
Definition: memory.h:1205
long use_count() const
Definition: memory.h:1197
bool unique() const
Definition: memory.h:1190
reference operator*() const
Definition: memory.h:1167
bool _internal_equiv(shared_ptr const &) const
Definition: memory.h:1219
shared_ptr & operator=(shared_ptr const &)
Definition: memory.h:980
void * _internal_get_deleter(std::type_info const &) const
Definition: memory.h:1212
P * get() const
Definition: memory.h:1183
void swap(shared_ptr< P > &)
Definition: memory.h:972
friend class shared_ptr
Definition: memory.h:819
P * operator->() const
Definition: memory.h:1175
virtual void destroy()
Definition: memory.h:184
void class_invariant() const
Definition: memory.h:129
virtual void * get_deleter(std::type_info const &ti)=0
virtual void dispose()
Definition: memory.h:241
virtual void * get_deleter(std::type_info const &)
Definition: memory.h:248
virtual void dispose()
Definition: memory.h:308
virtual void * get_deleter(std::type_info const &)
Definition: memory.h:315
virtual void destroy()
Definition: memory.h:382
virtual void * get_deleter(std::type_info const &)
Definition: memory.h:392
virtual void dispose()
Definition: memory.h:375
ctrl_block_pda(P *, D, A)
Definition: memory.h:362
void swap(shared_ctrl_handle &)
Definition: memory.h:528
void * get_deleter(std::type_info const &) const
Definition: memory.h:558
shared_ctrl_handle & operator=(shared_ctrl_handle const &)
Definition: memory.h:543
friend bool operator<(weak_ctrl_handle const &, weak_ctrl_handle const &)
Definition: memory.h:710
friend bool operator==(weak_ctrl_handle const &, weak_ctrl_handle const &)
Definition: memory.h:704
void swap(weak_ctrl_handle &)
Definition: memory.h:647
long use_count() const
Definition: memory.h:698
weak_ctrl_handle & operator=(shared_ctrl_handle const &)
Definition: memory.h:662
void swap(this_type &other)
Definition: memory.h:1436
friend class weak_ptr
Definition: memory.h:1306
bool _internal_less(weak_ptr< P2 > const &rhs) const
Definition: memory.h:1453
bool _empty() const
Definition: memory.h:1422
weak_ptr & operator=(weak_ptr< P2 > const &r)
bool expired() const
Definition: memory.h:1415
shared_ptr< P > lock() const
Definition: memory.h:1401
void reset()
Definition: memory.h:1429
void _internal_assign(P *px2, sp::shared_ctrl_handle const &pn2)
Definition: memory.h:1444
long use_count() const
Definition: memory.h:1408
#define inline
Definition: internal.h:71
bool operator==(shared_ctrl_handle const &lhs, shared_ctrl_handle const &rhs)
Definition: memory.h:582
void sp_enable_shared_from_this(shared_ptr< X > const *ppx, Y const *py, enable_shared_from_this< T > const *pe)
Definition: memory.h:782
bool operator<(shared_ctrl_handle const &lhs, shared_ctrl_handle const &rhs)
Definition: memory.h:588
Definition: DoubConv.h:17
shared_ptr< P > dynamic_pointer_cast(shared_ptr< P2 > const &)
Definition: memory.h:1268
P * get_pointer(shared_ptr< P > const &)
Definition: memory.h:1275
bool operator!=(shared_ptr< P > const &, shared_ptr< P2 > const &)
Definition: memory.h:1233
void swap(shared_ptr< P > &, shared_ptr< P > &)
Definition: memory.h:1247
shared_ptr< P > static_pointer_cast(shared_ptr< P2 > const &)
Definition: memory.h:1254
bool operator<(shared_ptr< P > const &, shared_ptr< P2 > const &)
Definition: memory.h:1240
bool operator==(shared_ptr< P > const &, shared_ptr< P2 > const &)
Definition: memory.h:1226
shared_ptr< P > const_pointer_cast(shared_ptr< P2 > const &)
Definition: memory.h:1261
D * get_deleter(shared_ptr< P > const &)
Definition: memory.h:1282
std::ostream & operator<<(std::ostream &os, const HepRandom &dist)
Definition: Random.cc:116
void operator()(void const *) const
Definition: memory.h:1482
#define const
Definition: zconf.h:118