Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
59 namespace CLHEP {
60 
61 
62 // ----------------------------------------------------------------------
63 // forward declarations
64 // ----------------------------------------------------------------------
65 
66 template< typename T > class shared_ptr;
67 template< typename T > class weak_ptr;
68 template< typename T > class enable_shared_from_this;
69 template< 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 {
79 public:
80  inline virtual char const * what() const throw();
81 
82 }; // bad_weak_ptr
83 
84 char const *
85  bad_weak_ptr::what() const throw()
86 {
87  return "bad_weak_ptr";
88 }
89 
90 
91 namespace sp {
92 
93 
94 // ----------------------------------------------------------------------
95 // abstract_ctrl_block - shared_ptr's counters and type-erased deleter
96 // ----------------------------------------------------------------------
97 
99  : public noncopyable
100 {
101 public:
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 
122 private:
123  int n_shared_ptrs;
124  int n_weak_ptrs;
125 
126 }; // abstract_ctrl_block
127 
128 void
130 {
131  assert( n_shared_ptrs == 0 || n_weak_ptrs >= 1 );
132 }
133 
135  : n_shared_ptrs( 1 )
136  , n_weak_ptrs ( 1 )
137 {
138  class_invariant();
139 }
140 
142 {
143  class_invariant();
144 }
145 
146 void
148 {
149  class_invariant();
150  ++n_shared_ptrs;
151 }
152 
153 bool
155 {
156  class_invariant();
157  return n_shared_ptrs ? ++n_shared_ptrs : false;
158 }
159 
160 void
162 {
163  class_invariant();
164  ++n_weak_ptrs;
165 }
166 
167 void
169 {
170  class_invariant();
171  if( 0 == --n_shared_ptrs )
172  dispose(), weak_release();
173 }
174 
175 void
177 {
178  class_invariant();
179  if( 0 == --n_weak_ptrs )
180  destroy();
181 }
182 
183 void
185 {
186  assert( n_weak_ptrs == 0 );
187  delete this;
188 }
189 
190 long
192 {
193  class_invariant();
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 
205 template< typename P > // P is pointee type
207  : public abstract_ctrl_block
208 {
209  typedef ctrl_block_p<P> this_type;
210 
211 public:
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 
224 private:
225  P * owned_ptr;
226 
227 }; // ctrl_block_p
228 
229 template< typename P >
232  , owned_ptr( p )
233 { }
234 
235 template< typename P >
237 { }
238 
239 template< typename P >
240 void
242 {
243  delete owned_ptr;
244 }
245 
246 template< typename P >
247 void *
248  ctrl_block_p<P>::get_deleter( std::type_info const & )
249 {
250  return 0;
251 }
252 
253 template< typename P >
254 void *
255  ctrl_block_p<P>::operator new ( std::size_t )
256 {
257  return std::allocator<this_type>().allocate( 1 );
258 }
259 
260 template< typename P >
261 void
262  ctrl_block_p<P>::operator delete ( void * p )
263 {
264  std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
265 }
266 
267 template< typename P // pointee type
268  , typename D // deleter type
269  >
271  : public abstract_ctrl_block
272 {
274 
275 public:
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 
288 private:
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 
295 template< typename P, typename D >
298  , owned_ptr( p )
299  , deleter ( d )
300 { }
301 
302 template< typename P, typename D >
304 { }
305 
306 template< typename P, typename D >
307 void
309 {
310  deleter( owned_ptr );
311 }
312 
313 template< typename P, typename D >
314 void *
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 
320 template< typename P, typename D >
321 void *
322  ctrl_block_pd<P,D>::operator new ( std::size_t )
323 {
324  return std::allocator<this_type>().allocate( 1 );
325 }
326 
327 template< typename P, typename D >
328 void
329  ctrl_block_pd<P,D>::operator delete ( void * p )
330 {
331  std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
332 }
333 
334 template< typename P // pointee type
335  , typename D // deleter type
336  , typename A // allocator type
337  >
339  : public abstract_ctrl_block
340 {
342 
343 public:
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 
353 private:
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 
361 template< typename P, typename D, typename A >
364  , owned_ptr( p )
365  , deleter ( d )
366  , allocator( a )
367 { }
368 
369 template< typename P, typename D, typename A >
371 { }
372 
373 template< typename P, typename D, typename A >
374 void
376 {
377  deleter( owned_ptr );
378 }
379 
380 template< typename P, typename D, typename A >
381 void
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 
390 template< typename P, typename D, typename A >
391 void *
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 
402 class shared_ctrl_handle;
403 class weak_ctrl_handle;
404 
405 struct sp_nothrow_tag { };
406 
408 {
409  friend class weak_ctrl_handle;
410 
411 public:
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
445  operator == ( shared_ctrl_handle const &, shared_ctrl_handle const & );
446  friend inline
447  bool
448  operator < ( shared_ctrl_handle const &, shared_ctrl_handle const & );
449  // comparisons
450 
451 private:
452  abstract_ctrl_block * acb_ptr;
453 
454 }; // shared_ctrl_handle
455 
457  : acb_ptr( 0 )
458 { }
459 
460 template< 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 
475 template< 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 
490 template< typename P, typename D, typename A >
492  : acb_ptr( 0 )
493 {
494  typedef ctrl_block_pda<P,D,A>
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 
514 template< 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 
527 void
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 
557 void *
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 
563 bool
565 {
566  return 1L == use_count();
567 }
568 
569 bool
571 {
572  return acb_ptr == 0;
573 }
574 
575 long
577 {
578  return acb_ptr == 0 ? 0L : acb_ptr->use_count();
579 }
580 
581 bool
583 {
584  return lhs.acb_ptr == rhs.acb_ptr;
585 }
586 
587 bool
589 {
590  return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
591 }
592 
594 {
595  friend class shared_ctrl_handle;
596 
597 public:
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 
624 private:
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 
646 void
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 
691 bool
692  weak_ctrl_handle::empty() const throw()
693 {
694  return acb_ptr == 0;
695 }
696 
697 long
699 {
700  return acb_ptr == 0 ? 0L : acb_ptr->use_count();
701 }
702 
703 bool
704  operator == ( weak_ctrl_handle const & lhs, weak_ctrl_handle const & rhs )
705 {
706  return lhs.acb_ptr == rhs.acb_ptr;
707 }
708 
709 bool
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 
723  , sp_nothrow_tag )
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 
735 struct static_cast_tag { };
736 struct const_cast_tag { };
737 struct dynamic_cast_tag { };
739 
740 
741 // ----------------------------------------------------------------------
742 // shared_ptr_traits - specify dependent types
743 // ----------------------------------------------------------------------
744 
745 template< typename T >
747 {
748  typedef T & reference;
749 };
750 
751 template<>
753 {
754  typedef void reference;
755 };
756 
757 template<>
759 {
760  typedef void reference;
761 };
762 
763 template<>
764  struct shared_ptr_traits<void volatile>
765 {
766  typedef void reference;
767 };
768 
769 template<>
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 
780 template< typename X, typename Y, typename T >
781 inline 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 
791 template< typename X, typename Y, typename T >
792 inline 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 
802 inline 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 
813 template< typename P > // pointee type
814  class shared_ptr
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 
822 public:
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
842  shared_ptr( weak_ptr<P2> const & );
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
860  shared_ptr( AP
861  , typename enable_if_auto_ptr<AP,void*>::type = 0
862  );
863  template< typename P2 >
864  inline
865  shared_ptr( shared_ptr<P2> const &
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 >
899  inline bool _internal_less( shared_ptr<P2> const & ) const;
900  inline void * _internal_get_deleter( std::type_info const & ) const;
901  inline bool _internal_equiv( shared_ptr const & ) const;
902  // implementation helpers -- do not use
903 
904 private:
905  P * px; // contained pointer
906  sp::shared_ctrl_handle pn; // control information
907 
908 }; // shared_ptr
909 
910 template< typename P, typename P2 >
911  inline bool operator == ( shared_ptr<P> const &, shared_ptr<P2> const & );
912 template< typename P, typename P2 >
913  inline bool operator != ( shared_ptr<P> const &, shared_ptr<P2> const & );
914 template< typename P, typename P2 >
915  inline bool operator < ( shared_ptr<P> const &, shared_ptr<P2> const & );
916 
917 template< typename P >
918  inline void swap( shared_ptr<P> &, shared_ptr<P> & );
919 
920 template< typename P, typename P2 >
922 template< typename P, typename P2 >
924 template< typename P, typename P2 >
926 
927 template< typename P >
928  inline P * get_pointer( shared_ptr<P> const & );
929 template< typename D, typename P >
930  inline D * get_deleter( shared_ptr<P> const & );
931 
932 template< 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 
937 template< typename P >
938  shared_ptr<P>::shared_ptr() throw()
939  : px( 0 )
940  , pn( )
941 { }
942 
943 template< typename P >
944 template< 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 
952 template< typename P >
953 template< 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 
961 template< typename P >
962 template< typename P2, typename D, typename A > // D's, A's copy c'tors must not throw
964  : px( p )
965  , pn( p, d, a )
966 {
967  sp::sp_enable_shared_from_this( this, p, p );
968 }
969 
970 template< typename P >
971  void
973 {
974  std::swap( px, other.px );
975  pn.swap( other.pn );
976 }
977 
978 template< typename P >
979  shared_ptr<P> &
980  shared_ptr<P>::operator = ( shared_ptr const & other ) throw()
981 {
982  this_type( other ).swap( *this );
983  return *this;
984 }
985 
986 template< typename P >
987 template< 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 
995 template< typename P >
996 template< 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 
1007 template< typename P >
1008 template< typename P2 >
1010  , P * p
1011  ) throw()
1012  : px( p )
1013  , pn( other.pn )
1014 { }
1015 
1016 template< typename P >
1017 template< typename P2 >
1020  )
1021  : px( static_cast<element_type*>( other.px ) )
1022  , pn( other.pn )
1023 { }
1024 
1025 template< typename P >
1026 template< typename P2 >
1029  )
1030  : px( const_cast<element_type*>( other.px ) )
1031  , pn( other.pn )
1032 { }
1033 
1034 template< typename P >
1035 template< 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 
1046 template< typename P >
1047 template< 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 
1058 template< typename P >
1059 template< 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 
1069 template< typename P >
1070 template< 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 
1082 template< typename P >
1083 template< typename P2 >
1086  ) throw()
1087  : px( other.px )
1088  , pn( other.pn )
1089  { }
1090 
1091 template< typename P >
1092 template< typename P2 >
1093  shared_ptr<P> &
1095 {
1096  this_type( other ).swap( *this );
1097  return *this;
1098 }
1099 
1100 template< typename P >
1101 template< typename P2 >
1102  shared_ptr<P> &
1103  shared_ptr<P>::operator = ( std::auto_ptr<P2> & other )
1104 {
1105  this_type( other ).swap( *this );
1106  return *this;
1107 }
1108 
1109 template< typename P >
1110 template< 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 
1118 template< typename P >
1119  void
1121 {
1122  this_type().swap( *this );
1123 }
1124 
1125 template< typename P >
1126 template< 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 
1134 template< typename P >
1135 template< typename P2, typename D >
1136  void
1138 {
1139  this_type( p, d ).swap( *this );
1140 }
1141 
1142 template< typename P >
1143 template< 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 
1150 template< typename P >
1151 template< 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 
1158 template< typename P >
1159  shared_ptr<P>::operator bool () const throw()
1160 {
1161  return px;
1162 }
1163 
1164 template< typename P >
1166  //typename shared_ptr<P>::reference
1168 {
1169  assert( px != 0 );
1170  return *px;
1171 }
1172 
1173 template< typename P >
1174  P *
1176 {
1177  assert( px != 0 );
1178  return px;
1179 }
1180 
1181 template< typename P >
1182  P *
1183  shared_ptr<P>::get() const throw()
1184 {
1185  return px;
1186 }
1187 
1188 template< typename P >
1189  bool
1190  shared_ptr<P>::unique() const throw()
1191 {
1192  return pn.unique();
1193 }
1194 
1195 template< typename P >
1196  long
1198 {
1199  return pn.use_count();
1200 }
1201 
1202 template< typename P >
1203 template< typename P2 >
1204  bool
1206 {
1207  return pn < rhs.pn;
1208 }
1209 
1210 template< 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 
1217 template< typename P >
1218  bool
1220 {
1221  return px == other.px && pn == other.pn;
1222 }
1223 
1224 template< typename P, typename P2 >
1225  bool
1227 {
1228  return a.get() == b.get();
1229 }
1230 
1231 template< typename P, typename P2 >
1232  bool
1234 {
1235  return a.get() != b.get();
1236 }
1237 
1238 template< 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 
1245 template< typename P >
1246  void
1248 {
1249  a.swap( b );
1250 }
1251 
1252 template< typename P, typename P2 >
1253  shared_ptr<P>
1255 {
1256  return shared_ptr<P>( other, sp::static_cast_tag() );
1257 }
1258 
1259 template< typename P, typename P2 >
1260  shared_ptr<P>
1262 {
1263  return shared_ptr<P>( other, sp::const_cast_tag() );
1264 }
1265 
1266 template< typename P, typename P2 >
1267  shared_ptr<P>
1269 {
1270  return shared_ptr<P>( other, sp::dynamic_cast_tag() );
1271 }
1272 
1273 template< typename P >
1274  P *
1276 {
1277  return p.get();
1278 }
1279 
1280 template< typename D, typename P >
1281  D *
1283 {
1284  return static_cast<D*>( p._internal_get_deleter( typeid(D)) );
1285 }
1286 
1287 template< 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 
1300 template< typename P >
1301  class weak_ptr
1302 {
1303  typedef weak_ptr<P> this_type;
1304 
1305  template< typename > friend class shared_ptr;
1306  template< typename > friend class weak_ptr;
1307 
1308 public:
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 
1343 private:
1344  P * px; // contained pointer
1345  sp::weak_ctrl_handle pn; // control information
1346 
1347 }; // weak_ptr
1348 
1349 template< typename P, typename P2 >
1350  inline bool operator < ( weak_ptr<P> const & a, weak_ptr<P2> const & b );
1351 
1352 template< typename P >
1353  inline void swap( weak_ptr<P> & a, weak_ptr<P> & b );
1354 
1355 template< typename P >
1356 weak_ptr<P>::weak_ptr() throw()
1357  : px( 0 )
1358  , pn( )
1359 { }
1360 
1361 template< typename P >
1362 template< typename P2 >
1365  ) throw()
1366  : px( r.lock().get() ) // same as r.px, but doesn't risk invalidation
1367  , pn( r.pn )
1368 { }
1369 
1370 template< typename P >
1371 template< typename P2 >
1374  ) throw()
1375  : px( r.px )
1376  , pn( r.pn )
1377 { }
1378 
1379 template< typename P >
1380 template< typename P2 >
1381  weak_ptr<P> &
1383 {
1384  px = r.lock().get();
1385  pn = r.pn;
1386  return *this;
1387 }
1388 
1389 template< typename P >
1390 template< typename P2 >
1391  weak_ptr<P> &
1393 {
1394  px = r.px;
1395  pn = r.pn;
1396  return *this;
1397 }
1398 
1399 template< typename P >
1401  weak_ptr<P>::lock() const throw()
1402 {
1403  return shared_ptr<element_type>( *this, sp::sp_nothrow_tag() );
1404 }
1405 
1406 template< typename P >
1407  long
1408  weak_ptr<P>::use_count() const throw()
1409 {
1410  return pn.use_count();
1411 }
1412 
1413 template< typename P >
1414  bool
1415  weak_ptr<P>::expired() const throw()
1416 {
1417  return pn.use_count() == 0;
1418 }
1419 
1420 template< typename P >
1421  bool
1422  weak_ptr<P>::_empty() const // extension, not in std::weak_ptr
1423 {
1424  return pn.empty();
1425 }
1426 
1427 template< typename P >
1428  void
1430 {
1431  this_type().swap(*this);
1432 }
1433 
1434 template< 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 
1442 template< typename P >
1443  void
1445 {
1446  px = px2;
1447  pn = pn2;
1448 }
1449 
1450 template< typename P >
1451 template< typename P2 >
1452  bool
1454 {
1455  return pn < rhs.pn;
1456 }
1457 
1458 template< 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 
1465 template< 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 
1481 void
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 
1500 template< typename T >
1501  class enable_shared_from_this
1502 {
1503 protected:
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 
1519 public:
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 
1536 public: // 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 
1547 private:
1548  mutable weak_ptr<T> weak_this_;
1549 }; // enable_shared_from_this<>
1550 
1551 
1552 // enable_shared_from_this2.hpp
1553 
1554 namespace detail
1555 {
1556 
1557 class esft2_deleter_wrapper
1558 {
1559 private:
1560  shared_ptr<void> deleter_;
1561 
1562 public:
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 
1584 template< typename T >
1585  class enable_shared_from_this2
1586 {
1587 protected:
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 
1605 private:
1606  mutable weak_ptr<T> weak_this_;
1607  mutable shared_ptr<T> shared_this_;
1608 
1609 public:
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 
1625 private:
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 
1638 public: // 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