12ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
22ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
32ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
42ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
52ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  shared_ptr.hpp
62ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
72ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
82ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  Copyright (c) 2001-2008 Peter Dimov
92ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  Distributed under the Boost Software License, Version 1.0. (See
112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  accompanying file LICENSE_1_0.txt or copy at
122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  http://www.boost.org/LICENSE_1_0.txt)
132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/config.hpp>   // for broken compiler workarounds
182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// In order to avoid circular dependencies with Boost.TR1
242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// we make sure that our include of <memory> doesn't try to
252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// pull in the TR1 headers: that's why we use this header
262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// rather than including <memory> directly:
272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/assert.hpp>
302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/checked_delete.hpp>
312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/throw_exception.hpp>
322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/smart_ptr/detail/shared_count.hpp>
332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/detail/workaround.hpp>
342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/smart_ptr/detail/sp_convertible.hpp>
352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/smart_ptr/detail/spinlock_pool.hpp>
382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/memory_order.hpp>
392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <algorithm>            // for std::swap
422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <functional>           // for std::less
432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <typeinfo>             // for std::bad_cast
442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <cstddef>              // for std::size_t
452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_NO_IOSTREAM)
472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_NO_IOSFWD)
482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <iosfwd>               // for std::basic_ostream
492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <ostream>
512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehnamespace boost
552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> class shared_ptr;
582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> class weak_ptr;
592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> class enable_shared_from_this;
602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> class enable_shared_from_this2;
612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehnamespace detail
632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehstruct static_cast_tag {};
662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehstruct const_cast_tag {};
672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehstruct dynamic_cast_tag {};
682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehstruct polymorphic_cast_tag {};
692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> struct shared_ptr_traits
712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef T & reference;
732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<> struct shared_ptr_traits<void>
762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef void reference;
782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<> struct shared_ptr_traits<void const>
832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef void reference;
852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<> struct shared_ptr_traits<void volatile>
882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef void reference;
902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<> struct shared_ptr_traits<void const volatile>
932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef void reference;
952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// enable_shared_from_this support
1002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< 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 )
1022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    if( pe != 0 )
1042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
1052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
1062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
1072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
1082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
1102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    if( pe != 0 )
1122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
1132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
1142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
1152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
1162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifdef _MANAGED
1182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// Avoid C4793, ... causes native code generation
1202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehstruct sp_any_pointer
1222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class T> sp_any_pointer( T* ) {}
1242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
1252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehinline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
1272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
1292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else // _MANAGED
1312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehinline void sp_enable_shared_from_this( ... )
1332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
1352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // _MANAGED
1372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
1392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// rvalue auto_ptr support based on a technique by Dave Abrahams
1412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< class T, class R > struct sp_enable_if_auto_ptr
1432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
1452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
1472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef R type;
1492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};
1502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
1522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh} // namespace detail
1542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
1572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  shared_ptr
1582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
1592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  An enhanced relative of scoped_ptr with reference counted copy semantics.
1602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  The object pointed to is deleted when the last shared_ptr pointing to it
1612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  is destroyed or reset.
1622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//
1632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> class shared_ptr
1652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
1662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehprivate:
1672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // Borland 5.5.1 specific workaround
1692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef shared_ptr<T> this_type;
1702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehpublic:
1722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef T element_type;
1742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef T value_type;
1752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef T * pointer;
1762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
1772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr(): px(0), pn() // never throws in 1.30+
1792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
1802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
1812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
1832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
1842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
1852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        boost::detail::sp_enable_shared_from_this( this, p, p );
1862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
1872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    //
1892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // Requirements: D's copy constructor must not throw
1902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    //
1912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // shared_ptr will release p by calling d(p)
1922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    //
1932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
1952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
1962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        boost::detail::sp_enable_shared_from_this( this, p, p );
1972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
1982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
1992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // As above, but with allocator. A's copy constructor shall not throw.
2002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
2022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        boost::detail::sp_enable_shared_from_this( this, p, p );
2042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh//  generated copy constructor, destructor are fine...
2072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if defined( BOOST_HAS_RVALUE_REFS )
2092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// ... except in C++0x, move disables the implicit copy
2112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
2132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
2172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
2202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        // it is now safe to copy r.px, as pn(r.pn) did not throw
2222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        px = r.px;
2232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
2272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        if( !pn.empty() )
2292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        {
2302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh            px = r.px;
2312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        }
2322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
2362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
2382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
2402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr<Y> const & r )
2422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
2442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    : px( r.px ), pn( r.pn ) // never throws
2452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // aliasing
2492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template< class Y >
2502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
2512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
2562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
2612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
2662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        if(px == 0) // need to allocate new counter -- the cast failed
2682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        {
2692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh            pn = boost::detail::shared_count();
2702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        }
2712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
2752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        if(px == 0)
2772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        {
2782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh            boost::throw_exception(std::bad_cast());
2792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        }
2802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifndef BOOST_NO_AUTO_PTR
2832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
2852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
2862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        Y * tmp = r.get();
2882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pn = boost::detail::shared_count(r);
2892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
2902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
2912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
2932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
2942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Ap>
2952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
2962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
2972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        typename Ap::element_type * tmp = r.get();
2982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pn = boost::detail::shared_count( r );
2992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
3002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
3042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // BOOST_NO_AUTO_PTR
3062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    // assignment
3082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr & operator=( shared_ptr const & r ) // never throws
3102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type(r).swap(*this);
3122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
3162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
3182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
3192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type(r).swap(*this);
3212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
3252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifndef BOOST_NO_AUTO_PTR
3272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
3292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr & operator=( std::auto_ptr<Y> & r )
3302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type(r).swap(*this);
3322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
3362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Ap>
3382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
3392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( r ).swap( *this );
3412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
3462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // BOOST_NO_AUTO_PTR
3482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// Move support
3502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if defined( BOOST_HAS_RVALUE_REFS )
3522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
3542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pn.swap( r.pn );
3562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        r.px = 0;
3572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
3602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
3612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
3632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
3652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr( shared_ptr<Y> && r )
3672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
3692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    : px( r.px ), pn() // never throws
3702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pn.swap( r.pn );
3722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        r.px = 0;
3732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr & operator=( shared_ptr && r ) // never throws
3762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
3782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y>
3822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
3832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
3852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *this;
3862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
3892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    void reset() // never throws in 1.30+
3912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type().swap(*this);
3932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
3942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
3952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> void reset(Y * p) // Y must be complete
3962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
3972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
3982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type(p).swap(*this);
3992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y, class D> void reset( Y * p, D d )
4022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( p, d ).swap( *this );
4042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y, class D, class A> void reset( Y * p, D d, A a )
4072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( p, d, a ).swap( *this );
4092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> void reset( shared_ptr<Y> const & r, T * p )
4122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        this_type( r, p ).swap( *this );
4142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    reference operator* () const // never throws
4172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        BOOST_ASSERT(px != 0);
4192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return *px;
4202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    T * operator-> () const // never throws
4232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        BOOST_ASSERT(px != 0);
4252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return px;
4262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    T * get() const // never throws
4292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return px;
4312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// implicit conversion to "bool"
4342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#include <boost/smart_ptr/detail/operator_bool.hpp>
4352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    bool unique() const // never throws
4372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return pn.unique();
4392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    long use_count() const // never throws
4422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return pn.use_count();
4442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    void swap(shared_ptr<T> & other) // never throws
4472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        std::swap(px, other.px);
4492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        pn.swap(other.pn);
4502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
4532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return pn < rhs.pn;
4552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
4582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return pn < rhs.pn;
4602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
4632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return pn.get_deleter( ti );
4652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    bool _internal_equiv( shared_ptr const & r ) const
4682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
4692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return px == r.px && pn == r.pn;
4702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
4712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// Tasteless as this may seem, making all members public allows member templates
4732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// to work in the absence of member template friends. (Matthew Langston)
4742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
4762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehprivate:
4782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> friend class shared_ptr;
4802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    template<class Y> friend class weak_ptr;
4812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
4842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    T * px;                     // contained pointer
4862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    boost::detail::shared_count pn;    // reference counter
4872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh};  // shared_ptr
4892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
4912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
4922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return a.get() == b.get();
4932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
4942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
4952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
4962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
4972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return a.get() != b.get();
4982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
4992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
5012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// Resolve the ambiguity between our op!= and the one in rel_ops
5032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
5052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return a.get() != b.get();
5072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
5102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
5122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return a.owner_before( b );
5142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
5172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    a.swap(b);
5192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
5222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::static_cast_tag());
5242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
5272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::const_cast_tag());
5292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
5322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
5342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// shared_*_cast names are deprecated. Use *_pointer_cast instead.
5372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
5392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::static_cast_tag());
5412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
5442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
5462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
5492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
5512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
5542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
5562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return shared_static_cast<T>(r);
5572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// get_pointer() enables boost::mem_fn to recognize shared_ptr
5602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline T * get_pointer(shared_ptr<T> const & p)
5622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return p.get();
5642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// operator<<
5672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_NO_IOSTREAM)
5692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
5712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
5732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    os << p.get();
5752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return os;
5762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
5792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// in STLport's no-iostreams mode no iostream symbols can be used
5812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#ifndef _STLP_NO_IOSTREAMS
5822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
5842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
5852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehusing std::basic_ostream;
5862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
5872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh# else
5882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
5892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh# endif
5902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
5912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    os << p.get();
5922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return os;
5932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
5942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // _STLP_NO_IOSTREAMS
5962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // __GNUC__ < 3
5982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
5992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // !defined(BOOST_NO_IOSTREAM)
6002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// get_deleter
6022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
6042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
6052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
6062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// g++ 2.9x doesn't allow static_cast<X const *>(void *)
6082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
6092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class D, class T> D * get_deleter(shared_ptr<T> const & p)
6112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
6132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return const_cast<D *>(static_cast<D const *>(q));
6142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#else
6172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6182ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class D, class T> D * get_deleter(shared_ptr<T> const & p)
6192ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6202ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
6212ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6222ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6232ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif
6242ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6252ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// atomic access
6262ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6272ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
6282ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6292ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
6302ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6312ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return false;
6322ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6332ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6342ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
6352ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6362ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
6372ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return *p;
6382ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6392ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6402ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
6412ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6422ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return atomic_load( p );
6432ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6442ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6452ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
6462ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6472ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
6482ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    p->swap( r );
6492ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6502ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6512ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
6522ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6532ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    atomic_store( p, r ); // std::move( r )
6542ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6552ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6562ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
6572ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6582ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
6592ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6602ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    sp.lock();
6612ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    p->swap( r );
6622ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    sp.unlock();
6632ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6642ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return r; // return std::move( r )
6652ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6662ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6672ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
6682ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6692ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return atomic_exchange( p, r ); // std::move( r )
6702ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6712ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6722ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
6732ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6742ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
6752ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6762ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    sp.lock();
6772ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6782ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    if( p->_internal_equiv( *v ) )
6792ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
6802ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        p->swap( w );
6812ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6822ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        sp.unlock();
6832ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6842ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return true;
6852ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
6862ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    else
6872ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    {
6882ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        shared_ptr<T> tmp( *p );
6892ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6902ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        sp.unlock();
6912ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6922ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        tmp.swap( *v );
6932ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh        return false;
6942ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    }
6952ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
6962ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
6972ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate<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*/ )
6982ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
6992ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return atomic_compare_exchange( p, v, w ); // std::move( w )
7002ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
7012ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7022ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
7032ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7042ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh// hash_value
7052ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7062ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< class T > struct hash;
7072ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7082ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsiehtemplate< class T > std::size_t hash_value( boost::shared_ptr<T> const & p )
7092ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh{
7102ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh    return boost::hash< T* >()( p.get() );
7112ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh}
7122ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7132ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh} // namespace boost
7142ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7152ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
7162ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh
7172ca0e41376e99ad53c02fdb5333339ad3dcad19fAndrew Hsieh#endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
718