239 lines
5.7 KiB
C++
239 lines
5.7 KiB
C++
#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/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
|