• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
3 
4 //  local_shared_ptr.hpp
5 //
6 //  Copyright 2017 Peter Dimov
7 //
8 //  Distributed under the Boost Software License, Version 1.0. (See
9 //  accompanying file LICENSE_1_0.txt or copy at
10 //  http://www.boost.org/LICENSE_1_0.txt)
11 //
12 //  See http://www.boost.org/libs/smart_ptr/ for documentation.
13 
14 #include <boost/smart_ptr/shared_ptr.hpp>
15 
16 namespace boost
17 {
18 
19 template<class T> class local_shared_ptr;
20 
21 namespace detail
22 {
23 
lsp_pointer_construct(boost::local_shared_ptr<E> *,Y * p,boost::detail::local_counted_base * & pn)24 template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
25 {
26     boost::detail::sp_assert_convertible< Y, E >();
27 
28     typedef boost::detail::local_sp_deleter< boost::checked_deleter<Y> > D;
29 
30     boost::shared_ptr<E> p2( p, D() );
31 
32     D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
33 
34     pd->pn_ = p2._internal_count();
35 
36     pn = pd;
37 }
38 
lsp_pointer_construct(boost::local_shared_ptr<E[]> *,Y * p,boost::detail::local_counted_base * & pn)39 template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
40 {
41     boost::detail::sp_assert_convertible< Y[], E[] >();
42 
43     typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
44 
45     boost::shared_ptr<E[]> p2( p, D() );
46 
47     D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
48 
49     pd->pn_ = p2._internal_count();
50 
51     pn = pd;
52 }
53 
lsp_pointer_construct(boost::local_shared_ptr<E[N]> *,Y * p,boost::detail::local_counted_base * & pn)54 template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
55 {
56     boost::detail::sp_assert_convertible< Y[N], E[N] >();
57 
58     typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
59 
60     boost::shared_ptr<E[N]> p2( p, D() );
61 
62     D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
63 
64     pd->pn_ = p2._internal_count();
65 
66     pn = pd;
67 }
68 
lsp_deleter_construct(boost::local_shared_ptr<E> *,P p,D const & d,boost::detail::local_counted_base * & pn)69 template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, boost::detail::local_counted_base * & pn )
70 {
71     typedef boost::detail::local_sp_deleter<D> D2;
72 
73     boost::shared_ptr<E> p2( p, D2( d ) );
74 
75     D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
76 
77     pd->pn_ = p2._internal_count();
78 
79     pn = pd;
80 }
81 
lsp_allocator_construct(boost::local_shared_ptr<E> *,P p,D const & d,A const & a,boost::detail::local_counted_base * & pn)82 template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn )
83 {
84     typedef boost::detail::local_sp_deleter<D> D2;
85 
86     boost::shared_ptr<E> p2( p, D2( d ), a );
87 
88     D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
89 
90     pd->pn_ = p2._internal_count();
91 
92     pn = pd;
93 }
94 
95 struct lsp_internal_constructor_tag
96 {
97 };
98 
99 } // namespace detail
100 
101 //
102 // local_shared_ptr
103 //
104 // as shared_ptr, but local to a thread.
105 // reference count manipulations are non-atomic.
106 //
107 
108 template<class T> class local_shared_ptr
109 {
110 private:
111 
112     typedef local_shared_ptr this_type;
113 
114 public:
115 
116     typedef typename boost::detail::sp_element<T>::type element_type;
117 
118 private:
119 
120     element_type * px;
121     boost::detail::local_counted_base * pn;
122 
123     template<class Y> friend class local_shared_ptr;
124 
125 public:
126 
127     // destructor
128 
~local_shared_ptr()129     ~local_shared_ptr() BOOST_SP_NOEXCEPT
130     {
131         if( pn )
132         {
133             pn->release();
134         }
135     }
136 
137     // constructors
138 
local_shared_ptr()139     BOOST_CONSTEXPR local_shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
140     {
141     }
142 
143 #if !defined( BOOST_NO_CXX11_NULLPTR )
144 
local_shared_ptr(boost::detail::sp_nullptr_t)145     BOOST_CONSTEXPR local_shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
146     {
147     }
148 
149 #endif
150 
151     // internal constructor, used by make_shared
local_shared_ptr(boost::detail::lsp_internal_constructor_tag,element_type * px_,boost::detail::local_counted_base * pn_)152     BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, element_type * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
153     {
154     }
155 
156     template<class Y>
local_shared_ptr(Y * p)157     explicit local_shared_ptr( Y * p ): px( p ), pn( 0 )
158     {
159         boost::detail::lsp_pointer_construct( this, p, pn );
160     }
161 
local_shared_ptr(Y * p,D d)162     template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ), pn( 0 )
163     {
164         boost::detail::lsp_deleter_construct( this, p, d, pn );
165     }
166 
167 #if !defined( BOOST_NO_CXX11_NULLPTR )
168 
local_shared_ptr(boost::detail::sp_nullptr_t p,D d)169     template<class D> local_shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( 0 )
170     {
171         boost::detail::lsp_deleter_construct( this, p, d, pn );
172     }
173 
174 #endif
175 
local_shared_ptr(Y * p,D d,A a)176     template<class Y, class D, class A> local_shared_ptr( Y * p, D d, A a ): px( p ), pn( 0 )
177     {
178         boost::detail::lsp_allocator_construct( this, p, d, a, pn );
179     }
180 
181 #if !defined( BOOST_NO_CXX11_NULLPTR )
182 
local_shared_ptr(boost::detail::sp_nullptr_t p,D d,A a)183     template<class D, class A> local_shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( 0 )
184     {
185         boost::detail::lsp_allocator_construct( this, p, d, a, pn );
186     }
187 
188 #endif
189 
190     // construction from shared_ptr
191 
local_shared_ptr(shared_ptr<Y> const & r,typename boost::detail::sp_enable_if_convertible<Y,T>::type=boost::detail::sp_empty ())192     template<class Y> local_shared_ptr( shared_ptr<Y> const & r,
193         typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
194         : px( r.get() ), pn( 0 )
195     {
196         boost::detail::sp_assert_convertible< Y, T >();
197 
198         if( r.use_count() != 0 )
199         {
200             pn = new boost::detail::local_counted_impl( r._internal_count() );
201         }
202     }
203 
204 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
205 
local_shared_ptr(shared_ptr<Y> && r,typename boost::detail::sp_enable_if_convertible<Y,T>::type=boost::detail::sp_empty ())206     template<class Y> local_shared_ptr( shared_ptr<Y> && r,
207         typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
208         : px( r.get() ), pn( 0 )
209     {
210         boost::detail::sp_assert_convertible< Y, T >();
211 
212         if( r.use_count() != 0 )
213         {
214             pn = new boost::detail::local_counted_impl( r._internal_count() );
215             r.reset();
216         }
217     }
218 
219 #endif
220 
221     // construction from unique_ptr
222 
223 #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
224 
225     template< class Y, class D >
local_shared_ptr(std::unique_ptr<Y,D> && r,typename boost::detail::sp_enable_if_convertible<Y,T>::type=boost::detail::sp_empty ())226     local_shared_ptr( std::unique_ptr< Y, D > && r,
227         typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
228         : px( r.get() ), pn( 0 )
229     {
230         boost::detail::sp_assert_convertible< Y, T >();
231 
232         if( px )
233         {
234             pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
235         }
236     }
237 
238 #endif
239 
240     template< class Y, class D >
241     local_shared_ptr( boost::movelib::unique_ptr< Y, D > r ); // !
242     //  : px( r.get() ), pn( new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) ) )
243     //{
244     //    boost::detail::sp_assert_convertible< Y, T >();
245     //}
246 
247     // copy constructor
248 
local_shared_ptr(local_shared_ptr const & r)249     local_shared_ptr( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
250     {
251         if( pn )
252         {
253             pn->add_ref();
254         }
255     }
256 
257     // move constructor
258 
259 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
260 
local_shared_ptr(local_shared_ptr && r)261     local_shared_ptr( local_shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
262     {
263         r.px = 0;
264         r.pn = 0;
265     }
266 
267 #endif
268 
269     // converting copy constructor
270 
local_shared_ptr(local_shared_ptr<Y> const & r,typename boost::detail::sp_enable_if_convertible<Y,T>::type=boost::detail::sp_empty ())271     template<class Y> local_shared_ptr( local_shared_ptr<Y> const & r,
272         typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
273         : px( r.px ), pn( r.pn )
274     {
275         boost::detail::sp_assert_convertible< Y, T >();
276 
277         if( pn )
278         {
279             pn->add_ref();
280         }
281     }
282 
283     // converting move constructor
284 
285 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
286 
local_shared_ptr(local_shared_ptr<Y> && r,typename boost::detail::sp_enable_if_convertible<Y,T>::type=boost::detail::sp_empty ())287     template<class Y> local_shared_ptr( local_shared_ptr<Y> && r,
288         typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
289         : px( r.px ), pn( r.pn )
290     {
291         boost::detail::sp_assert_convertible< Y, T >();
292 
293         r.px = 0;
294         r.pn = 0;
295     }
296 
297 #endif
298 
299     // aliasing
300 
301     template<class Y>
local_shared_ptr(local_shared_ptr<Y> const & r,element_type * p)302     local_shared_ptr( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
303     {
304         if( pn )
305         {
306             pn->add_ref();
307         }
308     }
309 
310 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
311 
312     template<class Y>
local_shared_ptr(local_shared_ptr<Y> && r,element_type * p)313     local_shared_ptr( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
314     {
315         r.px = 0;
316         r.pn = 0;
317     }
318 
319 #endif
320 
321     // assignment
322 
operator =(local_shared_ptr const & r)323     local_shared_ptr & operator=( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT
324     {
325         local_shared_ptr( r ).swap( *this );
326         return *this;
327     }
328 
operator =(local_shared_ptr<Y> const & r)329     template<class Y> local_shared_ptr & operator=( local_shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
330     {
331         local_shared_ptr( r ).swap( *this );
332         return *this;
333     }
334 
335 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
336 
operator =(local_shared_ptr && r)337     local_shared_ptr & operator=( local_shared_ptr && r ) BOOST_SP_NOEXCEPT
338     {
339         local_shared_ptr( std::move( r ) ).swap( *this );
340         return *this;
341     }
342 
343     template<class Y>
operator =(local_shared_ptr<Y> && r)344     local_shared_ptr & operator=( local_shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
345     {
346         local_shared_ptr( std::move( r ) ).swap( *this );
347         return *this;
348     }
349 
350 #endif
351 
352 #if !defined( BOOST_NO_CXX11_NULLPTR )
353 
operator =(boost::detail::sp_nullptr_t)354     local_shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
355     {
356         local_shared_ptr().swap(*this);
357         return *this;
358     }
359 
360 #endif
361 
362 #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
363 
364     template<class Y, class D>
operator =(std::unique_ptr<Y,D> && r)365     local_shared_ptr & operator=( std::unique_ptr<Y, D> && r )
366     {
367         local_shared_ptr( std::move(r) ).swap( *this );
368         return *this;
369     }
370 
371 #endif
372 
373     template<class Y, class D>
374     local_shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r ); // !
375 
376     // reset
377 
reset()378     void reset() BOOST_SP_NOEXCEPT
379     {
380         local_shared_ptr().swap( *this );
381     }
382 
reset(Y * p)383     template<class Y> void reset( Y * p ) // Y must be complete
384     {
385         local_shared_ptr( p ).swap( *this );
386     }
387 
reset(Y * p,D d)388     template<class Y, class D> void reset( Y * p, D d )
389     {
390         local_shared_ptr( p, d ).swap( *this );
391     }
392 
reset(Y * p,D d,A a)393     template<class Y, class D, class A> void reset( Y * p, D d, A a )
394     {
395         local_shared_ptr( p, d, a ).swap( *this );
396     }
397 
reset(local_shared_ptr<Y> const & r,element_type * p)398     template<class Y> void reset( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
399     {
400         local_shared_ptr( r, p ).swap( *this );
401     }
402 
403 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
404 
reset(local_shared_ptr<Y> && r,element_type * p)405     template<class Y> void reset( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
406     {
407         local_shared_ptr( std::move( r ), p ).swap( *this );
408     }
409 
410 #endif
411 
412     // accessors
413 
operator *() const414     typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT
415     {
416         return *px;
417     }
418 
operator ->() const419     typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT
420     {
421         return px;
422     }
423 
operator [](std::ptrdiff_t i) const424     typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
425     {
426         BOOST_ASSERT( px != 0 );
427         BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
428 
429         return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
430     }
431 
get() const432     element_type * get() const BOOST_SP_NOEXCEPT
433     {
434         return px;
435     }
436 
437     // implicit conversion to "bool"
438 #include <boost/smart_ptr/detail/operator_bool.hpp>
439 
local_use_count() const440     long local_use_count() const BOOST_SP_NOEXCEPT
441     {
442         return pn? pn->local_use_count(): 0;
443     }
444 
445     // conversions to shared_ptr, weak_ptr
446 
447 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
operator shared_ptr<Y>() const448     template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
449 #else
450     template<class Y> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
451 #endif
452     {
453         boost::detail::sp_assert_convertible<T, Y>();
454 
455         if( pn )
456         {
457             return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
458         }
459         else
460         {
461             return shared_ptr<Y>();
462         }
463     }
464 
465 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
operator weak_ptr<Y>() const466     template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
467 #else
468     template<class Y> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
469 #endif
470     {
471         boost::detail::sp_assert_convertible<T, Y>();
472 
473         if( pn )
474         {
475             return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
476         }
477         else
478         {
479             return weak_ptr<Y>();
480         }
481     }
482 
483     // swap
484 
swap(local_shared_ptr & r)485     void swap( local_shared_ptr & r ) BOOST_SP_NOEXCEPT
486     {
487         std::swap( px, r.px );
488         std::swap( pn, r.pn );
489     }
490 
491     // owner_before
492 
owner_before(local_shared_ptr<Y> const & r) const493     template<class Y> bool owner_before( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
494     {
495         return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
496     }
497 
498     // owner_equals
499 
owner_equals(local_shared_ptr<Y> const & r) const500     template<class Y> bool owner_equals( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
501     {
502         return pn == r.pn;
503     }
504 };
505 
operator ==(local_shared_ptr<T> const & a,local_shared_ptr<U> const & b)506 template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
507 {
508     return a.get() == b.get();
509 }
510 
operator !=(local_shared_ptr<T> const & a,local_shared_ptr<U> const & b)511 template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
512 {
513     return a.get() != b.get();
514 }
515 
516 #if !defined( BOOST_NO_CXX11_NULLPTR )
517 
operator ==(local_shared_ptr<T> const & p,boost::detail::sp_nullptr_t)518 template<class T> inline bool operator==( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
519 {
520     return p.get() == 0;
521 }
522 
operator ==(boost::detail::sp_nullptr_t,local_shared_ptr<T> const & p)523 template<class T> inline bool operator==( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
524 {
525     return p.get() == 0;
526 }
527 
operator !=(local_shared_ptr<T> const & p,boost::detail::sp_nullptr_t)528 template<class T> inline bool operator!=( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
529 {
530     return p.get() != 0;
531 }
532 
operator !=(boost::detail::sp_nullptr_t,local_shared_ptr<T> const & p)533 template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
534 {
535     return p.get() != 0;
536 }
537 
538 #endif
539 
operator ==(local_shared_ptr<T> const & a,shared_ptr<U> const & b)540 template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
541 {
542     return a.get() == b.get();
543 }
544 
operator !=(local_shared_ptr<T> const & a,shared_ptr<U> const & b)545 template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
546 {
547     return a.get() != b.get();
548 }
549 
operator ==(shared_ptr<T> const & a,local_shared_ptr<U> const & b)550 template<class T, class U> inline bool operator==( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
551 {
552     return a.get() == b.get();
553 }
554 
operator !=(shared_ptr<T> const & a,local_shared_ptr<U> const & b)555 template<class T, class U> inline bool operator!=( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
556 {
557     return a.get() != b.get();
558 }
559 
operator <(local_shared_ptr<T> const & a,local_shared_ptr<U> const & b)560 template<class T, class U> inline bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
561 {
562     return a.owner_before( b );
563 }
564 
swap(local_shared_ptr<T> & a,local_shared_ptr<T> & b)565 template<class T> inline void swap( local_shared_ptr<T> & a, local_shared_ptr<T> & b ) BOOST_SP_NOEXCEPT
566 {
567     a.swap( b );
568 }
569 
static_pointer_cast(local_shared_ptr<U> const & r)570 template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
571 {
572     (void) static_cast< T* >( static_cast< U* >( 0 ) );
573 
574     typedef typename local_shared_ptr<T>::element_type E;
575 
576     E * p = static_cast< E* >( r.get() );
577     return local_shared_ptr<T>( r, p );
578 }
579 
const_pointer_cast(local_shared_ptr<U> const & r)580 template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
581 {
582     (void) const_cast< T* >( static_cast< U* >( 0 ) );
583 
584     typedef typename local_shared_ptr<T>::element_type E;
585 
586     E * p = const_cast< E* >( r.get() );
587     return local_shared_ptr<T>( r, p );
588 }
589 
dynamic_pointer_cast(local_shared_ptr<U> const & r)590 template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
591 {
592     (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
593 
594     typedef typename local_shared_ptr<T>::element_type E;
595 
596     E * p = dynamic_cast< E* >( r.get() );
597     return p? local_shared_ptr<T>( r, p ): local_shared_ptr<T>();
598 }
599 
reinterpret_pointer_cast(local_shared_ptr<U> const & r)600 template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
601 {
602     (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
603 
604     typedef typename local_shared_ptr<T>::element_type E;
605 
606     E * p = reinterpret_cast< E* >( r.get() );
607     return local_shared_ptr<T>( r, p );
608 }
609 
610 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
611 
static_pointer_cast(local_shared_ptr<U> && r)612 template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
613 {
614     (void) static_cast< T* >( static_cast< U* >( 0 ) );
615 
616     typedef typename local_shared_ptr<T>::element_type E;
617 
618     E * p = static_cast< E* >( r.get() );
619     return local_shared_ptr<T>( std::move(r), p );
620 }
621 
const_pointer_cast(local_shared_ptr<U> && r)622 template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
623 {
624     (void) const_cast< T* >( static_cast< U* >( 0 ) );
625 
626     typedef typename local_shared_ptr<T>::element_type E;
627 
628     E * p = const_cast< E* >( r.get() );
629     return local_shared_ptr<T>( std::move(r), p );
630 }
631 
dynamic_pointer_cast(local_shared_ptr<U> && r)632 template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
633 {
634     (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
635 
636     typedef typename local_shared_ptr<T>::element_type E;
637 
638     E * p = dynamic_cast< E* >( r.get() );
639     return p? local_shared_ptr<T>( std::move(r), p ): local_shared_ptr<T>();
640 }
641 
reinterpret_pointer_cast(local_shared_ptr<U> && r)642 template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
643 {
644     (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
645 
646     typedef typename local_shared_ptr<T>::element_type E;
647 
648     E * p = reinterpret_cast< E* >( r.get() );
649     return local_shared_ptr<T>( std::move(r), p );
650 }
651 
652 #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
653 
654 // get_pointer() enables boost::mem_fn to recognize local_shared_ptr
655 
get_pointer(local_shared_ptr<T> const & p)656 template<class T> inline typename local_shared_ptr<T>::element_type * get_pointer( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
657 {
658     return p.get();
659 }
660 
661 // operator<<
662 
663 #if !defined(BOOST_NO_IOSTREAM)
664 
operator <<(std::basic_ostream<E,T> & os,local_shared_ptr<Y> const & p)665 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< ( std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p )
666 {
667     os << p.get();
668     return os;
669 }
670 
671 #endif // !defined(BOOST_NO_IOSTREAM)
672 
673 // get_deleter
674 
get_deleter(local_shared_ptr<T> const & p)675 template<class D, class T> D * get_deleter( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
676 {
677     return get_deleter<D>( shared_ptr<T>( p ) );
678 }
679 
680 // hash_value
681 
682 template< class T > struct hash;
683 
hash_value(local_shared_ptr<T> const & p)684 template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
685 {
686     return boost::hash< typename local_shared_ptr<T>::element_type* >()( p.get() );
687 }
688 
689 } // namespace boost
690 
691 // std::hash
692 
693 #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
694 
695 namespace std
696 {
697 
698 template<class T> struct hash< ::boost::local_shared_ptr<T> >
699 {
operator ()std::hash700     std::size_t operator()( ::boost::local_shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
701     {
702         return std::hash< typename ::boost::local_shared_ptr<T>::element_type* >()( p.get() );
703     }
704 };
705 
706 } // namespace std
707 
708 #endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
709 
710 #endif  // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
711