This is Unofficial EPICS BASE Doxygen Site
shared_ptr.hpp
Go to the documentation of this file.
1 #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
3 
4 //
5 // shared_ptr.hpp
6 //
7 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
8 // Copyright (c) 2001-2008 Peter Dimov
9 //
10 // Distributed under the Boost Software License, Version 1.0. (See
11 // accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13 //
14 // See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
15 //
16 
17 #include <boost/config.hpp> // for broken compiler workarounds
18 
19 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
20 #include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
21 #else
22 
23 // In order to avoid circular dependencies with Boost.TR1
24 // we make sure that our include of <memory> doesn't try to
25 // pull in the TR1 headers: that's why we use this header
26 // rather than including <memory> directly:
27 #include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
28 
29 #include <boost/assert.hpp>
30 #include <boost/checked_delete.hpp>
36 
37 #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
39 #include <boost/memory_order.hpp>
40 #endif
41 
42 #include <algorithm> // for std::swap
43 #include <functional> // for std::less
44 #include <typeinfo> // for std::bad_cast
45 #include <cstddef> // for std::size_t
46 
47 #if !defined(BOOST_NO_IOSTREAM)
48 #if !defined(BOOST_NO_IOSFWD)
49 #include <iosfwd> // for std::basic_ostream
50 #else
51 #include <ostream>
52 #endif
53 #endif
54 
55 namespace boost
56 {
57 
58 template<class T> class shared_ptr;
59 template<class T> class weak_ptr;
60 template<class T> class enable_shared_from_this;
61 class enable_shared_from_raw;
62 
63 namespace detail
64 {
65 
66 // sp_element, element_type
67 
68 template< class T > struct sp_element
69 {
70  typedef T type;
71 };
72 
73 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
74 
75 template< class T > struct sp_element< T[] >
76 {
77  typedef T type;
78 };
79 
80 #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
81 
82 template< class T, std::size_t N > struct sp_element< T[N] >
83 {
84  typedef T type;
85 };
86 
87 #endif
88 
89 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
90 
91 // sp_dereference, return type of operator*
92 
93 template< class T > struct sp_dereference
94 {
95  typedef T & type;
96 };
97 
98 template<> struct sp_dereference< void >
99 {
100  typedef void type;
101 };
102 
103 #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
104 
105 template<> struct sp_dereference< void const >
106 {
107  typedef void type;
108 };
109 
110 template<> struct sp_dereference< void volatile >
111 {
112  typedef void type;
113 };
114 
115 template<> struct sp_dereference< void const volatile >
116 {
117  typedef void type;
118 };
119 
120 #endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
121 
122 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
123 
124 template< class T > struct sp_dereference< T[] >
125 {
126  typedef void type;
127 };
128 
129 #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
130 
131 template< class T, std::size_t N > struct sp_dereference< T[N] >
132 {
133  typedef void type;
134 };
135 
136 #endif
137 
138 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
139 
140 // sp_member_access, return type of operator->
141 
142 template< class T > struct sp_member_access
143 {
144  typedef T * type;
145 };
146 
147 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
148 
149 template< class T > struct sp_member_access< T[] >
150 {
151  typedef void type;
152 };
153 
154 #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
155 
156 template< class T, std::size_t N > struct sp_member_access< T[N] >
157 {
158  typedef void type;
159 };
160 
161 #endif
162 
163 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
164 
165 // sp_array_access, return type of operator[]
166 
167 template< class T > struct sp_array_access
168 {
169  typedef void type;
170 };
171 
172 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
173 
174 template< class T > struct sp_array_access< T[] >
175 {
176  typedef T & type;
177 };
178 
179 #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
180 
181 template< class T, std::size_t N > struct sp_array_access< T[N] >
182 {
183  typedef T & type;
184 };
185 
186 #endif
187 
188 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
189 
190 // sp_extent, for operator[] index check
191 
192 template< class T > struct sp_extent
193 {
194  enum _vt { value = 0 };
195 };
196 
197 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
198 
199 template< class T, std::size_t N > struct sp_extent< T[N] >
200 {
201  enum _vt { value = N };
202 };
203 
204 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
205 
206 // enable_shared_from_this support
207 
208 template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
209 {
210  if( pe != 0 )
211  {
212  pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
213  }
214 }
215 
216 template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
217 
218 #ifdef _MANAGED
219 
220 // Avoid C4793, ... causes native code generation
221 
222 struct sp_any_pointer
223 {
224  template<class T> sp_any_pointer( T* ) {}
225 };
226 
227 inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
228 {
229 }
230 
231 #else // _MANAGED
232 
233 inline void sp_enable_shared_from_this( ... )
234 {
235 }
236 
237 #endif // _MANAGED
238 
239 #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
240 
241 // rvalue auto_ptr support based on a technique by Dave Abrahams
242 
243 template< class T, class R > struct sp_enable_if_auto_ptr
244 {
245 };
246 
247 template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
248 {
249  typedef R type;
250 };
251 
252 #endif
253 
254 // sp_assert_convertible
255 
256 template< class Y, class T > inline void sp_assert_convertible()
257 {
258 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
259 
260  // static_assert( sp_convertible< Y, T >::value );
261  typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
262  (void)sizeof( tmp );
263 
264 #else
265 
266  T* p = static_cast< Y* >( 0 );
267  (void)p;
268 
269 #endif
270 }
271 
272 // pointer constructor helper
273 
274 template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
275 {
278 }
279 
280 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
281 
282 template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
283 {
284  sp_assert_convertible< Y[], T[] >();
286 }
287 
288 template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
289 {
290  sp_assert_convertible< Y[N], T[N] >();
292 }
293 
294 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
295 
296 // deleter constructor helper
297 
298 template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
299 {
301 }
302 
303 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
304 
305 template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
306 {
307  sp_assert_convertible< Y[], T[] >();
308 }
309 
310 template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
311 {
312  sp_assert_convertible< Y[N], T[N] >();
313 }
314 
315 #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
316 
317 } // namespace detail
318 
319 
320 //
321 // shared_ptr
322 //
323 // An enhanced relative of scoped_ptr with reference counted copy semantics.
324 // The object pointed to is deleted when the last shared_ptr pointing to it
325 // is destroyed or reset.
326 //
327 
328 template<class T> class shared_ptr
329 {
330 private:
331 
332  // Borland 5.5.1 specific workaround
333  typedef shared_ptr<T> this_type;
334 
335 public:
336 
338 
339  shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
340  {
341  }
342 
343 #if !defined( BOOST_NO_CXX11_NULLPTR )
344 
345  shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
346  {
347  }
348 
349 #endif
350 
351  template<class Y>
352  explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
353  {
355  }
356 
357  //
358  // Requirements: D's copy constructor must not throw
359  //
360  // shared_ptr will release p by calling d(p)
361  //
362 
363  template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
364  {
366  }
367 
368 #if !defined( BOOST_NO_CXX11_NULLPTR )
369 
370  template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
371  {
372  }
373 
374 #endif
375 
376  // As above, but with allocator. A's copy constructor shall not throw.
377 
378  template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
379  {
381  }
382 
383 #if !defined( BOOST_NO_CXX11_NULLPTR )
384 
385  template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
386  {
387  }
388 
389 #endif
390 
391 // generated copy constructor, destructor are fine...
392 
393 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
394 
395 // ... except in C++0x, move disables the implicit copy
396 
397  shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
398  {
399  }
400 
401 #endif
402 
403  template<class Y>
404  explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
405  {
406  boost::detail::sp_assert_convertible< Y, T >();
407 
408  // it is now safe to copy r.px, as pn(r.pn) did not throw
409  px = r.px;
410  }
411 
412  template<class Y>
414  BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
415  {
416  if( !pn.empty() )
417  {
418  px = r.px;
419  }
420  }
421 
422  template<class Y>
423 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
424 
426 
427 #else
428 
429  shared_ptr( shared_ptr<Y> const & r )
430 
431 #endif
432  BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
433  {
434  boost::detail::sp_assert_convertible< Y, T >();
435  }
436 
437  // aliasing
438  template< class Y >
439  shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
440  {
441  }
442 
443 #ifndef BOOST_NO_AUTO_PTR
444 
445  template<class Y>
446  explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
447  {
448  boost::detail::sp_assert_convertible< Y, T >();
449 
450  Y * tmp = r.get();
451  pn = boost::detail::shared_count( r );
452 
454  }
455 
456 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
457 
458  template<class Y>
459  shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
460  {
461  boost::detail::sp_assert_convertible< Y, T >();
462 
463  Y * tmp = r.get();
464  pn = boost::detail::shared_count( r );
465 
467  }
468 
469 #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
470 
471  template<class Ap>
472  explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
473  {
474  typedef typename Ap::element_type Y;
475 
476  boost::detail::sp_assert_convertible< Y, T >();
477 
478  Y * tmp = r.get();
479  pn = boost::detail::shared_count( r );
480 
482  }
483 
484 #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
485 
486 #endif // BOOST_NO_AUTO_PTR
487 
488 #if !defined( BOOST_NO_CXX11_SMART_PTR )
489 
490  template< class Y, class D >
491  shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
492  {
493  boost::detail::sp_assert_convertible< Y, T >();
494 
495  typename std::unique_ptr< Y, D >::pointer tmp = r.get();
496  pn = boost::detail::shared_count( r );
497 
499  }
500 
501 #endif
502 
503  // assignment
504 
506  {
507  this_type(r).swap(*this);
508  return *this;
509  }
510 
511 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
512 
513  template<class Y>
515  {
516  this_type(r).swap(*this);
517  return *this;
518  }
519 
520 #endif
521 
522 #ifndef BOOST_NO_AUTO_PTR
523 
524  template<class Y>
525  shared_ptr & operator=( std::auto_ptr<Y> & r )
526  {
527  this_type( r ).swap( *this );
528  return *this;
529  }
530 
531 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
532 
533  template<class Y>
534  shared_ptr & operator=( std::auto_ptr<Y> && r )
535  {
536  this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
537  return *this;
538  }
539 
540 #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
541 
542  template<class Ap>
544  {
545  this_type( r ).swap( *this );
546  return *this;
547  }
548 
549 #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
550 
551 #endif // BOOST_NO_AUTO_PTR
552 
553 #if !defined( BOOST_NO_CXX11_SMART_PTR )
554 
555  template<class Y, class D>
556  shared_ptr & operator=( std::unique_ptr<Y, D> && r )
557  {
558  this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
559  return *this;
560  }
561 
562 #endif
563 
564 // Move support
565 
566 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
567 
568  shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
569  {
570  pn.swap( r.pn );
571  r.px = 0;
572  }
573 
574  template<class Y>
575 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
576 
578 
579 #else
580 
581  shared_ptr( shared_ptr<Y> && r )
582 
583 #endif
584  BOOST_NOEXCEPT : px( r.px ), pn()
585  {
586  boost::detail::sp_assert_convertible< Y, T >();
587 
588  pn.swap( r.pn );
589  r.px = 0;
590  }
591 
593  {
594  this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
595  return *this;
596  }
597 
598  template<class Y>
600  {
601  this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
602  return *this;
603  }
604 
605 #endif
606 
607 #if !defined( BOOST_NO_CXX11_NULLPTR )
608 
610  {
611  this_type().swap(*this);
612  return *this;
613  }
614 
615 #endif
616 
617  void reset() BOOST_NOEXCEPT // never throws in 1.30+
618  {
619  this_type().swap(*this);
620  }
621 
622  template<class Y> void reset( Y * p ) // Y must be complete
623  {
624  BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
625  this_type( p ).swap( *this );
626  }
627 
628  template<class Y, class D> void reset( Y * p, D d )
629  {
630  this_type( p, d ).swap( *this );
631  }
632 
633  template<class Y, class D, class A> void reset( Y * p, D d, A a )
634  {
635  this_type( p, d, a ).swap( *this );
636  }
637 
638  template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
639  {
640  this_type( r, p ).swap( *this );
641  }
642 
643  // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
644  typename boost::detail::sp_dereference< T >::type operator* () const
645  {
646  BOOST_ASSERT( px != 0 );
647  return *px;
648  }
649 
650  // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
651  typename boost::detail::sp_member_access< T >::type operator-> () const
652  {
653  BOOST_ASSERT( px != 0 );
654  return px;
655  }
656 
657  // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
658  typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
659  {
660  BOOST_ASSERT( px != 0 );
662 
663  return px[ i ];
664  }
665 
666  element_type * get() const BOOST_NOEXCEPT
667  {
668  return px;
669  }
670 
671 // implicit conversion to "bool"
673 
674  bool unique() const BOOST_NOEXCEPT
675  {
676  return pn.unique();
677  }
678 
680  {
681  return pn.use_count();
682  }
683 
685  {
686  std::swap(px, other.px);
687  pn.swap(other.pn);
688  }
689 
690  template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
691  {
692  return pn < rhs.pn;
693  }
694 
695  template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
696  {
697  return pn < rhs.pn;
698  }
699 
701  {
702  return pn.get_deleter( ti );
703  }
704 
706  {
707  return pn.get_untyped_deleter();
708  }
709 
710  bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
711  {
712  return px == r.px && pn == r.pn;
713  }
714 
715 // Tasteless as this may seem, making all members public allows member templates
716 // to work in the absence of member template friends. (Matthew Langston)
717 
718 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
719 
720 private:
721 
722  template<class Y> friend class shared_ptr;
723  template<class Y> friend class weak_ptr;
724 
725 
726 #endif
727 
728  element_type * px; // contained pointer
729  boost::detail::shared_count pn; // reference counter
730 
731 }; // shared_ptr
732 
733 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
734 {
735  return a.get() == b.get();
736 }
737 
738 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
739 {
740  return a.get() != b.get();
741 }
742 
743 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
744 
745 // Resolve the ambiguity between our op!= and the one in rel_ops
746 
747 template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
748 {
749  return a.get() != b.get();
750 }
751 
752 #endif
753 
754 #if !defined( BOOST_NO_CXX11_NULLPTR )
755 
756 template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
757 {
758  return p.get() == 0;
759 }
760 
761 template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
762 {
763  return p.get() == 0;
764 }
765 
766 template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
767 {
768  return p.get() != 0;
769 }
770 
771 template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
772 {
773  return p.get() != 0;
774 }
775 
776 #endif
777 
778 template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
779 {
780  return a.owner_before( b );
781 }
782 
783 template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
784 {
785  a.swap(b);
786 }
787 
788 template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
789 {
790  (void) static_cast< T* >( static_cast< U* >( 0 ) );
791 
792  typedef typename shared_ptr<T>::element_type E;
793 
794  E * p = static_cast< E* >( r.get() );
795  return shared_ptr<T>( r, p );
796 }
797 
798 template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
799 {
800  (void) const_cast< T* >( static_cast< U* >( 0 ) );
801 
802  typedef typename shared_ptr<T>::element_type E;
803 
804  E * p = const_cast< E* >( r.get() );
805  return shared_ptr<T>( r, p );
806 }
807 
808 template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
809 {
810  (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
811 
812  typedef typename shared_ptr<T>::element_type E;
813 
814  E * p = dynamic_cast< E* >( r.get() );
815  return p? shared_ptr<T>( r, p ): shared_ptr<T>();
816 }
817 
819 {
820  (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
821 
822  typedef typename shared_ptr<T>::element_type E;
823 
824  E * p = reinterpret_cast< E* >( r.get() );
825  return shared_ptr<T>( r, p );
826 }
827 
828 // get_pointer() enables boost::mem_fn to recognize shared_ptr
829 
830 template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
831 {
832  return p.get();
833 }
834 
835 // operator<<
836 
837 #if !defined(BOOST_NO_IOSTREAM)
838 
839 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
840 
841 template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
842 {
843  os << p.get();
844  return os;
845 }
846 
847 #else
848 
849 // in STLport's no-iostreams mode no iostream symbols can be used
850 #ifndef _STLP_NO_IOSTREAMS
851 
852 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
853 // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
854 using std::basic_ostream;
855 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
856 # else
857 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
858 # endif
859 {
860  os << p.get();
861  return os;
862 }
863 
864 #endif // _STLP_NO_IOSTREAMS
865 
866 #endif // __GNUC__ < 3
867 
868 #endif // !defined(BOOST_NO_IOSTREAM)
869 
870 // get_deleter
871 
872 namespace detail
873 {
874 
875 #if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
876  ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
877  ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
878 
879 // g++ 2.9x doesn't allow static_cast<X const *>(void *)
880 // apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
881 
882 template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
883 {
884  void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
885  return const_cast<D *>(static_cast<D const *>(q));
886 }
887 
888 #else
889 
890 template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
891 {
892  return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
893 }
894 
895 #endif
896 
898 {
899 private:
900 
901  shared_ptr<void> deleter_;
902 
903 public:
904 
906  {
907  }
908 
909  template< class T > void set_deleter( shared_ptr<T> const & deleter )
910  {
911  deleter_ = deleter;
912  }
913 
914  template<typename D> D* get_deleter() const BOOST_NOEXCEPT
915  {
916  return boost::detail::basic_get_deleter<D>( deleter_ );
917  }
918 
919  template< class T> void operator()( T* )
920  {
921  BOOST_ASSERT( deleter_.use_count() <= 1 );
922  deleter_.reset();
923  }
924 };
925 
926 } // namespace detail
927 
928 template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
929 {
930  D *del = boost::detail::basic_get_deleter<D>(p);
931 
932  if(del == 0)
933  {
934  boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
935 // The following get_deleter method call is fully qualified because
936 // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
937  if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
938  }
939 
940  return del;
941 }
942 
943 // atomic access
944 
945 #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
946 
947 template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
948 {
949  return false;
950 }
951 
952 template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
953 {
955  return *p;
956 }
957 
958 template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
959 {
960  return atomic_load( p );
961 }
962 
963 template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
964 {
966  p->swap( r );
967 }
968 
969 template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
970 {
971  atomic_store( p, r ); // std::move( r )
972 }
973 
975 {
977 
978  sp.lock();
979  p->swap( r );
980  sp.unlock();
981 
982  return r; // return std::move( r )
983 }
984 
986 {
987  return atomic_exchange( p, r ); // std::move( r )
988 }
989 
991 {
993 
994  sp.lock();
995 
996  if( p->_internal_equiv( *v ) )
997  {
998  p->swap( w );
999 
1000  sp.unlock();
1001 
1002  return true;
1003  }
1004  else
1005  {
1006  shared_ptr<T> tmp( *p );
1007 
1008  sp.unlock();
1009 
1010  tmp.swap( *v );
1011  return false;
1012  }
1013 }
1014 
1015 template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
1016 {
1017  return atomic_compare_exchange( p, v, w ); // std::move( w )
1018 }
1019 
1020 #endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
1021 
1022 // hash_value
1023 
1024 template< class T > struct hash;
1025 
1026 template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
1027 {
1028  return boost::hash< T* >()( p.get() );
1029 }
1030 
1031 } // namespace boost
1032 
1033 #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
1034 
1035 #endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
std::nullptr_t sp_nullptr_t
bool owner_before(shared_ptr< Y > const &rhs) const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:690
void sp_assert_convertible()
Definition: shared_ptr.hpp:256
long use_count() const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:679
Definition: link.h:174
shared_ptr & operator=(shared_ptr const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:505
D * basic_get_deleter(shared_ptr< T > const &p) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:890
void * _internal_get_deleter(boost::detail::sp_typeinfo const &ti) const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:700
shared_ptr(shared_ptr &&r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:568
shared_ptr(Y *p, D d, A a)
Definition: shared_ptr.hpp:378
Definition: assert.hpp:91
bool owner_before(weak_ptr< Y > const &rhs) const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:695
epicsMutexId lock
Definition: osiClockTime.c:37
shared_ptr & operator=(std::auto_ptr< Y > &&r)
Definition: shared_ptr.hpp:534
int i
Definition: scan.c:967
shared_ptr< T > reinterpret_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:818
bool atomic_is_lock_free(shared_ptr< T > const *) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:947
void atomic_store(shared_ptr< T > *p, shared_ptr< T > r)
Definition: shared_ptr.hpp:963
shared_ptr(shared_ptr< Y > const &r, element_type *p) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:439
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
shared_ptr(std::unique_ptr< Y, D > &&r)
Definition: shared_ptr.hpp:491
shared_ptr(Y *p, D d)
Definition: shared_ptr.hpp:363
Definition: memory.hpp:41
void sp_deleter_construct(boost::shared_ptr< T > *ppx, Y *p)
Definition: shared_ptr.hpp:298
D * get_deleter(shared_ptr< T > const &p) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:928
shared_ptr(std::auto_ptr< Y > &&r)
Definition: shared_ptr.hpp:459
shared_ptr() BOOST_NOEXCEPT
Definition: shared_ptr.hpp:339
shared_ptr< T >::element_type * get_pointer(shared_ptr< T > const &p) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:830
void reset(Y *p)
Definition: shared_ptr.hpp:622
void reset(shared_ptr< Y > const &r, element_type *p)
Definition: shared_ptr.hpp:638
shared_ptr< T > atomic_load_explicit(shared_ptr< T > const *p, memory_order)
Definition: shared_ptr.hpp:958
void set_deleter(shared_ptr< T > const &deleter)
Definition: shared_ptr.hpp:909
shared_ptr & operator=(shared_ptr< Y > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:514
shared_ptr(boost::detail::sp_nullptr_t) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:345
bool operator==(shared_ptr< T > const &a, shared_ptr< U > const &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:733
D * get_deleter() const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:914
shared_ptr(shared_ptr< Y > &&r, typename boost::detail::sp_enable_if_convertible< Y, T >::type=boost::detail::sp_empty()) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:577
element_type * get() const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:666
void reset(Y *p, D d)
Definition: shared_ptr.hpp:628
void swap(shared_ptr &other) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:684
shared_ptr & operator=(shared_ptr< Y > &&r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:599
shared_ptr(boost::detail::sp_nullptr_t p, D d)
Definition: shared_ptr.hpp:370
void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:705
shared_ptr(weak_ptr< Y > const &r)
Definition: shared_ptr.hpp:404
#define BOOST_SP_TYPEID(T)
bool unique() const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:674
void sp_pointer_construct(boost::shared_ptr< T > *ppx, Y *p, boost::detail::shared_count &pn)
Definition: shared_ptr.hpp:274
void sp_enable_shared_from_this(boost::shared_ptr< X > const *ppx, Y const *py, boost::enable_shared_from_this< T > const *pe)
Definition: shared_ptr.hpp:208
bool atomic_compare_exchange(shared_ptr< T > *p, shared_ptr< T > *v, shared_ptr< T > w)
Definition: shared_ptr.hpp:990
void swap(shared_count &r)
shared_ptr & operator=(boost::detail::sp_nullptr_t) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:609
shared_ptr & operator=(std::auto_ptr< Y > &r)
Definition: shared_ptr.hpp:525
shared_ptr(shared_ptr const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:397
std::size_t hash_value(boost::shared_ptr< T > const &p) BOOST_NOEXCEPT
#define BOOST_NOEXCEPT
Definition: suffix.hpp:880
shared_ptr(std::auto_ptr< Y > &r)
Definition: shared_ptr.hpp:446
shared_ptr(shared_ptr< Y > const &r, typename boost::detail::sp_enable_if_convertible< Y, T >::type=boost::detail::sp_empty()) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:425
Definition: caget.c:48
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:783
shared_ptr & operator=(std::unique_ptr< Y, D > &&r)
Definition: shared_ptr.hpp:556
std::type_info sp_typeinfo
shared_ptr(weak_ptr< Y > const &r, boost::detail::sp_nothrow_tag) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:413
void atomic_store_explicit(shared_ptr< T > *p, shared_ptr< T > r, memory_order)
Definition: shared_ptr.hpp:969
shared_ptr & operator=(shared_ptr &&r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:592
element_type
Definition: postfix.c:33
void _internal_accept_owner(shared_ptr< X > const *ppx, Y *py) const
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:808
bool atomic_compare_exchange_explicit(shared_ptr< T > *p, shared_ptr< T > *v, shared_ptr< T > w, memory_order, memory_order)
bool _internal_equiv(shared_ptr const &r) const BOOST_NOEXCEPT
Definition: shared_ptr.hpp:710
static spinlock & spinlock_for(void const *pv)
#define BOOST_ASSERT(expr)
Definition: assert.hpp:51
shared_ptr< T > atomic_load(shared_ptr< T > const *p)
Definition: shared_ptr.hpp:952
shared_ptr< T > const_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:798
void reset(Y *p, D d, A a)
Definition: shared_ptr.hpp:633
shared_ptr< T > atomic_exchange(shared_ptr< T > *p, shared_ptr< T > r)
Definition: shared_ptr.hpp:974
bool operator!=(shared_ptr< T > const &a, shared_ptr< U > const &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:738
shared_ptr(boost::detail::sp_nullptr_t p, D d, A a)
Definition: shared_ptr.hpp:385
shared_ptr< T > atomic_exchange_explicit(shared_ptr< T > *p, shared_ptr< T > r, memory_order)
Definition: shared_ptr.hpp:985
void reset() BOOST_NOEXCEPT
Definition: shared_ptr.hpp:617
boost::detail::sp_element< T >::type element_type
Definition: shared_ptr.hpp:337