diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-03-21 15:45:20 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-03-21 15:46:37 +0900 |
commit | 733b5d5ae2c5d625211e2985ac25728ac3f54883 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /boost/smart_ptr | |
parent | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (diff) | |
download | boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.tar.gz boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.tar.bz2 boost-733b5d5ae2c5d625211e2985ac25728ac3f54883.zip |
Imported Upstream version 1.58.0upstream/1.58.0
Change-Id: If0072143aa26874812e0db6872e1efb10a3e5e94
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/smart_ptr')
-rw-r--r-- | boost/smart_ptr/detail/array_allocator.hpp | 2 | ||||
-rw-r--r-- | boost/smart_ptr/detail/sp_convertible.hpp | 1 | ||||
-rw-r--r-- | boost/smart_ptr/detail/sp_counted_base.hpp | 11 | ||||
-rw-r--r-- | boost/smart_ptr/detail/sp_counted_base_clang.hpp | 140 | ||||
-rw-r--r-- | boost/smart_ptr/detail/sp_counted_impl.hpp | 6 | ||||
-rw-r--r-- | boost/smart_ptr/detail/spinlock_pool.hpp | 4 | ||||
-rw-r--r-- | boost/smart_ptr/enable_shared_from_raw.hpp | 26 | ||||
-rw-r--r-- | boost/smart_ptr/enable_shared_from_this.hpp | 10 | ||||
-rw-r--r-- | boost/smart_ptr/shared_ptr.hpp | 2 |
9 files changed, 192 insertions, 10 deletions
diff --git a/boost/smart_ptr/detail/array_allocator.hpp b/boost/smart_ptr/detail/array_allocator.hpp index 4f9dc2b4b8..71479967bc 100644 --- a/boost/smart_ptr/detail/array_allocator.hpp +++ b/boost/smart_ptr/detail/array_allocator.hpp @@ -213,7 +213,7 @@ namespace boost { typedef Y* pointer; typedef const Y* const_pointer; typedef std::size_t size_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef Y& reference; typedef const Y& const_reference; diff --git a/boost/smart_ptr/detail/sp_convertible.hpp b/boost/smart_ptr/detail/sp_convertible.hpp index 31b2627825..4bba9ed444 100644 --- a/boost/smart_ptr/detail/sp_convertible.hpp +++ b/boost/smart_ptr/detail/sp_convertible.hpp @@ -16,6 +16,7 @@ // http://www.boost.org/LICENSE_1_0.txt #include <boost/config.hpp> +#include <cstddef> #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE ) # define BOOST_SP_NO_SP_CONVERTIBLE diff --git a/boost/smart_ptr/detail/sp_counted_base.hpp b/boost/smart_ptr/detail/sp_counted_base.hpp index c4158920e3..0addf077d1 100644 --- a/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/boost/smart_ptr/detail/sp_counted_base.hpp @@ -20,6 +20,12 @@ #include <boost/config.hpp> #include <boost/smart_ptr/detail/sp_has_sync.hpp> +#if defined( __clang__ ) && defined( __has_extension ) +# if __has_extension( __c_atomic__ ) +# define BOOST_SP_HAS_CLANG_C11_ATOMICS +# endif +#endif + #if defined( BOOST_SP_DISABLE_THREADS ) # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> @@ -35,6 +41,9 @@ #elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> +#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS ) +# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp> + #elif defined( __SNC__ ) # include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp> @@ -79,4 +88,6 @@ #endif +#undef BOOST_SP_HAS_CLANG_C11_ATOMICS + #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED diff --git a/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/boost/smart_ptr/detail/sp_counted_base_clang.hpp new file mode 100644 index 0000000000..c66b985465 --- /dev/null +++ b/boost/smart_ptr/detail/sp_counted_base_clang.hpp @@ -0,0 +1,140 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics +// +// Copyright (c) 2007, 2013, 2015 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 <boost/detail/sp_typeinfo.hpp> +#include <boost/cstdint.hpp> + +namespace boost +{ + +namespace detail +{ + +typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t; + +inline void atomic_increment( atomic_int_least32_t * pw ) +{ + __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); +} + +inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) +{ + return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); +} + +inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED ); + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + atomic_int_least32_t use_count_; // #shared + atomic_int_least32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base() + { + __c11_atomic_init( &use_count_, 1 ); + __c11_atomic_init( &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 __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED diff --git a/boost/smart_ptr/detail/sp_counted_impl.hpp b/boost/smart_ptr/detail/sp_counted_impl.hpp index a7b43aeaff..1222f3c9f4 100644 --- a/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -78,7 +78,7 @@ public: boost::checked_delete( px_ ); } - virtual void * get_deleter( detail::sp_typeinfo const & ) + virtual void * get_deleter( sp_typeinfo const & ) { return 0; } @@ -153,7 +153,7 @@ public: del( ptr ); } - virtual void * get_deleter( detail::sp_typeinfo const & ti ) + virtual void * get_deleter( sp_typeinfo const & ti ) { return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0; } @@ -249,7 +249,7 @@ public: a2.deallocate( this, 1 ); } - virtual void * get_deleter( detail::sp_typeinfo const & ti ) + virtual void * get_deleter( sp_typeinfo const & ti ) { return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0; } diff --git a/boost/smart_ptr/detail/spinlock_pool.hpp b/boost/smart_ptr/detail/spinlock_pool.hpp index f09d5c6401..39cf180b24 100644 --- a/boost/smart_ptr/detail/spinlock_pool.hpp +++ b/boost/smart_ptr/detail/spinlock_pool.hpp @@ -31,7 +31,7 @@ namespace boost namespace detail { -template< int I > class spinlock_pool +template< int M > class spinlock_pool { private: @@ -72,7 +72,7 @@ public: }; }; -template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] = +template< int M > spinlock spinlock_pool< M >::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, diff --git a/boost/smart_ptr/enable_shared_from_raw.hpp b/boost/smart_ptr/enable_shared_from_raw.hpp index 1911c07e8c..669a6492b6 100644 --- a/boost/smart_ptr/enable_shared_from_raw.hpp +++ b/boost/smart_ptr/enable_shared_from_raw.hpp @@ -53,7 +53,7 @@ protected: private: - void init_weak_once() const + void init_if_expired() const { if( weak_this_.expired() ) { @@ -62,6 +62,15 @@ private: } } + void init_if_empty() const + { + if( weak_this_._empty() ) + { + shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() ); + weak_this_ = shared_this_; + } + } + #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else @@ -74,7 +83,7 @@ private: shared_ptr<void const volatile> shared_from_this() const { - init_weak_once(); + init_if_expired(); return shared_ptr<void const volatile>( weak_this_ ); } @@ -83,6 +92,17 @@ private: return const_cast< enable_shared_from_raw const * >( this )->shared_from_this(); } + weak_ptr<void const volatile> weak_from_this() const + { + init_if_empty(); + return weak_this_; + } + + weak_ptr<void const volatile> weak_from_this() const volatile + { + return const_cast< enable_shared_from_raw const * >( this )->weak_from_this(); + } + // Note: invoked automatically by shared_ptr; do not call template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const { @@ -125,7 +145,7 @@ boost::weak_ptr<T> weak_from_raw(T *p) { BOOST_ASSERT(p != 0); boost::weak_ptr<T> result; - result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p); + result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p); return result; } diff --git a/boost/smart_ptr/enable_shared_from_this.hpp b/boost/smart_ptr/enable_shared_from_this.hpp index 3230f02579..4e3f243d28 100644 --- a/boost/smart_ptr/enable_shared_from_this.hpp +++ b/boost/smart_ptr/enable_shared_from_this.hpp @@ -58,6 +58,16 @@ public: return p; } + weak_ptr<T> weak_from_this() BOOST_NOEXCEPT + { + return weak_this_; + } + + weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT + { + return weak_this_; + } + public: // actually private, but avoids compiler template friendship issues // Note: invoked automatically by shared_ptr; do not call diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp index 82ece8bdb9..8be92abb5d 100644 --- a/boost/smart_ptr/shared_ptr.hpp +++ b/boost/smart_ptr/shared_ptr.hpp @@ -655,7 +655,7 @@ public: BOOST_ASSERT( px != 0 ); BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); - return px[ i ]; + return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] ); } element_type * get() const BOOST_NOEXCEPT |