annotate DEPENDENCIES/generic/include/boost/smart_ptr/shared_ptr.hpp @ 16:2665513ce2d3

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