123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
- #define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
- //
- // atomic_shared_ptr.hpp
- //
- // Copyright 2017 Peter Dimov
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/libs/smart_ptr/ for documentation.
- //
- #include <boost/smart_ptr/detail/requires_cxx11.hpp>
- #include <boost/smart_ptr/shared_ptr.hpp>
- #include <boost/smart_ptr/detail/spinlock.hpp>
- #include <cstring>
- namespace boost
- {
- template<class T> class atomic_shared_ptr
- {
- private:
- boost::shared_ptr<T> p_;
- mutable boost::detail::spinlock l_;
- atomic_shared_ptr(const atomic_shared_ptr&);
- atomic_shared_ptr& operator=(const atomic_shared_ptr&);
- private:
- bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
- {
- l_.lock();
- if( p_._internal_equiv( v ) )
- {
- p_.swap( w );
- l_.unlock();
- return true;
- }
- else
- {
- shared_ptr<T> tmp( p_ );
- l_.unlock();
- tmp.swap( v );
- return false;
- }
- }
- public:
- #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
- constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
- {
- }
- atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
- : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT
- {
- }
- #else
- atomic_shared_ptr() BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
- std::memcpy( &l_, &init, sizeof( init ) );
- }
- atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
- #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- : p_( std::move( p ) )
- #else
- : p_( p )
- #endif
- {
- boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
- std::memcpy( &l_, &init, sizeof( init ) );
- }
- #endif
- atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- p_.swap( r );
- return *this;
- }
- BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
- {
- return false;
- }
- shared_ptr<T> load() const BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- return p_;
- }
- template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- return p_;
- }
- operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- return p_;
- }
- void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- p_.swap( r );
- }
- template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- p_.swap( r );
- }
- shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
- {
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- p_.swap( r );
- }
- #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- return std::move( r );
- #else
- return r;
- #endif
- }
- template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
- {
- {
- boost::detail::spinlock::scoped_lock lock( l_ );
- p_.swap( r );
- }
- #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- return std::move( r );
- #else
- return r;
- #endif
- }
- template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, w );
- }
- #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
- {
- return compare_exchange( v, std::move( w ) );
- }
- #endif
- };
- } // namespace boost
- #endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
|