CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

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