shared_count( P p, D d ): pi_(0)
+#endif
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+ typedef Y* P;
+#endif
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = new sp_counted_impl_pd(p, d);
+ }
+ catch(...)
+ {
+ d(p); // delete p
+ throw;
+ }
+
+#else
+
+ pi_ = new sp_counted_impl_pd
(p, d);
+
+ if(pi_ == 0)
+ {
+ d(p); // delete p
+ boost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+ }
+
+ template shared_count( P p, D d, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef sp_counted_impl_pda impl_type;
+ typedef typename A::template rebind< impl_type >::other A2;
+
+ A2 a2( a );
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+ new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+ }
+ catch(...)
+ {
+ d( p );
+
+ if( pi_ != 0 )
+ {
+ a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
+ }
+
+ throw;
+ }
+
+#else
+
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+
+ if( pi_ != 0 )
+ {
+ new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+ }
+ else
+ {
+ d( p );
+ boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+ }
+
+#ifndef BOOST_NO_AUTO_PTR
+
+ // auto_ptr is special cased to provide the strong guarantee
+
+ template
+ explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ boost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+
+ r.release();
+ }
+
+#endif
+
+ ~shared_count() // nothrow
+ {
+ if( pi_ != 0 ) pi_->release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ id_ = 0;
+#endif
+ }
+
+ shared_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ if( pi_ != 0 ) pi_->add_ref_copy();
+ }
+
+#if defined( BOOST_HAS_RVALUE_REFS )
+
+ shared_count(shared_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ r.pi_ = 0;
+ }
+
+#endif
+
+ explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
+ shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
+
+ shared_count & operator= (shared_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if( tmp != 0 ) tmp->add_ref_copy();
+ if( pi_ != 0 ) pi_->release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ void swap(shared_count & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+ r.pi_ = pi_;
+ pi_ = tmp;
+ }
+
+ long use_count() const // nothrow
+ {
+ return pi_ != 0? pi_->use_count(): 0;
+ }
+
+ bool unique() const // nothrow
+ {
+ return use_count() == 1;
+ }
+
+ bool empty() const // nothrow
+ {
+ return pi_ == 0;
+ }
+
+ friend inline bool operator==(shared_count const & a, shared_count const & b)
+ {
+ return a.pi_ == b.pi_;
+ }
+
+ friend inline bool operator<(shared_count const & a, shared_count const & b)
+ {
+ return std::less()( a.pi_, b.pi_ );
+ }
+
+ void * get_deleter( sp_typeinfo const & ti ) const
+ {
+ return pi_? pi_->get_deleter( ti ): 0;
+ }
+};
+
+
+class weak_count
+{
+private:
+
+ sp_counted_base * pi_;
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ int id_;
+#endif
+
+ friend class shared_count;
+
+public:
+
+ weak_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ }
+
+ weak_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ if(pi_ != 0) pi_->weak_add_ref();
+ }
+
+ weak_count(weak_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ if(pi_ != 0) pi_->weak_add_ref();
+ }
+
+// Move support
+
+#if defined( BOOST_HAS_RVALUE_REFS )
+
+ weak_count(weak_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ r.pi_ = 0;
+ }
+
+#endif
+
+ ~weak_count() // nothrow
+ {
+ if(pi_ != 0) pi_->weak_release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ id_ = 0;
+#endif
+ }
+
+ weak_count & operator= (shared_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if(tmp != 0) tmp->weak_add_ref();
+ if(pi_ != 0) pi_->weak_release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ weak_count & operator= (weak_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if(tmp != 0) tmp->weak_add_ref();
+ if(pi_ != 0) pi_->weak_release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ void swap(weak_count & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+ r.pi_ = pi_;
+ pi_ = tmp;
+ }
+
+ long use_count() const // nothrow
+ {
+ return pi_ != 0? pi_->use_count(): 0;
+ }
+
+ bool empty() const // nothrow
+ {
+ return pi_ == 0;
+ }
+
+ friend inline bool operator==(weak_count const & a, weak_count const & b)
+ {
+ return a.pi_ == b.pi_;
+ }
+
+ friend inline bool operator<(weak_count const & a, weak_count const & b)
+ {
+ return std::less()(a.pi_, b.pi_);
+ }
+};
+
+inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+{
+ if( pi_ == 0 || !pi_->add_ref_lock() )
+ {
+ boost::throw_exception( boost::bad_weak_ptr() );
+ }
+}
+
+inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+{
+ if( pi_ != 0 && !pi_->add_ref_lock() )
+ {
+ pi_ = 0;
+ }
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#ifdef __BORLANDC__
+# pragma warn .8027 // Functions containing try are not expanded inline
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/shared_ptr_nmt.hpp b/include/boost/smart_ptr/detail/shared_ptr_nmt.hpp
new file mode 100644
index 0000000..afc1ec0
--- /dev/null
+++ b/include/boost/smart_ptr/detail/shared_ptr_nmt.hpp
@@ -0,0 +1,182 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
+
+//
+// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
+//
+// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
+//
+
+#include
+#include
+#include
+#include
+
+#ifndef BOOST_NO_AUTO_PTR
+# include // for std::auto_ptr
+#endif
+
+#include // for std::swap
+#include // for std::less
+#include // for std::bad_alloc
+
+namespace boost
+{
+
+template class shared_ptr
+{
+private:
+
+ typedef detail::atomic_count count_type;
+
+public:
+
+ typedef T element_type;
+ typedef T value_type;
+
+ explicit shared_ptr(T * p = 0): px(p)
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try // prevent leak if new throws
+ {
+ pn = new count_type(1);
+ }
+ catch(...)
+ {
+ boost::checked_delete(p);
+ throw;
+ }
+
+#else
+
+ pn = new count_type(1);
+
+ if(pn == 0)
+ {
+ boost::checked_delete(p);
+ boost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+ }
+
+ ~shared_ptr()
+ {
+ if(--*pn == 0)
+ {
+ boost::checked_delete(px);
+ delete pn;
+ }
+ }
+
+ shared_ptr(shared_ptr const & r): px(r.px) // never throws
+ {
+ pn = r.pn;
+ ++*pn;
+ }
+
+ shared_ptr & operator=(shared_ptr const & r)
+ {
+ shared_ptr(r).swap(*this);
+ return *this;
+ }
+
+#ifndef BOOST_NO_AUTO_PTR
+
+ explicit shared_ptr(std::auto_ptr & r)
+ {
+ pn = new count_type(1); // may throw
+ px = r.release(); // fix: moved here to stop leak if new throws
+ }
+
+ shared_ptr & operator=(std::auto_ptr & r)
+ {
+ shared_ptr(r).swap(*this);
+ return *this;
+ }
+
+#endif
+
+ void reset(T * p = 0)
+ {
+ BOOST_ASSERT(p == 0 || p != px);
+ shared_ptr(p).swap(*this);
+ }
+
+ T & operator*() const // never throws
+ {
+ BOOST_ASSERT(px != 0);
+ return *px;
+ }
+
+ T * operator->() const // never throws
+ {
+ BOOST_ASSERT(px != 0);
+ return px;
+ }
+
+ T * get() const // never throws
+ {
+ return px;
+ }
+
+ long use_count() const // never throws
+ {
+ return *pn;
+ }
+
+ bool unique() const // never throws
+ {
+ return *pn == 1;
+ }
+
+ void swap(shared_ptr & other) // never throws
+ {
+ std::swap(px, other.px);
+ std::swap(pn, other.pn);
+ }
+
+private:
+
+ T * px; // contained pointer
+ count_type * pn; // ptr to reference counter
+};
+
+template inline bool operator==(shared_ptr const & a, shared_ptr const & b)
+{
+ return a.get() == b.get();
+}
+
+template inline bool operator!=(shared_ptr const & a, shared_ptr const & b)
+{
+ return a.get() != b.get();
+}
+
+template inline bool operator<(shared_ptr const & a, shared_ptr const & b)
+{
+ return std::less()(a.get(), b.get());
+}
+
+template void swap(shared_ptr & a, shared_ptr & b)
+{
+ a.swap(b);
+}
+
+// get_pointer() enables boost::mem_fn to recognize shared_ptr
+
+template inline T * get_pointer(shared_ptr const & p)
+{
+ return p.get();
+}
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp
new file mode 100644
index 0000000..66e5ec7
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_convertible.hpp
@@ -0,0 +1,76 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_convertible.hpp
+//
+// Copyright 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x610 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+namespace boost
+{
+
+namespace detail
+{
+
+template< class Y, class T > struct sp_convertible
+{
+ typedef char (&yes) [1];
+ typedef char (&no) [2];
+
+ static yes f( T* );
+ static no f( ... );
+
+ enum _vt { value = sizeof( f( static_cast(0) ) ) == sizeof(yes) };
+};
+
+struct sp_empty
+{
+};
+
+template< bool > struct sp_enable_if_convertible_impl;
+
+template<> struct sp_enable_if_convertible_impl
+{
+ typedef sp_empty type;
+};
+
+template<> struct sp_enable_if_convertible_impl
+{
+};
+
+template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
+{
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
new file mode 100644
index 0000000..cab45cc
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
@@ -0,0 +1,70 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base.hpp
+//
+// Copyright 2005, 2006 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+#include
+
+#if defined( BOOST_SP_DISABLE_THREADS )
+# include
+
+#elif defined( BOOST_SP_USE_SPINLOCK )
+# include
+
+#elif defined( BOOST_SP_USE_PTHREADS )
+# include
+
+#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
+# include
+
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+# include
+
+#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
+# include
+
+#elif defined(__HP_aCC) && defined(__ia64)
+# include
+
+#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
+# include
+
+#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
+# include
+
+#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
+# include
+
+#elif defined( BOOST_SP_HAS_SYNC )
+# include
+
+#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
+# include
+
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
+# include
+
+#elif !defined( BOOST_HAS_THREADS )
+# include
+
+#else
+# include
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
new file mode 100644
index 0000000..dffd995
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
@@ -0,0 +1,150 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
+//
+// Copyright 2007 Baruch Zilber
+// Copyright 2007 Boris Gubenko
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int r = static_cast(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
+ if (1 == r)
+ {
+ _Asm_mf();
+ }
+
+ return r - 1;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int v = *pw;
+
+ for (;;)
+ {
+ if (0 == v)
+ {
+ return 0;
+ }
+
+ _Asm_mov_to_ar(_AREG_CCV,
+ v,
+ (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
+ int r = static_cast(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
+ if (r == v)
+ {
+ return r + 1;
+ }
+
+ v = r;
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ ); // TODO use ld.acq here
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
new file mode 100644
index 0000000..51ac56a
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
@@ -0,0 +1,170 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+loop:
+
+ lwarx a, 0, pw
+ addi a, a, 1
+ stwcx. a, 0, pw
+ bne- loop
+ }
+}
+
+inline long atomic_decrement( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+ sync
+
+loop:
+
+ lwarx a, 0, pw
+ addi a, a, -1
+ stwcx. a, 0, pw
+ bne- loop
+
+ isync
+ }
+
+ return a;
+}
+
+inline long atomic_conditional_increment( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+loop:
+
+ lwarx a, 0, pw
+ cmpwi a, 0
+ beq store
+
+ addi a, a, 1
+
+store:
+
+ stwcx. a, 0, pw
+ bne- loop
+ }
+
+ return a;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
new file mode 100644
index 0000000..1234e78
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
@@ -0,0 +1,158 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+// Copyright 2005 Rene Rivera
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+ // int r = *pw;
+ // *pw += dv;
+ // return r;
+
+ asm
+ {
+ mov esi, [pw]
+ mov eax, dv
+ lock xadd dword ptr [esi], eax
+ }
+}
+
+inline void atomic_increment( int * pw )
+{
+ //atomic_exchange_and_add( pw, 1 );
+
+ asm
+ {
+ mov esi, [pw]
+ lock inc dword ptr [esi]
+ }
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // int rv = *pw;
+ // if( rv != 0 ) ++*pw;
+ // return rv;
+
+ asm
+ {
+ mov esi, [pw]
+ mov eax, dword ptr [esi]
+ L0:
+ test eax, eax
+ je L1
+ mov ebx, eax
+ inc ebx
+ lock cmpxchg dword ptr [esi], ebx
+ jne L0
+ L1:
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
new file mode 100644
index 0000000..d122a49
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
@@ -0,0 +1,157 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2006 Peter Dimov
+// Copyright 2005 Ben Hutchings
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ // No barrier is required here but fetchadd always has an acquire or
+ // release barrier associated with it. We choose release as it should be
+ // cheaper.
+ __asm__ ("fetchadd4.rel %0=%1,1" :
+ "=r"(tmp), "=m"(*pw) :
+ "m"( *pw ));
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv;
+
+ __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
+ " cmp.eq p7,p0=1,%0 ;; \n"
+ "(p7) ld4.acq %0=%1 " :
+ "=&r"(rv), "=m"(*pw) :
+ "m"( *pw ) :
+ "p7");
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv, tmp, tmp2;
+
+ __asm__ ("0: ld4 %0=%3 ;; \n"
+ " cmp.eq p7,p0=0,%0 ;; \n"
+ "(p7) br.cond.spnt 1f \n"
+ " mov ar.ccv=%0 \n"
+ " add %1=1,%0 ;; \n"
+ " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
+ " cmp.ne p7,p0=%0,%2 ;; \n"
+ "(p7) br.cond.spnt 0b \n"
+ " mov %0=%1 ;; \n"
+ "1:" :
+ "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
+ "m"( *pw ) :
+ "ar.ccv", "p7");
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ ); // TODO use ld.acq here
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
new file mode 100644
index 0000000..0c69b0b
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
@@ -0,0 +1,172 @@
+#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
+#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
+//
+// Copyright (c) 2009, Spirent Communications, Inc.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "ll %0, %1\n\t"
+ "addiu %0, 1\n\t"
+ "sc %0, %1\n\t"
+ "beqz %0, 0b":
+ "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw )
+ );
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv, tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "ll %1, %2\n\t"
+ "addiu %0, %1, -1\n\t"
+ "sc %0, %2\n\t"
+ "beqz %0, 0b\n\t"
+ "addiu %0, %1, -1":
+ "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw ):
+ "memory"
+ );
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv, tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "ll %0, %2\n\t"
+ "beqz %0, 1f\n\t"
+ "addiu %1, %0, 1\n\t"
+ "sc %1, %2\n\t"
+ "beqz %1, 0b\n\t"
+ "addiu %0, %0, 1\n\t"
+ "1:":
+ "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw ):
+ "memory"
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
new file mode 100644
index 0000000..7f5c414
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
@@ -0,0 +1,181 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ __asm__
+ (
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "addi %1, %1, 1\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b":
+
+ "=m"( *pw ), "=&b"( tmp ):
+ "r"( pw ), "m"( *pw ):
+ "cc"
+ );
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv;
+
+ __asm__ __volatile__
+ (
+ "sync\n\t"
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "addi %1, %1, -1\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b\n\t"
+ "isync":
+
+ "=m"( *pw ), "=&b"( rv ):
+ "r"( pw ), "m"( *pw ):
+ "memory", "cc"
+ );
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv;
+
+ __asm__
+ (
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "cmpwi %1, 0\n\t"
+ "beq 1f\n\t"
+ "addi %1, %1, 1\n\t"
+ "1:\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b":
+
+ "=m"( *pw ), "=&b"( rv ):
+ "r"( pw ), "m"( *pw ):
+ "cc"
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
new file mode 100644
index 0000000..8af6f0a
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
@@ -0,0 +1,166 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
+//
+// Copyright (c) 2006 Piotr Wyderski
+// Copyright (c) 2006 Tomas Puverle
+// Copyright (c) 2006 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+// Thanks to Michael van der Westhuizen
+
+#include
+#include // int32_t
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
+{
+ __asm__ __volatile__( "cas %0, %2, %1"
+ : "+m" (*dest_), "+r" (swap_)
+ : "r" (compare_)
+ : "memory" );
+
+ return swap_;
+}
+
+inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
+{
+ // long r = *pw;
+ // *pw += dv;
+ // return r;
+
+ for( ;; )
+ {
+ int32_t r = *pw;
+
+ if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
+ {
+ return r;
+ }
+ }
+}
+
+inline void atomic_increment( int32_t * pw )
+{
+ atomic_fetch_and_add( pw, 1 );
+}
+
+inline int32_t atomic_decrement( int32_t * pw )
+{
+ return atomic_fetch_and_add( pw, -1 );
+}
+
+inline int32_t atomic_conditional_increment( int32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ for( ;; )
+ {
+ int32_t r = *pw;
+
+ if( r == 0 )
+ {
+ return r;
+ }
+
+ if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
+ {
+ return r;
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int32_t use_count_; // #shared
+ int32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return const_cast< int32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
new file mode 100644
index 0000000..4d7fa8d
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
@@ -0,0 +1,173 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+ // int r = *pw;
+ // *pw += dv;
+ // return r;
+
+ int r;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
+ "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
+ "memory", "cc" // clobbers
+ );
+
+ return r;
+}
+
+inline void atomic_increment( int * pw )
+{
+ //atomic_exchange_and_add( pw, 1 );
+
+ __asm__
+ (
+ "lock\n\t"
+ "incl %0":
+ "=m"( *pw ): // output (%0)
+ "m"( *pw ): // input (%1)
+ "cc" // clobbers
+ );
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // int rv = *pw;
+ // if( rv != 0 ) ++*pw;
+ // return rv;
+
+ int rv, tmp;
+
+ __asm__
+ (
+ "movl %0, %%eax\n\t"
+ "0:\n\t"
+ "test %%eax, %%eax\n\t"
+ "je 1f\n\t"
+ "movl %%eax, %2\n\t"
+ "incl %2\n\t"
+ "lock\n\t"
+ "cmpxchgl %2, %0\n\t"
+ "jne 0b\n\t"
+ "1:":
+ "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
+ "m"( *pw ): // input (%3)
+ "cc" // clobbers
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
new file mode 100644
index 0000000..dfd70e7
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
@@ -0,0 +1,107 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_nt.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ ++use_count_;
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ if( use_count_ == 0 ) return false;
+ ++use_count_;
+ return true;
+ }
+
+ void release() // nothrow
+ {
+ if( --use_count_ == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ ++weak_count_;
+ }
+
+ void weak_release() // nothrow
+ {
+ if( --weak_count_ == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return use_count_;
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp
new file mode 100644
index 0000000..3c56fec
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp
@@ -0,0 +1,135 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_pt.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+ mutable pthread_mutex_t m_;
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
+
+#if defined(__hpux) && defined(_DECTHREADS_)
+ pthread_mutex_init( &m_, pthread_mutexattr_default );
+#else
+ pthread_mutex_init( &m_, 0 );
+#endif
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ pthread_mutex_destroy( &m_ );
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ pthread_mutex_lock( &m_ );
+ ++use_count_;
+ pthread_mutex_unlock( &m_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ pthread_mutex_lock( &m_ );
+ bool r = use_count_ == 0? false: ( ++use_count_, true );
+ pthread_mutex_unlock( &m_ );
+ return r;
+ }
+
+ void release() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long new_use_count = --use_count_;
+ pthread_mutex_unlock( &m_ );
+
+ if( new_use_count == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ ++weak_count_;
+ pthread_mutex_unlock( &m_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long new_weak_count = --weak_count_;
+ pthread_mutex_unlock( &m_ );
+
+ if( new_weak_count == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long r = use_count_;
+ pthread_mutex_unlock( &m_ );
+
+ return r;
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
new file mode 100644
index 0000000..d1b6bec
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
@@ -0,0 +1,113 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_solaris.hpp
+// based on: detail/sp_counted_base_w32.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+// Copyright 2006 Michael van der Westhuizen
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ uint32_t use_count_; // #shared
+ uint32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_inc_32( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ for( ;; )
+ {
+ uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
+ if( tmp == 0 ) return false;
+ if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
+ }
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_dec_32_nv( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_inc_32( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_dec_32_nv( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
new file mode 100644
index 0000000..bbd11e6
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
@@ -0,0 +1,131 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+
+ int r = *pw;
+ *pw += dv;
+ return r;
+}
+
+inline void atomic_increment( int * pw )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+ ++*pw;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+
+ int rv = *pw;
+ if( rv != 0 ) ++*pw;
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ spinlock_pool<1>::scoped_lock lock( &use_count_ );
+ return use_count_;
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
new file mode 100644
index 0000000..41f654e
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
@@ -0,0 +1,155 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
+//
+// Copyright (c) 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include
+#include
+
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include
+#endif
+
+namespace boost
+{
+
+namespace detail
+{
+
+#if INT_MAX >= 2147483647
+
+typedef int sp_int32_t;
+
+#else
+
+typedef long sp_int32_t;
+
+#endif
+
+inline void atomic_increment( sp_int32_t * pw )
+{
+ __sync_fetch_and_add( pw, 1 );
+}
+
+inline sp_int32_t atomic_decrement( sp_int32_t * pw )
+{
+ return __sync_fetch_and_add( pw, -1 );
+}
+
+inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ sp_int32_t r = *pw;
+
+ for( ;; )
+ {
+ if( r == 0 )
+ {
+ return r;
+ }
+
+ sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
+
+ if( r2 == r )
+ {
+ return r;
+ }
+ else
+ {
+ r = r2;
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ sp_int32_t use_count_; // #shared
+ sp_int32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return const_cast< sp_int32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp
new file mode 100644
index 0000000..06aa456
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp
@@ -0,0 +1,130 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_w32.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+ void add_ref_copy()
+ {
+ BOOST_INTERLOCKED_INCREMENT( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ for( ;; )
+ {
+ long tmp = static_cast< long const volatile& >( use_count_ );
+ if( tmp == 0 ) return false;
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
+
+ // work around a code generation bug
+
+ long tmp2 = tmp + 1;
+ if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
+
+#else
+
+ if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
+
+#endif
+ }
+ }
+
+ void release() // nothrow
+ {
+ if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
new file mode 100644
index 0000000..397421a
--- /dev/null
+++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
@@ -0,0 +1,231 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_impl.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
+#endif
+
+#include
+#include
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+#include
+#endif
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+#include // std::allocator
+#endif
+
+#include // std::size_t
+
+namespace boost
+{
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
+void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
+
+#endif
+
+namespace detail
+{
+
+template class sp_counted_impl_p: public sp_counted_base
+{
+private:
+
+ X * px_;
+
+ sp_counted_impl_p( sp_counted_impl_p const & );
+ sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
+
+ typedef sp_counted_impl_p this_type;
+
+public:
+
+ explicit sp_counted_impl_p( X * px ): px_( px )
+ {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ boost::sp_scalar_constructor_hook( px, sizeof(X), this );
+#endif
+ }
+
+ virtual void dispose() // nothrow
+ {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
+#endif
+ boost::checked_delete( px_ );
+ }
+
+ virtual void * get_deleter( detail::sp_typeinfo const & )
+ {
+ return 0;
+ }
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+
+ void * operator new( std::size_t )
+ {
+ return std::allocator