Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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