aboutsummaryrefslogtreecommitdiff
path: root/cutl/details/boost/smart_ptr
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-10-19 08:57:20 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-10-19 08:57:20 +0200
commited6115361006240e3c7b02295599e4534cc55a13 (patch)
tree612f12d6c7c49421102041fceb7609db8ab8257e /cutl/details/boost/smart_ptr
parentaf8d1a0139ca105c6830f4ac7c320aca2e1c1f5e (diff)
Update internal Boost subset to 1.54.0
Diffstat (limited to 'cutl/details/boost/smart_ptr')
-rw-r--r--cutl/details/boost/smart_ptr/detail/operator_bool.hpp25
-rw-r--r--cutl/details/boost/smart_ptr/detail/shared_count.hpp165
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_convertible.hpp15
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base.hpp21
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_aix.hpp143
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp10
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_pt.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp162
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_spin.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_sync.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp151
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp1
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_counted_impl.hpp27
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp26
-rw-r--r--cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp45
-rw-r--r--cutl/details/boost/smart_ptr/detail/spinlock.hpp5
-rw-r--r--cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp41
-rw-r--r--cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp4
-rw-r--r--cutl/details/boost/smart_ptr/scoped_array.hpp39
-rw-r--r--cutl/details/boost/smart_ptr/scoped_ptr.hpp36
-rw-r--r--cutl/details/boost/smart_ptr/shared_ptr.hpp600
28 files changed, 1354 insertions, 172 deletions
diff --git a/cutl/details/boost/smart_ptr/detail/operator_bool.hpp b/cutl/details/boost/smart_ptr/detail/operator_bool.hpp
index 842a05d..8ae1527 100644
--- a/cutl/details/boost/smart_ptr/detail/operator_bool.hpp
+++ b/cutl/details/boost/smart_ptr/detail/operator_bool.hpp
@@ -1,14 +1,21 @@
// This header intentionally has no include guards.
//
-// Copyright (c) 2001-2009 Peter Dimov
+// Copyright (c) 2001-2009, 2012 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
-#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
+#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
- operator bool () const
+ explicit operator bool () const BOOST_NOEXCEPT
+ {
+ return px != 0;
+ }
+
+#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
+
+ operator bool () const BOOST_NOEXCEPT
{
return px != 0;
}
@@ -21,7 +28,7 @@
typedef void (*unspecified_bool_type)( this_type*** );
- operator unspecified_bool_type() const // never throws
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: unspecified_bool;
}
@@ -31,18 +38,18 @@
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
- typedef T * (this_type::*unspecified_bool_type)() const;
+ typedef element_type * (this_type::*unspecified_bool_type)() const;
- operator unspecified_bool_type() const // never throws
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: &this_type::get;
}
#else
- typedef T * this_type::*unspecified_bool_type;
+ typedef element_type * this_type::*unspecified_bool_type;
- operator unspecified_bool_type() const // never throws
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: &this_type::px;
}
@@ -50,7 +57,7 @@
#endif
// operator! is redundant, but some compilers need it
- bool operator! () const // never throws
+ bool operator! () const BOOST_NOEXCEPT
{
return px == 0;
}
diff --git a/cutl/details/boost/smart_ptr/detail/shared_count.hpp b/cutl/details/boost/smart_ptr/detail/shared_count.hpp
index 16d6527..77aea5c 100644
--- a/cutl/details/boost/smart_ptr/detail/shared_count.hpp
+++ b/cutl/details/boost/smart_ptr/detail/shared_count.hpp
@@ -35,7 +35,14 @@
// rather than including <memory> directly:
#include <cutl/details/boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <functional> // std::less
-#include <new> // std::bad_alloc
+
+#ifdef BOOST_NO_EXCEPTIONS
+# include <new> // std::bad_alloc
+#endif
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+# include <cutl/details/boost/utility/addressof.hpp>
+#endif
namespace cutl_details_boost
{
@@ -52,6 +59,42 @@ int const weak_count_id = 0x298C38A4;
struct sp_nothrow_tag {};
+template< class D > struct sp_inplace_tag
+{
+};
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+template< class T > class sp_reference_wrapper
+{
+public:
+
+ explicit sp_reference_wrapper( T & t): t_( cutl_details_boost::addressof( t ) )
+ {
+ }
+
+ template< class Y > void operator()( Y * p ) const
+ {
+ (*t_)( p );
+ }
+
+private:
+
+ T * t_;
+};
+
+template< class D > struct sp_convert_reference
+{
+ typedef D type;
+};
+
+template< class D > struct sp_convert_reference< D& >
+{
+ typedef sp_reference_wrapper< D > type;
+};
+
+#endif
+
class weak_count;
class shared_count
@@ -142,6 +185,40 @@ public:
#endif
}
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+ template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = new sp_counted_impl_pd< P, D >( p );
+ }
+ catch( ... )
+ {
+ D::operator_fn( p ); // delete p
+ throw;
+ }
+
+#else
+
+ pi_ = new sp_counted_impl_pd< P, D >( p );
+
+ if( pi_ == 0 )
+ {
+ D::operator_fn( p ); // delete p
+ cutl_details_boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+ }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
@@ -188,6 +265,56 @@ public:
#endif
}
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+ template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef sp_counted_impl_pda< P, D, A > 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, a );
+ }
+ catch(...)
+ {
+ D::operator_fn( 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, a );
+ }
+ else
+ {
+ D::operator_fn( p );
+ cutl_details_boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+ }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
#ifndef BOOST_NO_AUTO_PTR
// auto_ptr<Y> is special cased to provide the strong guarantee
@@ -212,6 +339,33 @@ public:
#endif
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+ template<class Y, class D>
+ explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef typename sp_convert_reference<D>::type D2;
+
+ D2 d2( r.get_deleter() );
+ pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ cutl_details_boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+
+ r.release();
+ }
+
+#endif
+
~shared_count() // nothrow
{
if( pi_ != 0 ) pi_->release();
@@ -228,7 +382,7 @@ public:
if( pi_ != 0 ) pi_->add_ref_copy();
}
-#if defined( BOOST_HAS_RVALUE_REFS )
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_count(shared_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -293,6 +447,11 @@ public:
{
return pi_? pi_->get_deleter( ti ): 0;
}
+
+ void * get_untyped_deleter() const
+ {
+ return pi_? pi_->get_untyped_deleter(): 0;
+ }
};
@@ -335,7 +494,7 @@ public:
// Move support
-#if defined( BOOST_HAS_RVALUE_REFS )
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
diff --git a/cutl/details/boost/smart_ptr/detail/sp_convertible.hpp b/cutl/details/boost/smart_ptr/detail/sp_convertible.hpp
index f8317c4..f9ee9e0 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_convertible.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_convertible.hpp
@@ -48,6 +48,21 @@ template< class Y, class T > struct sp_convertible
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
};
+template< class Y, class T > struct sp_convertible< Y, T[] >
+{
+ enum _vt { value = false };
+};
+
+template< class Y, class T > struct sp_convertible< Y[], T[] >
+{
+ enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
+template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
+{
+ enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
struct sp_empty
{
};
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base.hpp
index d256482..9a36bf9 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base.hpp
@@ -32,22 +32,28 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp>
-#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
-# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
+#elif defined( __SNC__ )
+# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
-#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
-# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
+# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
+#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
+# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
+
+#elif defined( __IBMCPP__ ) && defined( __powerpc )
+# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
+
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
-#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
+#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
-#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
+#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
@@ -59,6 +65,9 @@
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp>
+#elif defined( _AIX )
+# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_aix.hpp>
+
#elif !defined( BOOST_HAS_THREADS )
# include <cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp>
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
index 07438de..6b3b551 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
@@ -104,6 +104,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_aix.hpp
new file mode 100644
index 0000000..6b66a7b
--- /dev/null
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_aix.hpp
@@ -0,0 +1,143 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_aix.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 <cutl/details/boost/detail/sp_typeinfo.hpp>
+#include <builtins.h>
+#include <sys/atomic_op.h>
+
+namespace cutl_details_boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int32_t* pw )
+{
+ // ++*pw;
+
+ fetch_and_add( pw, 1 );
+}
+
+inline int32_t atomic_decrement( int32_t * pw )
+{
+ // return --*pw;
+
+ int32_t originalValue;
+
+ __lwsync();
+ originalValue = fetch_and_add( pw, -1 );
+ __isync();
+
+ return (originalValue - 1);
+}
+
+inline int32_t atomic_conditional_increment( int32_t * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int32_t tmp = fetch_and_add( pw, 0 );
+ for( ;; )
+ {
+ if( tmp == 0 ) return 0;
+ if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
+ }
+}
+
+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;
+ virtual void * get_untyped_deleter() = 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 fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
+ }
+};
+
+} // namespace detail
+
+} // namespace cutl_details_boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
index c7bd3bb..4500914 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
@@ -124,6 +124,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
index 4ada0a2..d04f19f 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
@@ -111,6 +111,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
index 3b2b578..0fd16f3 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
@@ -37,9 +37,12 @@ inline void atomic_increment( int * pw )
__asm__ __volatile__
(
"0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
"ll %0, %1\n\t"
"addiu %0, 1\n\t"
"sc %0, %1\n\t"
+ ".set pop\n\t"
"beqz %0, 0b":
"=&r"( tmp ), "=m"( *pw ):
"m"( *pw )
@@ -55,9 +58,12 @@ inline int atomic_decrement( int * pw )
__asm__ __volatile__
(
"0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
"ll %1, %2\n\t"
"addiu %0, %1, -1\n\t"
"sc %0, %2\n\t"
+ ".set pop\n\t"
"beqz %0, 0b\n\t"
"addiu %0, %1, -1":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
@@ -78,10 +84,13 @@ inline int atomic_conditional_increment( int * pw )
__asm__ __volatile__
(
"0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
"ll %0, %2\n\t"
"beqz %0, 1f\n\t"
"addiu %1, %0, 1\n\t"
"sc %1, %2\n\t"
+ ".set pop\n\t"
"beqz %1, 0b\n\t"
"addiu %0, %0, 1\n\t"
"1:":
@@ -126,6 +135,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
index d00f1d1..a302b3a 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
@@ -135,6 +135,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
index fca4802..8121760 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
@@ -120,6 +120,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
index 68f0646..fc3d72b 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
@@ -127,6 +127,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp
index 89dff6b..92c1ee2 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_nt.hpp
@@ -59,6 +59,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_pt.hpp
index a0e63f8..7ba3867 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_pt.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_pt.hpp
@@ -70,6 +70,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
new file mode 100644
index 0000000..56fce3d
--- /dev/null
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
@@ -0,0 +1,162 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_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
+// Copyright (c) 2011 Emil Dotchevski
+//
+// 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 <cutl/details/boost/detail/sp_typeinfo.hpp>
+#include <inttypes.h> // uint32_t
+
+namespace cutl_details_boost
+{
+
+namespace detail
+{
+
+inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
+{
+ return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
+}
+
+inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
+{
+ // long r = *pw;
+ // *pw += dv;
+ // return r;
+
+ for( ;; )
+ {
+ uint32_t r = *pw;
+
+ if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
+ {
+ return r;
+ }
+ }
+}
+
+inline void atomic_increment( uint32_t * pw )
+{
+ (void) __builtin_cellAtomicIncr32( pw );
+}
+
+inline uint32_t atomic_decrement( uint32_t * pw )
+{
+ return __builtin_cellAtomicDecr32( pw );
+}
+
+inline uint32_t atomic_conditional_increment( uint32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ for( ;; )
+ {
+ uint32_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 & );
+
+ 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;
+ virtual void * get_untyped_deleter() = 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< uint32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace cutl_details_boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_spin.hpp
index 0d17517..0f95421 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_spin.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_spin.hpp
@@ -84,6 +84,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_sync.hpp
index 2814ce7..b1a0b35 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_sync.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_sync.hpp
@@ -109,6 +109,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
new file mode 100644
index 0000000..3973606
--- /dev/null
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
@@ -0,0 +1,151 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
+// 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
+// Copyright 2012 IBM Corp.
+//
+// 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 <cutl/details/boost/detail/sp_typeinfo.hpp>
+
+extern "builtin" void __lwsync(void);
+extern "builtin" void __isync(void);
+extern "builtin" int __fetch_and_add(volatile int* addr, int val);
+extern "builtin" int __compare_and_swap(volatile int*, int*, int);
+
+namespace cutl_details_boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int *pw )
+{
+ // ++*pw;
+ __lwsync();
+ __fetch_and_add(pw, 1);
+ __isync();
+}
+
+inline int atomic_decrement( int *pw )
+{
+ // return --*pw;
+ __lwsync();
+ int originalValue = __fetch_and_add(pw, -1);
+ __isync();
+
+ return (originalValue - 1);
+}
+
+inline int atomic_conditional_increment( int *pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ __lwsync();
+ int v = *const_cast<volatile int*>(pw);
+ for (;;)
+ // loop until state is known
+ {
+ if (v == 0) return 0;
+ if (__compare_and_swap(pw, &v, v + 1))
+ {
+ __isync(); return (v + 1);
+ }
+ }
+}
+
+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)
+ char pad[64] __attribute__((__aligned__(64)));
+ // pad to prevent false sharing
+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;
+ virtual void * get_untyped_deleter() = 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 *const_cast<volatile int*>(&use_count_);
+ }
+};
+
+} // namespace detail
+
+} // namespace cutl_details_boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp
index f69c68d..63c7d7e 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_base_w32.hpp
@@ -67,6 +67,7 @@ public:
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
diff --git a/cutl/details/boost/smart_ptr/detail/sp_counted_impl.hpp b/cutl/details/boost/smart_ptr/detail/sp_counted_impl.hpp
index 5707803..d958544 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_counted_impl.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_counted_impl.hpp
@@ -83,6 +83,11 @@ public:
return 0;
}
+ virtual void * get_untyped_deleter()
+ {
+ return 0;
+ }
+
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
@@ -135,7 +140,11 @@ public:
// pre: d(p) must not throw
- sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
+ sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
+ {
+ }
+
+ sp_counted_impl_pd( P p ): ptr( p ), del()
{
}
@@ -149,6 +158,11 @@ public:
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
}
+ virtual void * get_untyped_deleter()
+ {
+ return &reinterpret_cast<char&>( del );
+ }
+
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
@@ -195,7 +209,11 @@ public:
// pre: d( p ) must not throw
- sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
+ sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
+ {
+ }
+
+ sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
{
}
@@ -218,6 +236,11 @@ public:
{
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
}
+
+ virtual void * get_untyped_deleter()
+ {
+ return &reinterpret_cast<char&>( d_ );
+ }
};
#ifdef __CODEGUARD__
diff --git a/cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp b/cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp
index 7fcd09e..16de21d 100644
--- a/cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp
+++ b/cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp
@@ -20,7 +20,17 @@
// are available.
//
-#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+#ifndef BOOST_SP_NO_SYNC
+
+#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
#define BOOST_SP_HAS_SYNC
@@ -36,14 +46,24 @@
#undef BOOST_SP_HAS_SYNC
#endif
+#if defined( __sh__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC
#endif
-#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
+#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC
#endif
-#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
+#endif
+
+#endif // #ifndef BOOST_SP_NO_SYNC
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp b/cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp
new file mode 100644
index 0000000..245dd22
--- /dev/null
+++ b/cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp
@@ -0,0 +1,45 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_nullptr_t.hpp
+//
+// Copyright 2013 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 <cutl/details/boost/config.hpp>
+#include <cstddef>
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+namespace cutl_details_boost
+{
+
+namespace detail
+{
+
+#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
+
+ typedef decltype(nullptr) sp_nullptr_t;
+
+#else
+
+ typedef std::nullptr_t sp_nullptr_t;
+
+#endif
+
+} // namespace detail
+
+} // namespace cutl_details_boost
+
+#endif // !defined( BOOST_NO_CXX11_NULLPTR )
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/spinlock.hpp b/cutl/details/boost/smart_ptr/detail/spinlock.hpp
index b943ac3..ffc70c5 100644
--- a/cutl/details/boost/smart_ptr/detail/spinlock.hpp
+++ b/cutl/details/boost/smart_ptr/detail/spinlock.hpp
@@ -31,7 +31,10 @@
#include <cutl/details/boost/config.hpp>
#include <cutl/details/boost/smart_ptr/detail/sp_has_sync.hpp>
-#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
+#if defined( BOOST_SP_USE_PTHREADS )
+# include <cutl/details/boost/smart_ptr/detail/spinlock_pt.hpp>
+
+#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include <cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
diff --git a/cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
index cfee653..752c830 100644
--- a/cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
+++ b/cutl/details/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
@@ -2,7 +2,7 @@
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
//
-// Copyright (c) 2008 Peter Dimov
+// Copyright (c) 2008, 2011 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +11,22 @@
#include <cutl/details/boost/smart_ptr/detail/yield_k.hpp>
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
+
+# define BOOST_SP_ARM_BARRIER "dmb"
+# define BOOST_SP_ARM_HAS_LDREX
+
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+
+# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
+# define BOOST_SP_ARM_HAS_LDREX
+
+#else
+
+# define BOOST_SP_ARM_BARRIER ""
+
+#endif
+
namespace cutl_details_boost
{
@@ -29,12 +45,28 @@ public:
{
int r;
+#ifdef BOOST_SP_ARM_HAS_LDREX
+
__asm__ __volatile__(
- "swp %0, %1, [%2]":
+ "ldrex %0, [%2]; \n"
+ "cmp %0, %1; \n"
+ "strexne %0, %1, [%2]; \n"
+ BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
+#else
+
+ __asm__ __volatile__(
+ "swp %0, %1, [%2];\n"
+ BOOST_SP_ARM_BARRIER :
+ "=&r"( r ): // outputs
+ "r"( 1 ), "r"( &v_ ): // inputs
+ "memory", "cc" );
+
+#endif
+
return r == 0;
}
@@ -48,7 +80,7 @@ public:
void unlock()
{
- __asm__ __volatile__( "" ::: "memory" );
+ __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0;
}
@@ -82,4 +114,7 @@ public:
#define BOOST_DETAIL_SPINLOCK_INIT {0}
+#undef BOOST_SP_ARM_BARRIER
+#undef BOOST_SP_ARM_HAS_LDREX
+
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
diff --git a/cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp b/cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp
index 84bf69f..8ae09e3 100644
--- a/cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp
+++ b/cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp
@@ -41,7 +41,11 @@ public:
static spinlock & spinlock_for( void const * pv )
{
+#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
+ std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
+#else
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
+#endif
return pool_[ i ];
}
diff --git a/cutl/details/boost/smart_ptr/scoped_array.hpp b/cutl/details/boost/smart_ptr/scoped_array.hpp
index 0883b43..60b4c0c 100644
--- a/cutl/details/boost/smart_ptr/scoped_array.hpp
+++ b/cutl/details/boost/smart_ptr/scoped_array.hpp
@@ -11,9 +11,10 @@
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
//
+#include <cutl/details/boost/config.hpp>
#include <cutl/details/boost/assert.hpp>
#include <cutl/details/boost/checked_delete.hpp>
-#include <cutl/details/boost/config.hpp> // in case ptrdiff_t not in std
+#include <cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <cutl/details/boost/detail/workaround.hpp>
@@ -53,7 +54,7 @@ public:
typedef T element_type;
- explicit scoped_array( T * p = 0 ) : px( p ) // never throws
+ explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
cutl_details_boost::sp_array_constructor_hook( px );
@@ -68,20 +69,20 @@ public:
cutl_details_boost::checked_array_delete( px );
}
- void reset(T * p = 0) // never throws
+ void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
- T & operator[](std::ptrdiff_t i) const // never throws
+ T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 );
return px[i];
}
- T * get() const // never throws
+ T * get() const BOOST_NOEXCEPT
{
return px;
}
@@ -89,7 +90,7 @@ public:
// implicit conversion to "bool"
#include <cutl/details/boost/smart_ptr/detail/operator_bool.hpp>
- void swap(scoped_array & b) // never throws
+ void swap(scoped_array & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
@@ -97,7 +98,31 @@ public:
}
};
-template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( scoped_array<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( cutl_details_boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( scoped_array<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( cutl_details_boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
+template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
diff --git a/cutl/details/boost/smart_ptr/scoped_ptr.hpp b/cutl/details/boost/smart_ptr/scoped_ptr.hpp
index cd2b2d3..4ddda13 100644
--- a/cutl/details/boost/smart_ptr/scoped_ptr.hpp
+++ b/cutl/details/boost/smart_ptr/scoped_ptr.hpp
@@ -11,8 +11,10 @@
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
//
+#include <cutl/details/boost/config.hpp>
#include <cutl/details/boost/assert.hpp>
#include <cutl/details/boost/checked_delete.hpp>
+#include <cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <cutl/details/boost/detail/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR
@@ -63,7 +65,7 @@ public:
#ifndef BOOST_NO_AUTO_PTR
- explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws
+ explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
cutl_details_boost::sp_scalar_constructor_hook( px );
@@ -98,7 +100,7 @@ public:
return px;
}
- T * get() const // never throws
+ T * get() const BOOST_NOEXCEPT
{
return px;
}
@@ -106,7 +108,7 @@ public:
// implicit conversion to "bool"
#include <cutl/details/boost/smart_ptr/detail/operator_bool.hpp>
- void swap(scoped_ptr & b) // never throws
+ void swap(scoped_ptr & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
@@ -114,14 +116,38 @@ public:
}
};
-template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( scoped_ptr<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( cutl_details_boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( scoped_ptr<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( cutl_details_boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
+template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
-template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
+template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
{
return p.get();
}
diff --git a/cutl/details/boost/smart_ptr/shared_ptr.hpp b/cutl/details/boost/smart_ptr/shared_ptr.hpp
index e6556de..f528a7a 100644
--- a/cutl/details/boost/smart_ptr/shared_ptr.hpp
+++ b/cutl/details/boost/smart_ptr/shared_ptr.hpp
@@ -32,6 +32,7 @@
#include <cutl/details/boost/smart_ptr/detail/shared_count.hpp>
#include <cutl/details/boost/detail/workaround.hpp>
#include <cutl/details/boost/smart_ptr/detail/sp_convertible.hpp>
+#include <cutl/details/boost/smart_ptr/detail/sp_nullptr_t.hpp>
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
#include <cutl/details/boost/smart_ptr/detail/spinlock_pool.hpp>
@@ -41,6 +42,7 @@
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
+#include <cstddef> // for std::size_t
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
@@ -50,56 +52,157 @@
#endif
#endif
-#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
-# pragma warning(push)
-# pragma warning(disable:4284) // odd return type for operator->
-#endif
-
namespace cutl_details_boost
{
template<class T> class shared_ptr;
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
-template<class T> class enable_shared_from_this2;
+class enable_shared_from_raw;
namespace detail
{
-struct static_cast_tag {};
-struct const_cast_tag {};
-struct dynamic_cast_tag {};
-struct polymorphic_cast_tag {};
+// sp_element, element_type
+
+template< class T > struct sp_element
+{
+ typedef T type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_element< T[] >
+{
+ typedef T type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_element< T[N] >
+{
+ typedef T type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_dereference, return type of operator*
-template<class T> struct shared_ptr_traits
+template< class T > struct sp_dereference
{
- typedef T & reference;
+ typedef T & type;
};
-template<> struct shared_ptr_traits<void>
+template<> struct sp_dereference< void >
{
- typedef void reference;
+ typedef void type;
};
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
-template<> struct shared_ptr_traits<void const>
+template<> struct sp_dereference< void const >
{
- typedef void reference;
+ typedef void type;
};
-template<> struct shared_ptr_traits<void volatile>
+template<> struct sp_dereference< void volatile >
{
- typedef void reference;
+ typedef void type;
};
-template<> struct shared_ptr_traits<void const volatile>
+template<> struct sp_dereference< void const volatile >
{
- typedef void reference;
+ typedef void type;
+};
+
+#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_dereference< T[] >
+{
+ typedef void type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_dereference< T[N] >
+{
+ typedef void type;
};
#endif
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_member_access, return type of operator->
+
+template< class T > struct sp_member_access
+{
+ typedef T * type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_member_access< T[] >
+{
+ typedef void type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_member_access< T[N] >
+{
+ typedef void type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_array_access, return type of operator[]
+
+template< class T > struct sp_array_access
+{
+ typedef void type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_array_access< T[] >
+{
+ typedef T & type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_array_access< T[N] >
+{
+ typedef T & type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_extent, for operator[] index check
+
+template< class T > struct sp_extent
+{
+ enum _vt { value = 0 };
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, std::size_t N > struct sp_extent< T[N] >
+{
+ enum _vt { value = N };
+};
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
// enable_shared_from_this support
template< class X, class Y, class T > inline void sp_enable_shared_from_this( cutl_details_boost::shared_ptr<X> const * ppx, Y const * py, cutl_details_boost::enable_shared_from_this< T > const * pe )
@@ -110,13 +213,7 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( cu
}
}
-template< class X, class Y, class T > inline void sp_enable_shared_from_this( cutl_details_boost::shared_ptr<X> * ppx, Y const * py, cutl_details_boost::enable_shared_from_this2< T > const * pe )
-{
- if( pe != 0 )
- {
- pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
- }
-}
+template< class X, class Y > inline void sp_enable_shared_from_this( cutl_details_boost::shared_ptr<X> * ppx, Y const * py, cutl_details_boost::enable_shared_from_raw const * pe );
#ifdef _MANAGED
@@ -154,6 +251,69 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
#endif
+// sp_assert_convertible
+
+template< class Y, class T > inline void sp_assert_convertible()
+{
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+ // static_assert( sp_convertible< Y, T >::value );
+ typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
+ (void)sizeof( tmp );
+
+#else
+
+ T* p = static_cast< Y* >( 0 );
+ (void)p;
+
+#endif
+}
+
+// pointer constructor helper
+
+template< class T, class Y > inline void sp_pointer_construct( cutl_details_boost::shared_ptr< T > * ppx, Y * p, cutl_details_boost::detail::shared_count & pn )
+{
+ cutl_details_boost::detail::shared_count( p ).swap( pn );
+ cutl_details_boost::detail::sp_enable_shared_from_this( ppx, p, p );
+}
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, class Y > inline void sp_pointer_construct( cutl_details_boost::shared_ptr< T[] > * /*ppx*/, Y * p, cutl_details_boost::detail::shared_count & pn )
+{
+ sp_assert_convertible< Y[], T[] >();
+ cutl_details_boost::detail::shared_count( p, cutl_details_boost::checked_array_deleter< T >() ).swap( pn );
+}
+
+template< class T, std::size_t N, class Y > inline void sp_pointer_construct( cutl_details_boost::shared_ptr< T[N] > * /*ppx*/, Y * p, cutl_details_boost::detail::shared_count & pn )
+{
+ sp_assert_convertible< Y[N], T[N] >();
+ cutl_details_boost::detail::shared_count( p, cutl_details_boost::checked_array_deleter< T >() ).swap( pn );
+}
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// deleter constructor helper
+
+template< class T, class Y > inline void sp_deleter_construct( cutl_details_boost::shared_ptr< T > * ppx, Y * p )
+{
+ cutl_details_boost::detail::sp_enable_shared_from_this( ppx, p, p );
+}
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, class Y > inline void sp_deleter_construct( cutl_details_boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
+{
+ sp_assert_convertible< Y[], T[] >();
+}
+
+template< class T, std::size_t N, class Y > inline void sp_deleter_construct( cutl_details_boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
+{
+ sp_assert_convertible< Y[N], T[N] >();
+}
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
} // namespace detail
@@ -174,19 +334,24 @@ private:
public:
- typedef T element_type;
- typedef T value_type;
- typedef T * pointer;
- typedef typename cutl_details_boost::detail::shared_ptr_traits<T>::reference reference;
+ typedef typename cutl_details_boost::detail::sp_element< T >::type element_type;
+
+ shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
+ {
+ }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
- shared_ptr(): px(0), pn() // never throws in 1.30+
+ shared_ptr( cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
{
}
+#endif
+
template<class Y>
- explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
+ explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
{
- cutl_details_boost::detail::sp_enable_shared_from_this( this, p, p );
+ cutl_details_boost::detail::sp_pointer_construct( this, p, pn );
}
//
@@ -195,29 +360,58 @@ public:
// shared_ptr will release p by calling d(p)
//
- template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
+ template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
{
- cutl_details_boost::detail::sp_enable_shared_from_this( this, p, p );
+ cutl_details_boost::detail::sp_deleter_construct( this, p );
}
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D> shared_ptr( cutl_details_boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
+ {
+ }
+
+#endif
+
// As above, but with allocator. A's copy constructor shall not throw.
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
- cutl_details_boost::detail::sp_enable_shared_from_this( this, p, p );
+ cutl_details_boost::detail::sp_deleter_construct( this, p );
+ }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D, class A> shared_ptr( cutl_details_boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
+ {
+ }
+
+#endif
+
+// generated copy constructor, destructor are fine...
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// ... except in C++0x, move disables the implicit copy
+
+ shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+ {
}
-// generated copy constructor, destructor are fine
+#endif
template<class Y>
- explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
+ explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
{
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
+
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
- shared_ptr( weak_ptr<Y> const & r, cutl_details_boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, cutl_details_boost::detail::sp_nothrow_tag() ) // never throws
+ shared_ptr( weak_ptr<Y> const & r, cutl_details_boost::detail::sp_nothrow_tag )
+ BOOST_NOEXCEPT : px( 0 ), pn( r.pn, cutl_details_boost::detail::sp_nothrow_tag() )
{
if( !pn.empty() )
{
@@ -235,72 +429,80 @@ public:
shared_ptr( shared_ptr<Y> const & r )
#endif
- : px( r.px ), pn( r.pn ) // never throws
+ BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
}
// aliasing
template< class Y >
- shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
+ shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
{
}
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, cutl_details_boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
- {
- }
+#ifndef BOOST_NO_AUTO_PTR
template<class Y>
- shared_ptr(shared_ptr<Y> const & r, cutl_details_boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
+ explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
{
- }
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, cutl_details_boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
- {
- if(px == 0) // need to allocate new counter -- the cast failed
- {
- pn = cutl_details_boost::detail::shared_count();
- }
- }
+ Y * tmp = r.get();
+ pn = cutl_details_boost::detail::shared_count( r );
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, cutl_details_boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
- {
- if(px == 0)
- {
- cutl_details_boost::throw_exception(std::bad_cast());
- }
+ cutl_details_boost::detail::sp_deleter_construct( this, tmp );
}
-#ifndef BOOST_NO_AUTO_PTR
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y>
- explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
+ shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
{
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
+
Y * tmp = r.get();
- pn = cutl_details_boost::detail::shared_count(r);
- cutl_details_boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
+ pn = cutl_details_boost::detail::shared_count( r );
+
+ cutl_details_boost::detail::sp_deleter_construct( this, tmp );
}
-#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template<class Ap>
explicit shared_ptr( Ap r, typename cutl_details_boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
{
- typename Ap::element_type * tmp = r.get();
+ typedef typename Ap::element_type Y;
+
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
+
+ Y * tmp = r.get();
pn = cutl_details_boost::detail::shared_count( r );
- cutl_details_boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
- }
+ cutl_details_boost::detail::sp_deleter_construct( this, tmp );
+ }
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_NO_AUTO_PTR
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template< class Y, class D >
+ shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
+ {
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
+
+ typename std::unique_ptr< Y, D >::pointer tmp = r.get();
+ pn = cutl_details_boost::detail::shared_count( r );
+
+ cutl_details_boost::detail::sp_deleter_construct( this, tmp );
+ }
+
+#endif
+
// assignment
- shared_ptr & operator=( shared_ptr const & r ) // never throws
+ shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
{
this_type(r).swap(*this);
return *this;
@@ -309,7 +511,7 @@ public:
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
template<class Y>
- shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
+ shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
{
this_type(r).swap(*this);
return *this;
@@ -322,11 +524,20 @@ public:
template<class Y>
shared_ptr & operator=( std::auto_ptr<Y> & r )
{
- this_type(r).swap(*this);
+ this_type( r ).swap( *this );
+ return *this;
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y>
+ shared_ptr & operator=( std::auto_ptr<Y> && r )
+ {
+ this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
return *this;
}
-#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template<class Ap>
typename cutl_details_boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
@@ -335,16 +546,26 @@ public:
return *this;
}
-
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_NO_AUTO_PTR
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y, class D>
+ shared_ptr & operator=( std::unique_ptr<Y, D> && r )
+ {
+ this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
+ return *this;
+ }
+
+#endif
+
// Move support
-#if defined( BOOST_HAS_RVALUE_REFS )
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
+ shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
{
pn.swap( r.pn );
r.px = 0;
@@ -360,20 +581,22 @@ public:
shared_ptr( shared_ptr<Y> && r )
#endif
- : px( r.px ), pn() // never throws
+ BOOST_NOEXCEPT : px( r.px ), pn()
{
+ cutl_details_boost::detail::sp_assert_convertible< Y, T >();
+
pn.swap( r.pn );
r.px = 0;
}
- shared_ptr & operator=( shared_ptr && r ) // never throws
+ shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
{
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
return *this;
}
template<class Y>
- shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
+ shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
{
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
return *this;
@@ -381,15 +604,25 @@ public:
#endif
- void reset() // never throws in 1.30+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ shared_ptr & operator=( cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
+ {
+ this_type().swap(*this);
+ return *this;
+ }
+
+#endif
+
+ void reset() BOOST_NOEXCEPT // never throws in 1.30+
{
this_type().swap(*this);
}
- template<class Y> void reset(Y * p) // Y must be complete
+ template<class Y> void reset( Y * p ) // Y must be complete
{
- BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
- this_type(p).swap(*this);
+ BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
+ this_type( p ).swap( *this );
}
template<class Y, class D> void reset( Y * p, D d )
@@ -402,24 +635,35 @@ public:
this_type( p, d, a ).swap( *this );
}
- template<class Y> void reset( shared_ptr<Y> const & r, T * p )
+ template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
{
this_type( r, p ).swap( *this );
}
-
- reference operator* () const // never throws
+
+ // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ typename cutl_details_boost::detail::sp_dereference< T >::type operator* () const
{
- BOOST_ASSERT(px != 0);
+ BOOST_ASSERT( px != 0 );
return *px;
}
-
- T * operator-> () const // never throws
+
+ // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ typename cutl_details_boost::detail::sp_member_access< T >::type operator-> () const
{
- BOOST_ASSERT(px != 0);
+ BOOST_ASSERT( px != 0 );
return px;
}
+
+ // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ typename cutl_details_boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
+ {
+ BOOST_ASSERT( px != 0 );
+ BOOST_ASSERT( i >= 0 && ( i < cutl_details_boost::detail::sp_extent< T >::value || cutl_details_boost::detail::sp_extent< T >::value == 0 ) );
+
+ return px[ i ];
+ }
- T * get() const // never throws
+ element_type * get() const BOOST_NOEXCEPT
{
return px;
}
@@ -427,33 +671,43 @@ public:
// implicit conversion to "bool"
#include <cutl/details/boost/smart_ptr/detail/operator_bool.hpp>
- bool unique() const // never throws
+ bool unique() const BOOST_NOEXCEPT
{
return pn.unique();
}
- long use_count() const // never throws
+ long use_count() const BOOST_NOEXCEPT
{
return pn.use_count();
}
- void swap(shared_ptr<T> & other) // never throws
+ void swap( shared_ptr & other ) BOOST_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
- template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
+ template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+ {
+ return pn < rhs.pn;
+ }
+
+ template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
{
return pn < rhs.pn;
}
- void * _internal_get_deleter( cutl_details_boost::detail::sp_typeinfo const & ti ) const
+ void * _internal_get_deleter( cutl_details_boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
{
return pn.get_deleter( ti );
}
- bool _internal_equiv( shared_ptr const & r ) const
+ void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
+ {
+ return pn.get_untyped_deleter();
+ }
+
+ bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
{
return px == r.px && pn == r.pn;
}
@@ -471,17 +725,17 @@ private:
#endif
- T * px; // contained pointer
+ element_type * px; // contained pointer
cutl_details_boost::detail::shared_count pn; // reference counter
}; // shared_ptr
-template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
+template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
{
return a.get() == b.get();
}
-template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
+template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
{
return a.get() != b.get();
}
@@ -490,64 +744,90 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share
// Resolve the ambiguity between our op!= and the one in rel_ops
-template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
+template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
{
return a.get() != b.get();
}
#endif
-template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( shared_ptr<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
- return a._internal_less(b);
+ return p.get() == 0;
}
-template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
+template<class T> inline bool operator==( cutl_details_boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
{
- a.swap(b);
+ return p.get() == 0;
}
-template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
+template<class T> inline bool operator!=( shared_ptr<T> const & p, cutl_details_boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::static_cast_tag());
+ return p.get() != 0;
}
-template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
+template<class T> inline bool operator!=( cutl_details_boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::const_cast_tag());
+ return p.get() != 0;
}
-template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
+#endif
+
+template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::dynamic_cast_tag());
+ return a.owner_before( b );
}
-// shared_*_cast names are deprecated. Use *_pointer_cast instead.
+template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
+{
+ a.swap(b);
+}
-template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::static_cast_tag());
+ (void) static_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = static_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
}
-template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::dynamic_cast_tag());
+ (void) const_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = const_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
}
-template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
- return shared_ptr<T>(r, cutl_details_boost::detail::polymorphic_cast_tag());
+ (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = dynamic_cast< E* >( r.get() );
+ return p? shared_ptr<T>( r, p ): shared_ptr<T>();
}
-template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
- BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
- return shared_static_cast<T>(r);
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = reinterpret_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
}
// get_pointer() enables cutl_details_boost::mem_fn to recognize shared_ptr
-template<class T> inline T * get_pointer(shared_ptr<T> const & p)
+template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
{
return p.get();
}
@@ -589,6 +869,9 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
// get_deleter
+namespace detail
+{
+
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
@@ -596,7 +879,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
-template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
+template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
{
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
return const_cast<D *>(static_cast<D const *>(q));
@@ -604,18 +887,64 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
#else
-template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
+template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
{
- return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
+ return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
}
#endif
+class esft2_deleter_wrapper
+{
+private:
+
+ shared_ptr<void> deleter_;
+
+public:
+
+ esft2_deleter_wrapper()
+ {
+ }
+
+ template< class T > void set_deleter( shared_ptr<T> const & deleter )
+ {
+ deleter_ = deleter;
+ }
+
+ template<typename D> D* get_deleter() const BOOST_NOEXCEPT
+ {
+ return cutl_details_boost::detail::basic_get_deleter<D>( deleter_ );
+ }
+
+ template< class T> void operator()( T* )
+ {
+ BOOST_ASSERT( deleter_.use_count() <= 1 );
+ deleter_.reset();
+ }
+};
+
+} // namespace detail
+
+template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ D *del = cutl_details_boost::detail::basic_get_deleter<D>(p);
+
+ if(del == 0)
+ {
+ cutl_details_boost::detail::esft2_deleter_wrapper *del_wrapper = cutl_details_boost::detail::basic_get_deleter<cutl_details_boost::detail::esft2_deleter_wrapper>(p);
+// The following get_deleter method call is fully qualified because
+// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
+ if(del_wrapper) del = del_wrapper->::cutl_details_boost::detail::esft2_deleter_wrapper::get_deleter<D>();
+ }
+
+ return del;
+}
+
// atomic access
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
-template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
+template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
{
return false;
}
@@ -688,13 +1017,18 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
return atomic_compare_exchange( p, v, w ); // std::move( w )
}
-#endif
+#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
-} // namespace cutl_details_boost
+// hash_value
-#ifdef BOOST_MSVC
-# pragma warning(pop)
-#endif
+template< class T > struct hash;
+
+template< class T > std::size_t hash_value( cutl_details_boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return cutl_details_boost::hash< T* >()( p.get() );
+}
+
+} // namespace cutl_details_boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)