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

memory.h

Go to the documentation of this file.
00001 #ifndef CLHEP_MEMORY_H
00002 #define CLHEP_MEMORY_H
00003 
00004 // ======================================================================
00005 //
00006 // memory - memory management utilities
00007 //
00008 // Note:  the following adaptation of the C++0X std::shared_ptr/weak_ptr
00009 // interface and semantics has been customized for the specific internal
00010 // needs of CLHEP/Random; it neither has nor needs the full generality
00011 // of its namesake.
00012 //
00013 // Author:  W. E. Brown, 2010-03-19, adapted from the boost library's
00014 // shared_ptr and related functionality whose internal attributions bear
00015 // the following various notices:
00016 //
00017 //   (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
00018 //   Copyright (c) 2001, 2002, 2003 Peter Dimov
00019 //   Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00020 //   Copyright (c) 2001-2008 Peter Dimov
00021 //   Copyright (c) 2001-2009 Peter Dimov
00022 //   Copyright 2002, 2009 Peter Dimov
00023 //   Copyright 2004-2005 Peter Dimov
00024 //   Copyright 2004-2008 Peter Dimov
00025 //   Copyright 2005, 2006 Peter Dimov
00026 //   Copyright 2008 Frank Mori Hess
00027 //   Copyright 2008 Peter Dimov
00028 //   Distributed under the Boost Software License, Version 1.0.
00029 //   See http://www.boost.org/LICENSE_1_0.txt
00030 //
00031 // ======================================================================
00032 
00033 // don't generate unnecessary warnings
00034 #if defined __GNUC__ 
00035   #if __GNUC__ > 3 && __GNUC_MINOR__ > 6
00036     #pragma GCC diagnostic push
00037     #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
00038   #endif
00039 #endif 
00040 #ifdef __clang__
00041   #pragma clang diagnostic push
00042   #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
00043 #endif
00044 
00045 #include "CLHEP/Utility/defs.h"
00046 #include "CLHEP/Utility/noncopyable.h"
00047 #include "CLHEP/Utility/type_traits.h"
00048 
00049 #include <algorithm>  // for swap
00050 #include <cassert>    // for assert macro
00051 #include <cstddef>    // for size_t
00052 #include <exception>  // for exception
00053 #include <functional> // for less
00054 #include <iosfwd>     // for basic_ostream
00055 #include <memory>     // for allocator, auto_ptr
00056 #include <typeinfo>   // for bad_cast, type_info
00057 
00058 
00059 namespace CLHEP {
00060 
00061 
00062 // ----------------------------------------------------------------------
00063 // forward declarations
00064 // ----------------------------------------------------------------------
00065 
00066 template< typename T > class shared_ptr;
00067 template< typename T > class weak_ptr;
00068 template< typename T > class enable_shared_from_this;
00069 template< typename T > class enable_shared_from_this2;
00070 
00071 
00072 // ----------------------------------------------------------------------
00073 // bad_weak_ptr - exception thrown when a stale weak_ptr is encountered
00074 // ----------------------------------------------------------------------
00075 
00076 class bad_weak_ptr
00077   : public std::exception
00078 {
00079 public:
00080   inline  virtual  char const *  what() const throw();
00081 
00082 };  // bad_weak_ptr
00083 
00084 char const *
00085   bad_weak_ptr::what() const throw()
00086 {
00087   return "bad_weak_ptr";
00088 }
00089 
00090 
00091 namespace sp {
00092 
00093 
00094 // ----------------------------------------------------------------------
00095 // abstract_ctrl_block - shared_ptr's counters and type-erased deleter
00096 // ----------------------------------------------------------------------
00097 
00098 class abstract_ctrl_block
00099   : public noncopyable
00100 {
00101 public:
00102   inline  void  class_invariant() const throw();
00103   // class class_invariant
00104 
00105   inline           abstract_ctrl_block();
00106   inline  virtual  ~abstract_ctrl_block() throw();
00107   // constructor and destructor
00108 
00109   inline           void    add_ref();
00110   inline           bool    add_ref_lock();
00111   inline           void    weak_add_ref() throw();
00112           virtual  void *  get_deleter( std::type_info const & ti ) = 0;
00113   inline           void    release() throw();
00114   inline           void    weak_release() throw();
00115           virtual  void    dispose() throw() = 0;
00116   inline  virtual  void    destroy() throw();
00117   // resource management functions
00118 
00119   inline  long use_count() const throw();
00120   // accessor
00121 
00122 private:
00123   int  n_shared_ptrs;
00124   int  n_weak_ptrs;
00125 
00126 };  // abstract_ctrl_block
00127 
00128 void
00129   abstract_ctrl_block::class_invariant() const throw()
00130 {
00131   assert( n_shared_ptrs == 0  || n_weak_ptrs >= 1 );
00132 }
00133 
00134 abstract_ctrl_block::abstract_ctrl_block()
00135   : n_shared_ptrs( 1 )
00136   , n_weak_ptrs  ( 1 )
00137 {
00138   class_invariant();
00139 }
00140 
00141 abstract_ctrl_block::~abstract_ctrl_block() throw()
00142 {
00143   class_invariant();
00144 }
00145 
00146 void
00147   abstract_ctrl_block::add_ref()
00148 {
00149   class_invariant();
00150   ++n_shared_ptrs;
00151 }
00152 
00153 bool
00154   abstract_ctrl_block::add_ref_lock()  // true on success
00155 {
00156   class_invariant();
00157   return n_shared_ptrs ? ++n_shared_ptrs : false;
00158 }
00159 
00160 void
00161   abstract_ctrl_block::weak_add_ref() throw()
00162 {
00163   class_invariant();
00164   ++n_weak_ptrs;
00165 }
00166 
00167 void
00168   abstract_ctrl_block::release() throw()
00169 {
00170   class_invariant();
00171   if( 0 == --n_shared_ptrs )
00172     dispose(), weak_release();
00173 }
00174 
00175 void
00176   abstract_ctrl_block::weak_release() throw()
00177 {
00178   class_invariant();
00179   if( 0 == --n_weak_ptrs )
00180     destroy();
00181 }
00182 
00183 void
00184   abstract_ctrl_block::destroy() throw()
00185 {
00186   assert( n_weak_ptrs == 0 );
00187   delete this;
00188 }
00189 
00190 long
00191   abstract_ctrl_block::use_count() const throw()
00192 {
00193   class_invariant();
00194   return n_shared_ptrs;
00195 }
00196 
00197 
00198 // ----------------------------------------------------------------------
00199 // concrete ctrl_block_* variations:
00200 //   ctrl_block_p  : owned pointer only; no deleter, no allocator
00201 //   ctrl_block_pd : owned pointer and deleter only; no allocator
00202 //   ctrl_block_pda: owned pointer, deleter, and allocator
00203 // ----------------------------------------------------------------------
00204 
00205 template< typename P >  // P is pointee type
00206   class ctrl_block_p
00207     : public abstract_ctrl_block
00208 {
00209   typedef ctrl_block_p<P> this_type;
00210 
00211 public:
00212   inline  explicit ctrl_block_p( P * );
00213   inline           ~ctrl_block_p() throw();
00214   // constructor and destructor
00215 
00216   inline  void *  operator new ( std::size_t );
00217   inline  void    operator delete ( void * );
00218   // allocation functions
00219 
00220   inline  virtual  void *  get_deleter( std::type_info const & );
00221   inline  virtual  void    dispose() throw();
00222   // resource management functions
00223 
00224 private:
00225   P *  owned_ptr;
00226 
00227 };  // ctrl_block_p
00228 
00229 template< typename P >
00230 ctrl_block_p<P>::ctrl_block_p( P * p )
00231   : abstract_ctrl_block( )
00232   , owned_ptr( p )
00233 { }
00234 
00235 template< typename P >
00236 ctrl_block_p<P>::~ctrl_block_p() throw()
00237 { }
00238 
00239 template< typename P >
00240 void
00241   ctrl_block_p<P>::dispose() throw()
00242 {
00243   delete owned_ptr;
00244 }
00245 
00246 template< typename P >
00247 void *
00248   ctrl_block_p<P>::get_deleter( std::type_info const & )
00249 {
00250   return 0;
00251 }
00252 
00253 template< typename P >
00254 void *
00255   ctrl_block_p<P>::operator new ( std::size_t )
00256 {
00257   return std::allocator<this_type>().allocate( 1 );
00258 }
00259 
00260 template< typename P >
00261 void
00262   ctrl_block_p<P>::operator delete ( void * p )
00263 {
00264   std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
00265 }
00266 
00267 template< typename P  // pointee type
00268         , typename D  // deleter type
00269         >
00270   class ctrl_block_pd
00271     : public abstract_ctrl_block
00272 {
00273   typedef ctrl_block_pd<P,D> this_type;
00274 
00275 public:
00276   inline  ctrl_block_pd( P *, D );
00277   inline  ~ctrl_block_pd() throw();
00278   // constructor and destructor
00279 
00280   inline  void *  operator new ( std::size_t );
00281   inline  void    operator delete ( void * );
00282   // allocation functions
00283 
00284   inline  virtual  void *  get_deleter( std::type_info const & );
00285   inline  virtual  void    dispose() throw();
00286   // resource management functions
00287 
00288 private:
00289   P *  owned_ptr;
00290   D    deleter;   // D's copy constructor must not throw, and
00291                   // call to deleter( owned_ptr ) must not throw
00292 
00293 };  // ctrl_block_pd
00294 
00295 template< typename P, typename D >
00296 ctrl_block_pd<P,D>::ctrl_block_pd( P * p, D d )
00297   : abstract_ctrl_block( )
00298   , owned_ptr( p )
00299   , deleter  ( d )
00300 { }
00301 
00302 template< typename P, typename D >
00303 ctrl_block_pd<P,D>::~ctrl_block_pd() throw()
00304 { }
00305 
00306 template< typename P, typename D >
00307 void
00308   ctrl_block_pd<P,D>::dispose() throw()
00309 {
00310   deleter( owned_ptr );
00311 }
00312 
00313 template< typename P, typename D >
00314 void *
00315   ctrl_block_pd<P,D>::get_deleter( std::type_info const & ti )
00316 {
00317   return ti == typeid(D) ? &reinterpret_cast<char&>( deleter ) : 0;
00318 }
00319 
00320 template< typename P, typename D >
00321 void *
00322   ctrl_block_pd<P,D>::operator new ( std::size_t )
00323 {
00324   return std::allocator<this_type>().allocate( 1 );
00325 }
00326 
00327 template< typename P, typename D >
00328 void
00329   ctrl_block_pd<P,D>::operator delete ( void * p )
00330 {
00331   std::allocator<this_type>().deallocate( static_cast<this_type*>(p), 1 );
00332 }
00333 
00334 template< typename P  // pointee type
00335         , typename D  // deleter type
00336         , typename A  // allocator type
00337         >
00338   class ctrl_block_pda
00339     : public abstract_ctrl_block
00340 {
00341   typedef ctrl_block_pda<P,D,A> this_type;
00342 
00343 public:
00344   inline  ctrl_block_pda( P *, D, A );
00345   inline  ~ctrl_block_pda() throw();
00346   // constructor and destructor
00347 
00348   inline  virtual  void *  get_deleter( std::type_info const & );
00349   inline  virtual  void    dispose() throw();
00350   inline  virtual  void    destroy() throw();
00351   // resource management functions
00352 
00353 private:
00354   P *  owned_ptr;
00355   D    deleter;   // D's copy constructor must not throw, and
00356                   // call to deleter( owned_ptr ) must not throw
00357   A    allocator; // A's copy constructor must not throw
00358 
00359 };  // ctrl_block_pda
00360 
00361 template< typename P, typename D, typename A >
00362 ctrl_block_pda<P,D,A>::ctrl_block_pda( P * p, D d, A a )
00363   : abstract_ctrl_block( )
00364   , owned_ptr( p )
00365   , deleter  ( d )
00366   , allocator( a )
00367 { }
00368 
00369 template< typename P, typename D, typename A >
00370 ctrl_block_pda<P,D,A>::~ctrl_block_pda() throw()
00371 { }
00372 
00373 template< typename P, typename D, typename A >
00374 void
00375   ctrl_block_pda<P,D,A>::dispose() throw()
00376 {
00377   deleter( owned_ptr );
00378 }
00379 
00380 template< typename P, typename D, typename A >
00381 void
00382   ctrl_block_pda<P,D,A>::destroy() throw()
00383 {
00384   typename A::template rebind< this_type >::other  this_allocator( allocator );
00385 
00386   this_allocator.destroy( this );  // this->~this_type();
00387   this_allocator.deallocate( this, 1 );
00388 }
00389 
00390 template< typename P, typename D, typename A >
00391 void *
00392   ctrl_block_pda<P,D,A>::get_deleter( std::type_info const & ti )
00393 {
00394   return ti == typeid( D ) ? &reinterpret_cast<char&>( deleter ) : 0;
00395 }
00396 
00397 
00398 // ----------------------------------------------------------------------
00399 // shared_ctrl_handle, weak_ctrl_handle - ctrl block handles
00400 // ----------------------------------------------------------------------
00401 
00402 class shared_ctrl_handle;
00403 class weak_ctrl_handle;
00404 
00405 struct sp_nothrow_tag { };
00406 
00407 class shared_ctrl_handle
00408 {
00409   friend  class weak_ctrl_handle;
00410 
00411 public:
00412   inline  shared_ctrl_handle() throw();
00413   template< typename P >
00414     inline  explicit
00415     shared_ctrl_handle( P * );
00416   template< typename P, typename D >
00417     inline  shared_ctrl_handle( P *, D );
00418   template< typename P, typename D, typename A >
00419     inline  shared_ctrl_handle( P *, D, A );
00420   template< typename P >
00421     inline  explicit
00422     shared_ctrl_handle( std::auto_ptr<P> & );
00423   inline  ~shared_ctrl_handle() throw();
00424   // constructors and destructor
00425 
00426   inline  void  swap( shared_ctrl_handle & ) throw();
00427   inline  shared_ctrl_handle( shared_ctrl_handle const & ) throw();
00428   inline  shared_ctrl_handle &
00429     operator = ( shared_ctrl_handle const & ) throw();
00430   // copy functions
00431 
00432   inline  explicit
00433     shared_ctrl_handle( weak_ctrl_handle const & );
00434   inline  shared_ctrl_handle( weak_ctrl_handle const &, sp_nothrow_tag );
00435   // copy-like functions
00436 
00437   inline  void *  get_deleter( std::type_info const & ) const;
00438   inline  bool    unique() const throw();
00439   inline  bool    empty() const throw();
00440   inline  long    use_count() const throw();
00441   // accessors
00442 
00443   friend inline
00444   bool
00445     operator == ( shared_ctrl_handle const &, shared_ctrl_handle const & );
00446   friend inline
00447   bool
00448     operator < ( shared_ctrl_handle const &, shared_ctrl_handle const & );
00449   // comparisons
00450 
00451 private:
00452   abstract_ctrl_block *  acb_ptr;
00453 
00454 };  // shared_ctrl_handle
00455 
00456 shared_ctrl_handle::shared_ctrl_handle() throw()
00457   : acb_ptr( 0 )
00458 { }
00459 
00460 template< typename P >
00461   shared_ctrl_handle::shared_ctrl_handle( P * p )
00462   // a fctn-try block would be slightly more efficient here,
00463   // but some older compilers don't understand it
00464   : acb_ptr( 0 )
00465 {
00466   try  {
00467     acb_ptr = new ctrl_block_p<P>(p);
00468   }
00469   catch(...)  {
00470     delete p;
00471     throw;
00472   }
00473 }
00474 
00475 template< typename P, typename D >
00476   shared_ctrl_handle::shared_ctrl_handle( P * p, D d )
00477   // a fctn-try block would be slightly more efficient here,
00478   // but some older compilers don't understand it
00479   : acb_ptr( 0 )
00480 {
00481   try  {
00482     acb_ptr = new ctrl_block_pd<P,D>(p, d);
00483   }
00484   catch(...)  {
00485     d( p );
00486     throw;
00487   }
00488 }
00489 
00490 template< typename P, typename D, typename A >
00491   shared_ctrl_handle::shared_ctrl_handle( P * p, D d, A a )
00492   : acb_ptr( 0 )
00493 {
00494   typedef  ctrl_block_pda<P,D,A>
00495            ctrl_block;
00496   typedef  typename A::template rebind<ctrl_block>::other
00497            ctrl_block_allocator;
00498   ctrl_block_allocator cba( a );
00499 
00500   try
00501   {
00502     acb_ptr = cba.allocate( 1 );
00503     new( static_cast<void*>(acb_ptr) ) ctrl_block(p, d, a);
00504   }
00505   catch(...)
00506   {
00507     d( p );
00508     if( acb_ptr != 0 )
00509       cba.deallocate( static_cast<ctrl_block*>( acb_ptr ), 1 );
00510     throw;
00511   }
00512 }
00513 
00514 template< typename P >
00515   shared_ctrl_handle::shared_ctrl_handle( std::auto_ptr<P> & p )
00516     : acb_ptr( new ctrl_block_p<P>( p.get() ) )
00517 {
00518   p.release();
00519 }
00520 
00521 shared_ctrl_handle::~shared_ctrl_handle() throw()
00522 {
00523   if( acb_ptr != 0 )
00524     acb_ptr->release();
00525 }
00526 
00527 void
00528   shared_ctrl_handle::swap( shared_ctrl_handle & other ) throw()
00529 {
00530   abstract_ctrl_block * tmp = other.acb_ptr;
00531   other.acb_ptr = acb_ptr;
00532   acb_ptr = tmp;
00533 }
00534 
00535 shared_ctrl_handle::shared_ctrl_handle( shared_ctrl_handle const & other ) throw()
00536   : acb_ptr( other.acb_ptr )
00537 {
00538   if( acb_ptr != 0 )
00539     acb_ptr->add_ref();
00540 }
00541 
00542 shared_ctrl_handle &
00543   shared_ctrl_handle::operator = ( shared_ctrl_handle const & other ) throw()
00544 {
00545   abstract_ctrl_block * tmp = other.acb_ptr;
00546 
00547   if( tmp != acb_ptr )
00548   {
00549     if( tmp     != 0 ) tmp->add_ref();
00550     if( acb_ptr != 0 ) acb_ptr->release();
00551     acb_ptr = tmp;
00552   }
00553 
00554   return *this;
00555 }
00556 
00557 void *
00558   shared_ctrl_handle::get_deleter( std::type_info const & ti ) const
00559 {
00560   return acb_ptr ? acb_ptr->get_deleter( ti ) : 0;
00561 }
00562 
00563 bool
00564   shared_ctrl_handle::unique() const throw()
00565 {
00566   return 1L == use_count();
00567 }
00568 
00569 bool
00570   shared_ctrl_handle::empty() const throw()
00571 {
00572   return acb_ptr == 0;
00573 }
00574 
00575 long
00576   shared_ctrl_handle::use_count() const throw()
00577 {
00578   return acb_ptr == 0 ? 0L : acb_ptr->use_count();
00579 }
00580 
00581 bool
00582   operator == ( shared_ctrl_handle const & lhs, shared_ctrl_handle const & rhs )
00583 {
00584   return lhs.acb_ptr == rhs.acb_ptr;
00585 }
00586 
00587 bool
00588   operator < ( shared_ctrl_handle const & lhs, shared_ctrl_handle const & rhs )
00589 {
00590   return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
00591 }
00592 
00593 class weak_ctrl_handle
00594 {
00595   friend  class shared_ctrl_handle;
00596 
00597 public:
00598 
00599   inline  weak_ctrl_handle() throw();
00600   inline  weak_ctrl_handle( shared_ctrl_handle const & ) throw();
00601   inline  ~weak_ctrl_handle() throw();
00602   // constructors and destructor
00603 
00604   inline  void  swap( weak_ctrl_handle & ) throw();
00605   inline  weak_ctrl_handle( weak_ctrl_handle const & ) throw();
00606   inline  weak_ctrl_handle & operator = ( shared_ctrl_handle const & ) throw();
00607   // copy functions
00608 
00609   inline  weak_ctrl_handle & operator = ( weak_ctrl_handle const & ) throw();
00610   // copy-like functions
00611 
00612   inline  bool  empty() const throw();
00613   inline  long  use_count() const throw();
00614   // accessors
00615 
00616   friend inline
00617   bool
00618     operator == ( weak_ctrl_handle const &, weak_ctrl_handle const & );
00619   friend inline
00620   bool
00621     operator < ( weak_ctrl_handle const &, weak_ctrl_handle const & );
00622   // comparisons
00623 
00624 private:
00625   abstract_ctrl_block *  acb_ptr;
00626 
00627 };  // weak_ctrl_handle
00628 
00629 weak_ctrl_handle::weak_ctrl_handle() throw()
00630   : acb_ptr( 0 )
00631 { }
00632 
00633 weak_ctrl_handle::weak_ctrl_handle( shared_ctrl_handle const & other ) throw()
00634   : acb_ptr( other.acb_ptr )
00635 {
00636   if( acb_ptr != 0 )
00637     acb_ptr->weak_add_ref();
00638 }
00639 
00640 weak_ctrl_handle::~weak_ctrl_handle() throw()
00641 {
00642   if( acb_ptr != 0 )
00643     acb_ptr->weak_release();
00644 }
00645 
00646 void
00647   weak_ctrl_handle::swap( weak_ctrl_handle & other ) throw()
00648 {
00649   abstract_ctrl_block *  tmp = other.acb_ptr;
00650   other.acb_ptr = acb_ptr;
00651   acb_ptr = tmp;
00652 }
00653 
00654 weak_ctrl_handle::weak_ctrl_handle( weak_ctrl_handle const & other ) throw()
00655   : acb_ptr( other.acb_ptr )
00656 {
00657   if( acb_ptr != 0 )
00658     acb_ptr->weak_add_ref();
00659 }
00660 
00661 weak_ctrl_handle &
00662   weak_ctrl_handle::operator = ( shared_ctrl_handle const & other ) throw()
00663 {
00664   abstract_ctrl_block *  tmp = other.acb_ptr;
00665 
00666   if( tmp != acb_ptr )
00667   {
00668     if( tmp     != 0 ) tmp->weak_add_ref();
00669     if( acb_ptr != 0 ) acb_ptr->weak_release();
00670     acb_ptr = tmp;
00671 }
00672 
00673   return *this;
00674 }
00675 
00676 weak_ctrl_handle &
00677   weak_ctrl_handle::operator = ( weak_ctrl_handle const & other ) throw()
00678 {
00679   abstract_ctrl_block *  tmp = other.acb_ptr;
00680 
00681   if( tmp != acb_ptr )
00682 {
00683     if( tmp     != 0 ) tmp->weak_add_ref();
00684     if( acb_ptr != 0 ) acb_ptr->weak_release();
00685     acb_ptr = tmp;
00686 }
00687 
00688   return *this;
00689 }
00690 
00691 bool
00692   weak_ctrl_handle::empty() const throw()
00693 {
00694   return acb_ptr == 0;
00695 }
00696 
00697 long
00698   weak_ctrl_handle::use_count() const throw()
00699 {
00700   return acb_ptr == 0 ? 0L : acb_ptr->use_count();
00701 }
00702 
00703 bool
00704   operator == ( weak_ctrl_handle const & lhs, weak_ctrl_handle const & rhs )
00705 {
00706   return lhs.acb_ptr == rhs.acb_ptr;
00707 }
00708 
00709 bool
00710   operator < ( weak_ctrl_handle const & lhs, weak_ctrl_handle const & rhs )
00711 {
00712   return std::less<abstract_ctrl_block*>()( lhs.acb_ptr, rhs.acb_ptr );
00713 }
00714 
00715 shared_ctrl_handle::shared_ctrl_handle( weak_ctrl_handle const & other )
00716   : acb_ptr( other.acb_ptr )
00717 {
00718   if( acb_ptr == 0  ||  ! acb_ptr->add_ref_lock() )
00719     throw bad_weak_ptr();
00720 }
00721 
00722 shared_ctrl_handle::shared_ctrl_handle( weak_ctrl_handle const & other
00723                                       , sp_nothrow_tag )
00724   : acb_ptr( other.acb_ptr )
00725 {
00726   if( acb_ptr != 0  &&  ! acb_ptr->add_ref_lock() )
00727     acb_ptr = 0;
00728 }
00729 
00730 
00731 // ----------------------------------------------------------------------
00732 // cast tags
00733 // ----------------------------------------------------------------------
00734 
00735 struct static_cast_tag      { };
00736 struct const_cast_tag       { };
00737 struct dynamic_cast_tag     { };
00738 struct polymorphic_cast_tag { };
00739 
00740 
00741 // ----------------------------------------------------------------------
00742 // shared_ptr_traits - specify dependent types
00743 // ----------------------------------------------------------------------
00744 
00745 template< typename T >
00746   struct shared_ptr_traits
00747 {
00748   typedef  T &  reference;
00749 };
00750 
00751 template<>
00752   struct shared_ptr_traits<void>
00753 {
00754   typedef  void  reference;
00755 };
00756 
00757 template<>
00758   struct shared_ptr_traits<void const>
00759 {
00760   typedef  void  reference;
00761 };
00762 
00763 template<>
00764   struct shared_ptr_traits<void volatile>
00765 {
00766   typedef  void  reference;
00767 };
00768 
00769 template<>
00770   struct shared_ptr_traits<void const volatile>
00771 {
00772   typedef  void  reference;
00773 };
00774 
00775 
00776 // ----------------------------------------------------------------------
00777 // enable_shared_from_this support
00778 // ----------------------------------------------------------------------
00779 
00780 template< typename X, typename Y, typename T >
00781 inline void
00782   sp_enable_shared_from_this( shared_ptr<X>              const * ppx
00783                             , Y                          const * py
00784                             , enable_shared_from_this<T> const * pe
00785                             )
00786 {
00787   if( pe != 0 )
00788     pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
00789 }
00790 
00791 template< typename X, typename Y, typename T >
00792 inline void
00793   sp_enable_shared_from_this( shared_ptr<X>                     * ppx
00794                             , Y                           const * py
00795                             , enable_shared_from_this2<T> const * pe
00796                             )
00797 {
00798   if( pe != 0 )
00799     pe->_internal_accept_owner( ppx, const_cast<Y*>( py ) );
00800 }
00801 
00802 inline void
00803   sp_enable_shared_from_this( ... )
00804 { }
00805 
00806 }  // namespace sp
00807 
00808 
00809 // ----------------------------------------------------------------------
00810 // shared_ptr - "if you are the last person, please turn out the light"
00811 // ----------------------------------------------------------------------
00812 
00813 template< typename P >  // pointee type
00814   class shared_ptr
00815 {
00816   typedef  shared_ptr<P>                                 this_type;
00817   typedef  typename sp::shared_ptr_traits<P>::reference  reference;
00818 
00819   template< typename >  friend  class shared_ptr;
00820   template< typename >  friend  class weak_ptr;
00821 
00822 public:
00823   typedef  P  element_type;
00824   // pointee type
00825 
00826   shared_ptr() throw();
00827   template< typename P2 >
00828     inline  explicit
00829     shared_ptr( P2 * );
00830   template< typename P2, typename D >
00831     inline  shared_ptr( P2 *, D );
00832   template< typename P2, typename D, typename A >
00833     inline  shared_ptr( P2 *, D, A );
00834   // constructors
00835 
00836   inline  void          swap( shared_ptr<P> & ) throw();
00837   inline  shared_ptr &  operator = ( shared_ptr const & ) throw();
00838   // copy functions; generated copy constructor, destructor are fine
00839 
00840   template< typename P2 >
00841     inline  explicit
00842     shared_ptr( weak_ptr<P2> const & );
00843   template< typename P2 >
00844     inline  shared_ptr( weak_ptr<P2> const &, sp::sp_nothrow_tag ) throw();
00845   template< typename P2 >
00846     inline  shared_ptr( shared_ptr<P2> const &, P * ) throw();
00847   template< typename P2 >
00848     inline  shared_ptr( shared_ptr<P2> const &, sp::static_cast_tag );
00849   template< typename P2 >
00850     inline  shared_ptr( shared_ptr<P2> const &, sp::const_cast_tag );
00851   template< typename P2 >
00852     inline  shared_ptr( shared_ptr<P2> const &, sp::dynamic_cast_tag );
00853   template< typename P2 >
00854     inline  shared_ptr( shared_ptr<P2> const &, sp::polymorphic_cast_tag );
00855   template< typename P2 >
00856     inline  explicit
00857     shared_ptr( std::auto_ptr<P2> & );
00858   template< typename AP >
00859     inline  explicit
00860     shared_ptr( AP
00861               , typename enable_if_auto_ptr<AP,void*>::type = 0
00862               );
00863   template< typename P2 >
00864     inline
00865     shared_ptr( shared_ptr<P2> const &
00866               , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
00867               ) throw();
00868   template< typename P2 >
00869     inline  shared_ptr &  operator = ( shared_ptr<P2> const & ) throw();
00870   template< typename P2 >
00871     inline  shared_ptr &  operator = ( std::auto_ptr<P2> & );
00872   template< typename AP >
00873     inline  typename enable_if_auto_ptr< AP, shared_ptr & >::type
00874     operator = ( AP );
00875   // copy-like functions
00876 
00877   inline  void reset() throw();
00878   template< typename P2 >
00879     inline  void  reset( P2 * );
00880   template< typename P2, typename D >
00881     inline  void  reset( P2 *, D );
00882   template< typename P2, typename D, typename A >
00883     inline  void  reset( P2 *, D, A );
00884   template< typename P2 >
00885     inline  void  reset( shared_ptr<P2> const &, P * );
00886   // reset functions
00887 
00888              inline  operator bool () const throw();
00889   inline  reference  operator *    () const throw();
00890   inline  P *        operator ->   () const throw();
00891   // pointer-like behavior
00892 
00893   inline  P *      get() const throw();
00894   inline  bool     unique() const throw();
00895   inline  long     use_count() const throw();
00896   // accessors
00897 
00898   template< typename P2 >
00899     inline  bool _internal_less( shared_ptr<P2> const & ) const;
00900   inline  void *  _internal_get_deleter( std::type_info const & ) const;
00901   inline  bool    _internal_equiv( shared_ptr const & ) const;
00902   // implementation helpers -- do not use
00903 
00904 private:
00905   P *                    px;  // contained pointer
00906   sp::shared_ctrl_handle pn;  // control information
00907 
00908 };  // shared_ptr
00909 
00910 template< typename P, typename P2 >
00911   inline bool  operator == ( shared_ptr<P> const &, shared_ptr<P2> const & );
00912 template< typename P, typename P2 >
00913   inline bool  operator != ( shared_ptr<P> const &, shared_ptr<P2> const & );
00914 template< typename P, typename P2 >
00915   inline bool  operator <  ( shared_ptr<P> const &, shared_ptr<P2> const & );
00916 
00917 template< typename P >
00918   inline void  swap( shared_ptr<P> &, shared_ptr<P> & );
00919 
00920 template< typename P, typename P2 >
00921   inline shared_ptr<P>  static_pointer_cast( shared_ptr<P2> const & );
00922 template< typename P, typename P2 >
00923   inline shared_ptr<P>  const_pointer_cast( shared_ptr<P2> const & );
00924 template< typename P, typename P2 >
00925   inline shared_ptr<P>  dynamic_pointer_cast( shared_ptr<P2> const & );
00926 
00927 template< typename P >
00928   inline P *  get_pointer( shared_ptr<P> const & );
00929 template< typename D, typename P >
00930   inline D *  get_deleter( shared_ptr<P> const & );
00931 
00932 template< typename C, typename T, typename P >
00933   inline std::basic_ostream<C,T> &  operator << ( std::basic_ostream<C,T> &
00934                                                 , shared_ptr<P> const &
00935                                                 );
00936 
00937 template< typename P >
00938   shared_ptr<P>::shared_ptr() throw()
00939   : px( 0 )
00940   , pn(         )
00941 { }
00942 
00943 template< typename P >
00944 template< typename P2 >  // P2 must be a complete type
00945   shared_ptr<P>::shared_ptr( P2 * p )
00946   : px( p )
00947   , pn( p )
00948 {
00949   sp::sp_enable_shared_from_this( this, p, p );
00950 }
00951 
00952 template< typename P >
00953 template< typename P2, typename D >  // D's copy c'tor must not throw
00954   shared_ptr<P>::shared_ptr( P2 * p, D d )
00955   : px( p    )
00956   , pn( p, d )
00957 {
00958   sp::sp_enable_shared_from_this( this, p, p );
00959 }
00960 
00961 template< typename P >
00962 template< typename P2, typename D, typename A >  // D's, A's copy c'tors must not throw
00963   shared_ptr<P>::shared_ptr( P2 * p, D d, A a )
00964   : px( p       )
00965   , pn( p, d, a )
00966 {
00967   sp::sp_enable_shared_from_this( this, p, p );
00968 }
00969 
00970 template< typename P >
00971   void
00972   shared_ptr<P>::swap( shared_ptr<P> & other ) throw()
00973 {
00974   std::swap( px, other.px );
00975   pn.swap( other.pn );
00976 }
00977 
00978 template< typename P >
00979   shared_ptr<P> &
00980   shared_ptr<P>::operator = ( shared_ptr const & other ) throw()
00981 {
00982   this_type( other ).swap( *this );
00983   return *this;
00984 }
00985 
00986 template< typename P >
00987 template< typename P2 >
00988   shared_ptr<P>::shared_ptr( weak_ptr<P2> const & other )
00989   : px( 0  )  // temporarily
00990   , pn( other.pn )  // may throw
00991 {
00992   px = other.px;  // safe to copy other.px, as pn(other.pn) did not throw
00993 }
00994 
00995 template< typename P >
00996 template< typename P2 >
00997   shared_ptr<P>::shared_ptr( weak_ptr<P2> const & other
00998                            , sp::sp_nothrow_tag
00999                            ) throw()
01000   : px( 0                        )  // temporarily
01001   , pn( other.pn, sp::sp_nothrow_tag() )
01002 {
01003   if( ! pn.empty() )
01004     px = other.px;
01005 }
01006 
01007 template< typename P >
01008 template< typename P2 >
01009   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01010                            , P * p
01011                            ) throw()
01012   : px( p        )
01013   , pn( other.pn )
01014 { }
01015 
01016 template< typename P >
01017 template< typename P2 >
01018   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01019                            , sp::static_cast_tag
01020                            )
01021   : px( static_cast<element_type*>( other.px ) )
01022   , pn( other.pn                               )
01023 { }
01024 
01025 template< typename P >
01026 template< typename P2 >
01027   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01028                            , sp::const_cast_tag
01029                            )
01030   : px( const_cast<element_type*>( other.px ) )
01031   , pn( other.pn                              )
01032 { }
01033 
01034 template< typename P >
01035 template< typename P2 >
01036   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01037                            , sp::dynamic_cast_tag
01038                            )
01039   : px( dynamic_cast<element_type*>( other.px ) )
01040   , pn( other.pn                                )
01041 {
01042   if( px == 0 )               // cast failed?
01043     pn = sp::shared_ctrl_handle();  // yes; need our own control information
01044 }
01045 
01046 template< typename P >
01047 template< typename P2 >
01048   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01049                            , sp::polymorphic_cast_tag
01050                            )
01051   : px( dynamic_cast<element_type*>( other.px ) )
01052   , pn( other.pn                                )
01053 {
01054   if( px == 0 )
01055     throw std::bad_cast();
01056 }
01057 
01058 template< typename P >
01059 template< typename P2 >
01060   shared_ptr<P>::shared_ptr( std::auto_ptr<P2> & other )
01061   : px( other.get() )
01062   , pn(             )  // temporarily
01063 {
01064   P2 *  tmp = other.get();
01065   pn = sp::shared_ctrl_handle( other );
01066   sp::sp_enable_shared_from_this( this, tmp, tmp );
01067 }
01068 
01069 template< typename P >
01070 template< typename AP >
01071   shared_ptr<P>::shared_ptr( AP other
01072                            , typename enable_if_auto_ptr<AP,void*>::type
01073                            )
01074   : px( other.get() )
01075   , pn(             )  // temporarily
01076 {
01077   typename AP::element_type *  tmp = other.get();
01078   pn = sp::shared_ctrl_handle( other );
01079   sp::sp_enable_shared_from_this( this, tmp, tmp );
01080 }
01081 
01082 template< typename P >
01083 template< typename P2 >
01084   shared_ptr<P>::shared_ptr( shared_ptr<P2> const & other
01085                            , typename enable_if_ptr_convertible<P2,P,void*>::type
01086                            ) throw()
01087   : px( other.px )
01088   , pn( other.pn )
01089   { }
01090 
01091 template< typename P >
01092 template< typename P2 >
01093   shared_ptr<P> &
01094   shared_ptr<P>::operator = ( shared_ptr<P2> const & other ) throw()
01095 {
01096   this_type( other ).swap( *this );
01097   return *this;
01098 }
01099 
01100 template< typename P >
01101 template< typename P2 >
01102   shared_ptr<P> &
01103   shared_ptr<P>::operator = ( std::auto_ptr<P2> & other )
01104 {
01105   this_type( other ).swap( *this );
01106   return *this;
01107 }
01108 
01109 template< typename P >
01110 template< typename AP >
01111   typename enable_if_auto_ptr< AP, shared_ptr<P> & >::type
01112   shared_ptr<P>::operator = ( AP other )
01113 {
01114   this_type( other ).swap( *this );
01115   return *this;
01116 }
01117 
01118 template< typename P >
01119   void
01120   shared_ptr<P>::reset() throw()
01121 {
01122   this_type().swap( *this );
01123 }
01124 
01125 template< typename P >
01126 template< typename P2 >
01127   void
01128   shared_ptr<P>::reset( P2 * p )  // P2 must be a complete type
01129 {
01130   assert( p == 0 || p != px );  // oughtn't reset oneself
01131   this_type( p ).swap( *this );
01132 }
01133 
01134 template< typename P >
01135 template< typename P2, typename D >
01136   void
01137   shared_ptr<P>::reset( P2 * p, D d )
01138 {
01139   this_type( p, d ).swap( *this );
01140 }
01141 
01142 template< typename P >
01143 template< typename P2, typename D, typename A >
01144   void
01145   shared_ptr<P>::reset( P2 * p, D d, A a )
01146 {
01147   this_type( p, d, a ).swap( *this );
01148 }
01149 
01150 template< typename P >
01151 template< typename P2 >
01152   void
01153   shared_ptr<P>::reset( shared_ptr<P2> const & other, P * p )
01154 {
01155   this_type( other, p ).swap( *this );
01156 }
01157 
01158 template< typename P >
01159   shared_ptr<P>::operator bool () const throw()
01160 {
01161   return px;
01162 }
01163 
01164 template< typename P >
01165   typename sp::shared_ptr_traits<P>::reference
01166   //typename shared_ptr<P>::reference
01167   shared_ptr<P>::operator * () const throw()
01168 {
01169   assert( px != 0 );
01170   return *px;
01171 }
01172 
01173 template< typename P >
01174   P *
01175   shared_ptr<P>::operator -> () const throw()
01176 {
01177   assert( px != 0 );
01178   return px;
01179 }
01180 
01181 template< typename P >
01182   P *
01183   shared_ptr<P>::get() const throw()
01184 {
01185   return px;
01186 }
01187 
01188 template< typename P >
01189   bool
01190   shared_ptr<P>::unique() const throw()
01191 {
01192   return pn.unique();
01193 }
01194 
01195 template< typename P >
01196   long
01197   shared_ptr<P>::use_count() const throw()
01198 {
01199   return pn.use_count();
01200 }
01201 
01202 template< typename P >
01203 template< typename P2 >
01204   bool
01205   shared_ptr<P>::_internal_less( shared_ptr<P2> const & rhs ) const
01206 {
01207   return pn < rhs.pn;
01208 }
01209 
01210 template< typename P >
01211   void *
01212   shared_ptr<P>::_internal_get_deleter( std::type_info const & ti ) const
01213 {
01214   return pn.get_deleter( ti );
01215 }
01216 
01217 template< typename P >
01218   bool
01219   shared_ptr<P>::_internal_equiv( shared_ptr const & other ) const
01220 {
01221   return px == other.px && pn == other.pn;
01222 }
01223 
01224 template< typename P, typename P2 >
01225   bool
01226   operator == ( shared_ptr<P> const & a, shared_ptr<P2> const & b )
01227 {
01228   return a.get() == b.get();
01229 }
01230 
01231 template< typename P, typename P2 >
01232   bool
01233   operator != ( shared_ptr<P> const & a, shared_ptr<P2> const & b )
01234 {
01235   return a.get() != b.get();
01236 }
01237 
01238 template< typename P, typename P2 >
01239   bool
01240   operator < ( shared_ptr<P> const & a, shared_ptr<P2> const & b )
01241 {
01242   return a._internal_less(b);
01243 }
01244 
01245 template< typename P >
01246   void
01247   swap( shared_ptr<P> & a, shared_ptr<P> & b )
01248 {
01249   a.swap( b );
01250 }
01251 
01252 template< typename P, typename P2 >
01253   shared_ptr<P>
01254   static_pointer_cast( shared_ptr<P2> const & other )
01255 {
01256   return shared_ptr<P>( other, sp::static_cast_tag() );
01257 }
01258 
01259 template< typename P, typename P2 >
01260   shared_ptr<P>
01261   const_pointer_cast( shared_ptr<P2> const & other )
01262 {
01263   return shared_ptr<P>( other, sp::const_cast_tag() );
01264 }
01265 
01266 template< typename P, typename P2 >
01267   shared_ptr<P>
01268   dynamic_pointer_cast( shared_ptr<P2> const & other )
01269 {
01270   return shared_ptr<P>( other, sp::dynamic_cast_tag() );
01271 }
01272 
01273 template< typename P >
01274   P *
01275   get_pointer( shared_ptr<P> const & p )
01276 {
01277   return p.get();
01278 }
01279 
01280 template< typename D, typename P >
01281   D *
01282   get_deleter( shared_ptr<P> const & p )
01283 {
01284   return static_cast<D*>( p._internal_get_deleter( typeid(D)) );
01285 }
01286 
01287 template< typename C, typename T, typename P >
01288   std::basic_ostream<C,T> &
01289   operator << ( std::basic_ostream<C,T> & os, shared_ptr<P> const & p )
01290 {
01291   os << p.get();
01292   return os;
01293 }
01294 
01295 
01296 // ----------------------------------------------------------------------
01297 // weak_ptr - non-owning handle from which a shared_ptr can be obtained
01298 // ----------------------------------------------------------------------
01299 
01300 template< typename P >
01301   class weak_ptr
01302 {
01303   typedef  weak_ptr<P>  this_type;
01304 
01305   template< typename >  friend  class shared_ptr;
01306   template< typename >  friend  class weak_ptr;
01307 
01308 public:
01309   typedef  P  element_type;
01310 
01311   inline  weak_ptr() throw();
01312 
01313   //  generated copy constructor, assignment, destructor are fine
01314 
01315   inline  void  swap( this_type & other ) throw();
01316   template< typename P2 >
01317   inline
01318   weak_ptr( weak_ptr<P2> const & r
01319           , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
01320           ) throw();
01321   template< typename P2 >
01322   inline
01323   weak_ptr( shared_ptr<P2> const & r
01324           , typename enable_if_ptr_convertible<P2,P,void*>::type = 0
01325           ) throw();
01326   template< typename P2 >
01327   inline  weak_ptr &  operator = (weak_ptr<P2> const & r) throw();
01328   template< typename P2 >
01329   inline  weak_ptr &  operator = (shared_ptr<P2> const & r) throw();
01330   // copy-like functions
01331 
01332   inline  shared_ptr<P>  lock() const throw();
01333   inline  long           use_count() const throw();
01334   inline  bool           expired() const throw();
01335   inline  bool           _empty() const; // extension, not in std::weak_ptr
01336   inline  void           reset() throw();
01337   // accessors
01338 
01339   inline  void  _internal_assign( P * px2, sp::shared_ctrl_handle const & pn2 );
01340   template< typename P2 >
01341     inline  bool _internal_less( weak_ptr<P2> const & rhs ) const;
01342 
01343 private:
01344   P *                   px;  // contained pointer
01345   sp::weak_ctrl_handle  pn;  // control information
01346 
01347 };  // weak_ptr
01348 
01349 template< typename P, typename P2 >
01350   inline  bool  operator < ( weak_ptr<P> const & a, weak_ptr<P2> const & b );
01351 
01352 template< typename P >
01353   inline  void  swap( weak_ptr<P> & a, weak_ptr<P> & b );
01354 
01355 template< typename P >
01356 weak_ptr<P>::weak_ptr() throw()
01357   : px( 0 )
01358   , pn(         )
01359 { }
01360 
01361 template< typename P >
01362 template< typename P2 >
01363   weak_ptr<P>::weak_ptr( weak_ptr<P2> const & r
01364                        , typename enable_if_ptr_convertible<P2,P,void*>::type
01365                        ) throw()
01366   : px( r.lock().get() )  // same as r.px, but doesn't risk invalidation
01367   , pn( r.pn           )
01368 { }
01369 
01370 template< typename P >
01371 template< typename P2 >
01372   weak_ptr<P>::weak_ptr( shared_ptr<P2> const & r
01373                        , typename enable_if_ptr_convertible<P2,P,void*>::type
01374                        ) throw()
01375   : px( r.px )
01376   , pn( r.pn )
01377 { }
01378 
01379 template< typename P >
01380 template< typename P2 >
01381   weak_ptr<P> &
01382   weak_ptr<P>::operator = (weak_ptr<P2> const & r) throw()
01383 {
01384   px = r.lock().get();
01385   pn = r.pn;
01386   return *this;
01387 }
01388 
01389 template< typename P >
01390 template< typename P2 >
01391   weak_ptr<P> &
01392   weak_ptr<P>::operator = (shared_ptr<P2> const & r) throw()
01393 {
01394   px = r.px;
01395   pn = r.pn;
01396   return *this;
01397 }
01398 
01399 template< typename P >
01400   shared_ptr<P>
01401   weak_ptr<P>::lock() const throw()
01402 {
01403   return shared_ptr<element_type>( *this, sp::sp_nothrow_tag() );
01404 }
01405 
01406 template< typename P >
01407   long
01408   weak_ptr<P>::use_count() const throw()
01409 {
01410   return pn.use_count();
01411 }
01412 
01413 template< typename P >
01414   bool
01415   weak_ptr<P>::expired() const throw()
01416 {
01417   return pn.use_count() == 0;
01418 }
01419 
01420 template< typename P >
01421   bool
01422   weak_ptr<P>::_empty() const // extension, not in std::weak_ptr
01423 {
01424   return pn.empty();
01425 }
01426 
01427 template< typename P >
01428   void
01429   weak_ptr<P>::reset() throw()
01430 {
01431   this_type().swap(*this);
01432 }
01433 
01434 template< typename P >
01435   void
01436   weak_ptr<P>::swap( this_type & other ) throw()
01437 {
01438   std::swap(px, other.px);
01439   pn.swap(other.pn);
01440 }
01441 
01442 template< typename P >
01443   void
01444   weak_ptr<P>::_internal_assign( P * px2, sp::shared_ctrl_handle const & pn2 )
01445 {
01446   px = px2;
01447   pn = pn2;
01448 }
01449 
01450 template< typename P >
01451 template< typename P2 >
01452   bool
01453   weak_ptr<P>::_internal_less( weak_ptr<P2> const & rhs ) const
01454 {
01455   return pn < rhs.pn;
01456 }
01457 
01458 template< typename P, typename P2 >
01459   bool
01460   operator < ( weak_ptr<P> const & a, weak_ptr<P2> const & b )
01461 {
01462   return a._internal_less(b);
01463 }
01464 
01465 template< typename P >
01466   void
01467   swap( weak_ptr<P> & a, weak_ptr<P> & b )
01468 {
01469   a.swap(b);
01470 }
01471 
01472 
01473 // ----------------------------------------------------------------------
01474 // do_nothing_deleter - for shared_ptrs not taking ownership
01475 // ----------------------------------------------------------------------
01476 
01477 struct do_nothing_deleter {
01478   inline  void  operator () ( void const * ) const;
01479 };
01480 
01481 void
01482 do_nothing_deleter::operator () ( void const * ) const
01483 { }
01484 
01485 
01486 }  // namespace CLHEP
01487 
01488 
01489 #if defined __GNUC__ 
01490   #if __GNUC__ > 3 && __GNUC_MINOR__ > 6
01491     #pragma GCC diagnostic pop
01492   #endif
01493 #endif 
01494 #ifdef __clang__
01495   #pragma clang diagnostic pop
01496 #endif
01497 
01498 
01499 
01500 #endif  // CLHEP_MEMORY_H
01501 //
01502 // ======================================================================
01503 
01504 
01505 #if 0
01506 
01507 //  enable_shared_from_this.hpp
01508 
01509 template< typename T >
01510   class enable_shared_from_this
01511 {
01512 protected:
01513   enable_shared_from_this()
01514   { }
01515 
01516   ~enable_shared_from_this()
01517   { }
01518 
01519   enable_shared_from_this( enable_shared_from_this const & )
01520   { }
01521 
01522   enable_shared_from_this &
01523   operator = ( enable_shared_from_this const & )
01524   {
01525     return *this;
01526   }
01527 
01528 public:
01529   shared_ptr<T>
01530     shared_from_this()
01531   {
01532     shared_ptr<T>  p( weak_this_ );
01533     assert( p.get() == this );
01534     return p;
01535   }
01536 
01537   shared_ptr<T const>
01538     shared_from_this() const
01539   {
01540     shared_ptr<T const>  p( weak_this_ );
01541     assert( p.get() == this );
01542     return p;
01543   }
01544 
01545 public: // actually private, but avoids compiler template friendship issues
01546 
01547   // Note: invoked automatically by shared_ptr; do not call
01548   template< typename X, typename Y >
01549     void
01550     _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
01551   {
01552     if( weak_this_.expired() )
01553         weak_this_ = shared_ptr<T>( *ppx, py );
01554   }
01555 
01556 private:
01557     mutable weak_ptr<T>  weak_this_;
01558 };  // enable_shared_from_this<>
01559 
01560 
01561 //  enable_shared_from_this2.hpp
01562 
01563 namespace detail
01564 {
01565 
01566 class esft2_deleter_wrapper
01567 {
01568 private:
01569   shared_ptr<void>  deleter_;
01570 
01571 public:
01572   esft2_deleter_wrapper()
01573   { }
01574 
01575   template< typename T >
01576     void
01577     set_deleter( shared_ptr<T> const & deleter )
01578   {
01579     deleter_ = deleter;
01580   }
01581 
01582   template< typename T >
01583     void
01584     operator () ( T* )
01585   {
01586     assert( deleter_.use_count() <= 1 );
01587     deleter_.reset();
01588   }
01589 };
01590 
01591 } // namespace detail
01592 
01593 template< typename T >
01594   class enable_shared_from_this2
01595 {
01596 protected:
01597 
01598   enable_shared_from_this2()
01599   { }
01600 
01601   enable_shared_from_this2( enable_shared_from_this2 const & )
01602   { }
01603 
01604   enable_shared_from_this2 & operator = ( enable_shared_from_this2 const & )
01605   {
01606     return *this;
01607   }
01608 
01609   ~enable_shared_from_this2()
01610   {
01611     assert( shared_this_.use_count() <= 1 ); // ensure no dangling shared_ptrs
01612   }
01613 
01614 private:
01615   mutable  weak_ptr<T>    weak_this_;
01616   mutable  shared_ptr<T>  shared_this_;
01617 
01618 public:
01619 
01620   shared_ptr<T>
01621   shared_from_this()
01622   {
01623     init_weak_once();
01624     return shared_ptr<T>( weak_this_ );
01625   }
01626 
01627   shared_ptr<T const>
01628   shared_from_this() const
01629   {
01630     init_weak_once();
01631     return shared_ptr<T>( weak_this_ );
01632   }
01633 
01634 private:
01635 
01636   void init_weak_once() const
01637   {
01638     if( weak_this_._empty() )
01639     {
01640       shared_this_.reset( static_cast< T* >( 0 )
01641                         , detail::esft2_deleter_wrapper()
01642                         );
01643       weak_this_ = shared_this_;
01644     }
01645   }
01646 
01647 public:  // actually private, but avoids compiler template friendship issues
01648 
01649   // Note: invoked automatically by shared_ptr; do not call
01650   template< typename X, typename Y >
01651     void
01652     _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
01653   {
01654     assert( ppx != 0 );
01655 
01656     if( weak_this_.use_count() == 0 )
01657       weak_this_ = shared_ptr<T>( *ppx, py );
01658     else if( shared_this_.use_count() != 0 )
01659     {
01660       assert( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
01661 
01662       detail::esft2_deleter_wrapper *  pd
01663         = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
01664       assert( pd != 0 );
01665 
01666       pd->set_deleter( *ppx );
01667 
01668       ppx->reset( shared_this_, ppx->get() );
01669       shared_this_.reset();
01670     }
01671   }
01672 };  // enable_shared_from_this2<>
01673 
01674 #endif  // 0

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7