#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 #include #include #include namespace boost { template class atomic_shared_ptr { private: boost::shared_ptr 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& v, shared_ptr w ) BOOST_SP_NOEXCEPT { l_.lock(); if( p_._internal_equiv( v ) ) { p_.swap( w ); l_.unlock(); return true; } else { shared_ptr 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 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 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 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 load() const BOOST_SP_NOEXCEPT { boost::detail::spinlock::scoped_lock lock( l_ ); return p_; } template shared_ptr load( M ) const BOOST_SP_NOEXCEPT { boost::detail::spinlock::scoped_lock lock( l_ ); return p_; } operator shared_ptr() const BOOST_SP_NOEXCEPT { boost::detail::spinlock::scoped_lock lock( l_ ); return p_; } void store( shared_ptr r ) BOOST_SP_NOEXCEPT { boost::detail::spinlock::scoped_lock lock( l_ ); p_.swap( r ); } template void store( shared_ptr r, M ) BOOST_SP_NOEXCEPT { boost::detail::spinlock::scoped_lock lock( l_ ); p_.swap( r ); } shared_ptr exchange( shared_ptr 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 shared_ptr exchange( shared_ptr 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 bool compare_exchange_weak( shared_ptr& v, const shared_ptr& w, M, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } template bool compare_exchange_weak( shared_ptr& v, const shared_ptr& w, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } bool compare_exchange_weak( shared_ptr& v, const shared_ptr& w ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } template bool compare_exchange_strong( shared_ptr& v, const shared_ptr& w, M, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } template bool compare_exchange_strong( shared_ptr& v, const shared_ptr& w, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } bool compare_exchange_strong( shared_ptr& v, const shared_ptr& w ) BOOST_SP_NOEXCEPT { return compare_exchange( v, w ); } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template bool compare_exchange_weak( shared_ptr& v, shared_ptr&& w, M, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } template bool compare_exchange_weak( shared_ptr& v, shared_ptr&& w, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } bool compare_exchange_weak( shared_ptr& v, shared_ptr&& w ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } template bool compare_exchange_strong( shared_ptr& v, shared_ptr&& w, M, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } template bool compare_exchange_strong( shared_ptr& v, shared_ptr&& w, M ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } bool compare_exchange_strong( shared_ptr& v, shared_ptr&& w ) BOOST_SP_NOEXCEPT { return compare_exchange( v, std::move( w ) ); } #endif }; } // namespace boost #endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED