diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp
index 085b12f..1eae671 100644
--- a/include/boost/detail/shared_count.hpp
+++ b/include/boost/detail/shared_count.hpp
@@ -46,6 +46,8 @@ int const weak_count_id = 0x298C38A4;
#endif
+struct sp_nothrow_tag {};
+
class weak_count;
class shared_count
@@ -216,6 +218,7 @@ public:
}
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
{
@@ -248,6 +251,11 @@ public:
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_;
@@ -364,6 +372,17 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
}
}
+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
diff --git a/include/boost/detail/sp_counted_base.hpp b/include/boost/detail/sp_counted_base.hpp
index f2e59b9..312893d 100644
--- a/include/boost/detail/sp_counted_base.hpp
+++ b/include/boost/detail/sp_counted_base.hpp
@@ -23,6 +23,10 @@
# include
+#elif defined( BOOST_SP_USE_SPINLOCK )
+
+# include
+
#elif defined( BOOST_SP_USE_PTHREADS )
# include
diff --git a/include/boost/detail/sp_counted_base_spin.hpp b/include/boost/detail/sp_counted_base_spin.hpp
new file mode 100644
index 0000000..610a468
--- /dev/null
+++ b/include/boost/detail/sp_counted_base_spin.hpp
@@ -0,0 +1,131 @@
+#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
+#define BOOST_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_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock.hpp b/include/boost/detail/spinlock.hpp
new file mode 100644
index 0000000..e273647
--- /dev/null
+++ b/include/boost/detail/spinlock.hpp
@@ -0,0 +1,47 @@
+#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/spinlock.hpp
+//
+// Copyright (c) 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)
+//
+// struct spinlock
+// {
+// void lock();
+// bool try_lock();
+// void unlock();
+//
+// class scoped_lock;
+// };
+//
+// #define BOOST_DETAIL_SPINLOCK_INIT
+//
+
+#include
+
+#if defined(__GNUC__) && defined( __arm__ )
+# include
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+# include
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# include
+#elif defined(BOOST_HAS_PTHREADS)
+# include
+#elif !defined(BOOST_HAS_THREADS)
+# include
+#else
+# error Unrecognized threading platform
+#endif
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_gcc_arm.hpp b/include/boost/detail/spinlock_gcc_arm.hpp
new file mode 100644
index 0000000..c21163b
--- /dev/null
+++ b/include/boost/detail/spinlock_gcc_arm.hpp
@@ -0,0 +1,85 @@
+#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
+
+//
+// Copyright (c) 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
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ int v_;
+
+public:
+
+ bool try_lock()
+ {
+ int r;
+
+ __asm__ __volatile__(
+ "swp %0, %1, [%2]":
+ "=&r"( r ): // outputs
+ "r"( 1 ), "r"( &v_ ): // inputs
+ "memory", "cc" );
+
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ boost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ __asm__ __volatile__( "" ::: "memory" );
+ *const_cast< int volatile* >( &v_ ) = 0;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_nt.hpp b/include/boost/detail/spinlock_nt.hpp
new file mode 100644
index 0000000..f03ba08
--- /dev/null
+++ b/include/boost/detail/spinlock_nt.hpp
@@ -0,0 +1,89 @@
+#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 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
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ bool locked_;
+
+public:
+
+ inline bool try_lock()
+ {
+ if( locked_ )
+ {
+ return false;
+ }
+ else
+ {
+ locked_ = true;
+ return true;
+ }
+ }
+
+ inline void lock()
+ {
+ BOOST_ASSERT( !locked_ );
+ locked_ = true;
+ }
+
+ inline void unlock()
+ {
+ BOOST_ASSERT( locked_ );
+ locked_ = false;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT { false }
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_pool.hpp b/include/boost/detail/spinlock_pool.hpp
new file mode 100644
index 0000000..92d26cb
--- /dev/null
+++ b/include/boost/detail/spinlock_pool.hpp
@@ -0,0 +1,85 @@
+#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/spinlock_pool.hpp
+//
+// Copyright (c) 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)
+//
+// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
+// spinlock_pool<1> is reserved for shared_ptr reference counts
+// spinlock_pool<2> is reserved for shared_ptr atomic access
+//
+
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+template< int I > class spinlock_pool
+{
+private:
+
+ static spinlock pool_[ 41 ];
+
+public:
+
+ static spinlock & spinlock_for( void const * pv )
+ {
+ size_t i = reinterpret_cast< size_t >( pv ) % 41;
+ return pool_[ i ];
+ }
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
+ {
+ sp_.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
+{
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT
+};
+
+} // namespace detail
+} // namespace boost
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_pt.hpp b/include/boost/detail/spinlock_pt.hpp
new file mode 100644
index 0000000..dfb2d6f
--- /dev/null
+++ b/include/boost/detail/spinlock_pt.hpp
@@ -0,0 +1,79 @@
+#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 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
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ pthread_mutex_t v_;
+
+public:
+
+ bool try_lock()
+ {
+ return pthread_mutex_trylock( &v_ ) == 0;
+ }
+
+ void lock()
+ {
+ pthread_mutex_lock( &v_ );
+ }
+
+ void unlock()
+ {
+ pthread_mutex_unlock( &v_ );
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_sync.hpp b/include/boost/detail/spinlock_sync.hpp
new file mode 100644
index 0000000..d602365
--- /dev/null
+++ b/include/boost/detail/spinlock_sync.hpp
@@ -0,0 +1,83 @@
+#ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 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
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ int v_;
+
+public:
+
+ bool try_lock()
+ {
+ int r = __sync_lock_test_and_set( &v_, 1 );
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ boost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ __sync_lock_release( &v_ );
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
diff --git a/include/boost/detail/spinlock_w32.hpp b/include/boost/detail/spinlock_w32.hpp
new file mode 100644
index 0000000..76cfe8f
--- /dev/null
+++ b/include/boost/detail/spinlock_w32.hpp
@@ -0,0 +1,113 @@
+#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
+#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 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
+
+// BOOST_COMPILER_FENCE
+
+#if defined(__INTEL_COMPILER)
+
+#define BOOST_COMPILER_FENCE __memory_barrier();
+
+#elif defined( _MSC_VER ) && _MSC_VER >= 1310
+
+extern "C" void _ReadWriteBarrier();
+#pragma intrinsic( _ReadWriteBarrier )
+
+#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
+
+#elif defined(__GNUC__)
+
+#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" ::: "memory" );
+
+#else
+
+#define BOOST_COMPILER_FENCE
+
+#endif
+
+//
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ long v_;
+
+public:
+
+ bool try_lock()
+ {
+ long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
+
+ BOOST_COMPILER_FENCE
+
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ boost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ BOOST_COMPILER_FENCE
+ *const_cast< long volatile* >( &v_ ) = 0;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
diff --git a/include/boost/detail/yield_k.hpp b/include/boost/detail/yield_k.hpp
new file mode 100644
index 0000000..d856d57
--- /dev/null
+++ b/include/boost/detail/yield_k.hpp
@@ -0,0 +1,145 @@
+#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
+#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/yield_k.hpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// void yield( unsigned k );
+//
+// Typical use:
+//
+// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
+//
+// 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
+
+// BOOST_SMT_PAUSE
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
+
+extern "C" void _mm_pause();
+#pragma intrinsic( _mm_pause )
+
+#define BOOST_SMT_PAUSE _mm_pause();
+
+#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+
+#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" ::: "memory" );
+
+#endif
+
+//
+
+#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include
+#endif
+
+namespace boost
+{
+
+namespace detail
+{
+
+#if !defined( BOOST_USE_WINDOWS_H )
+ extern "C" void __stdcall Sleep( unsigned ms );
+#endif
+
+inline void yield( unsigned k )
+{
+ if( k < 4 )
+ {
+ }
+#if defined( BOOST_SMT_PAUSE )
+ else if( k < 16 )
+ {
+ BOOST_SMT_PAUSE
+ }
+#endif
+ else if( k < 32 )
+ {
+ Sleep( 0 );
+ }
+ else
+ {
+ Sleep( 1 );
+ }
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#elif defined( BOOST_HAS_PTHREADS )
+
+#include
+#include
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned k )
+{
+ if( k < 4 )
+ {
+ }
+#if defined( BOOST_SMT_PAUSE )
+ else if( k < 16 )
+ {
+ BOOST_SMT_PAUSE
+ }
+#endif
+ else if( k < 32 || k & 1 )
+ {
+ sched_yield();
+ }
+ else
+ {
+ struct timespec rqtp = { 0 };
+
+ rqtp.tv_sec = 0;
+ rqtp.tv_nsec = 1000;
+
+ nanosleep( &rqtp, 0 );
+ }
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#else
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned )
+{
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#endif
+
+#endif // #ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
diff --git a/include/boost/scoped_array.hpp b/include/boost/scoped_array.hpp
index 667dfff..fcb80f6 100644
--- a/include/boost/scoped_array.hpp
+++ b/include/boost/scoped_array.hpp
@@ -46,6 +46,9 @@ private:
typedef scoped_array this_type;
+ void operator==( scoped_array const& ) const;
+ void operator!=( scoped_array const& ) const;
+
public:
typedef T element_type;
diff --git a/include/boost/scoped_ptr.hpp b/include/boost/scoped_ptr.hpp
index 651deed..279cec3 100644
--- a/include/boost/scoped_ptr.hpp
+++ b/include/boost/scoped_ptr.hpp
@@ -47,6 +47,9 @@ private:
typedef scoped_ptr this_type;
+ void operator==( scoped_ptr const& ) const;
+ void operator!=( scoped_ptr const& ) const;
+
public:
typedef T element_type;
diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp
index 5e1abd8..6f4d49a 100644
--- a/include/boost/shared_ptr.hpp
+++ b/include/boost/shared_ptr.hpp
@@ -31,7 +31,14 @@
#include // for std::swap
#include // for std::less
#include // for std::bad_cast
+
+#if !defined(BOOST_NO_IOSTREAM)
+#if !defined(BOOST_NO_IOSFWD)
#include // for std::basic_ostream
+#else
+#include
+#endif
+#endif
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
@@ -207,6 +214,15 @@ public:
px = r.px;
}
+ template
+ shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
+ {
+ if( !pn.empty() )
+ {
+ px = r.px;
+ }
+ }
+
template
shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws
{
@@ -555,6 +571,8 @@ template inline T * get_pointer(shared_ptr const & p)
// operator<<
+#if !defined(BOOST_NO_IOSTREAM)
+
#if defined(__GNUC__) && (__GNUC__ < 3)
template std::ostream & operator<< (std::ostream & os, shared_ptr const & p)
@@ -584,6 +602,8 @@ template std::basic_ostream & operator<< (std::
#endif // __GNUC__ < 3
+#endif // !defined(BOOST_NO_IOSTREAM)
+
// get_deleter
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
diff --git a/include/boost/weak_ptr.hpp b/include/boost/weak_ptr.hpp
index ae606f2..4335738 100644
--- a/include/boost/weak_ptr.hpp
+++ b/include/boost/weak_ptr.hpp
@@ -93,31 +93,7 @@ public:
shared_ptr lock() const // never throws
{
-#if defined(BOOST_HAS_THREADS)
-
- // optimization: avoid throw overhead
- if(expired())
- {
- return shared_ptr();
- }
-
- try
- {
- return shared_ptr(*this);
- }
- catch(bad_weak_ptr const &)
- {
- // Q: how can we get here?
- // A: another thread may have invalidated r after the use_count test above.
- return shared_ptr();
- }
-
-#else
-
- // optimization: avoid try/catch overhead when single threaded
- return expired()? shared_ptr(): shared_ptr(*this);
-
-#endif
+ return shared_ptr( *this, boost::detail::sp_nothrow_tag() );
}
long use_count() const // never throws
diff --git a/shared_ptr.htm b/shared_ptr.htm
index e108278..5b4444f 100644
--- a/shared_ptr.htm
+++ b/shared_ptr.htm
@@ -373,8 +373,8 @@ q = p;
long use_count() const; // never throws
Returns: the number of shared_ptr objects, *this included,
- that share ownership with *this, or an unspecified nonnegative
- value when *this is empty.
+ that share ownership with *this, or 0 when *this
+ is empty.
Throws: nothing.
Notes: use_count()
is not necessarily efficient. Use only
for debugging and testing purposes, not for production code.
@@ -522,6 +522,7 @@ q = p;
Returns: If *this owns a deleter d
of type (cv-unqualified) D, returns &d
;
otherwise returns 0.
+ Throws: nothing.
See shared_ptr_example.cpp for a
@@ -709,8 +710,8 @@ int * p = a.release();
$Date$
Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
- Copyright 2002-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.
+ Copyright 2002-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.