|
|
|
|
@@ -38,6 +38,9 @@
|
|
|
|
|
#include <boost/atomic/detail/extra_fp_operations.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
#include <boost/type_traits/alignment_of.hpp>
|
|
|
|
|
#if defined(BOOST_NO_CXX11_ALIGNAS)
|
|
|
|
|
#include <boost/type_traits/type_with_alignment.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
|
|
|
|
#pragma once
|
|
|
|
|
@@ -58,50 +61,88 @@ namespace boost {
|
|
|
|
|
namespace atomics {
|
|
|
|
|
namespace detail {
|
|
|
|
|
|
|
|
|
|
template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
|
|
|
|
|
class base_atomic_generic;
|
|
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic_generic< T, true >
|
|
|
|
|
template< typename T, bool IsSigned >
|
|
|
|
|
class base_atomic_common
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef T value_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations;
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, IsSigned > operations;
|
|
|
|
|
typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = boost::alignment_of< value_type >::value <= operations::storage_alignment ? operations::storage_alignment : boost::alignment_of< value_type >::value;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
#if !defined(BOOST_NO_CXX11_ALIGNAS)
|
|
|
|
|
alignas(storage_alignment) storage_type m_storage;
|
|
|
|
|
#else
|
|
|
|
|
// Note: Some compilers cannot use constant expressions in alignment attributes, so we have to use the union trick
|
|
|
|
|
union
|
|
|
|
|
{
|
|
|
|
|
storage_type m_storage;
|
|
|
|
|
typename boost::type_with_alignment< storage_alignment >::type m_aligner;
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic_common() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic_common(storage_type v) BOOST_NOEXCEPT : m_storage(v)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type& value() BOOST_NOEXCEPT { return *reinterpret_cast< value_type* >(&m_storage); }
|
|
|
|
|
BOOST_FORCEINLINE value_type volatile& value() volatile BOOST_NOEXCEPT { return *reinterpret_cast< volatile value_type* >(&m_storage); }
|
|
|
|
|
BOOST_FORCEINLINE value_type const& value() const BOOST_NOEXCEPT { return *reinterpret_cast< const value_type* >(&m_storage); }
|
|
|
|
|
BOOST_FORCEINLINE value_type const volatile& value() const volatile BOOST_NOEXCEPT { return *reinterpret_cast< const volatile value_type* >(&m_storage); }
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return m_storage; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return m_storage; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return m_storage; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return m_storage; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
|
|
|
|
|
class base_atomic_generic;
|
|
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic_generic< T, true > :
|
|
|
|
|
public base_atomic_common< T, false >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< T, false > base_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef typename base_type::value_arg_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v))
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic_generic< T, false >
|
|
|
|
|
class base_atomic_generic< T, false > :
|
|
|
|
|
public base_atomic_common< T, false >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< T, false > base_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef T value_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations;
|
|
|
|
|
typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef typename base_type::value_arg_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v))
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@@ -120,10 +161,10 @@ private:
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef typename base_type::operations operations;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef typename base_type::value_arg_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
@@ -141,7 +182,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(this->m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order);
|
|
|
|
|
operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -149,12 +190,12 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::load(this->m_storage.value, order));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::load(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -192,7 +233,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_strong(this->m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -201,7 +242,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -209,7 +250,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_weak(this->m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -218,7 +259,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -227,29 +268,28 @@ private:
|
|
|
|
|
|
|
|
|
|
//! Implementation for integers
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic< T, int >
|
|
|
|
|
class base_atomic< T, int > :
|
|
|
|
|
public base_atomic_common< T, atomics::detail::is_signed< T >::value >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< T, atomics::detail::is_signed< T >::value > base_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef T value_type;
|
|
|
|
|
typedef T difference_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef value_type difference_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, atomics::detail::is_signed< T >::value > operations;
|
|
|
|
|
typedef typename base_type::operations operations;
|
|
|
|
|
typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef value_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || boost::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
|
|
|
|
|
|
|
|
|
|
// Standard methods
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -258,7 +298,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
operations::store(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -266,22 +306,22 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::load(m_storage.value, order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::load(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_add(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::exchange(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::exchange(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -314,156 +354,156 @@ public:
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_and(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_or(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Boost.Atomic extensions
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(m_storage.value, order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(m_storage.value, order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::negate(m_storage.value, order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(m_storage.value, order));
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
extra_operations::opaque_add(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
extra_operations::opaque_sub(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_negate(m_storage.value, order);
|
|
|
|
|
extra_operations::opaque_negate(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
extra_operations::opaque_and(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
extra_operations::opaque_or(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
extra_operations::opaque_xor(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_complement(m_storage.value, order);
|
|
|
|
|
extra_operations::opaque_complement(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::add_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
return extra_operations::add_and_test(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::sub_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
return extra_operations::sub_and_test(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::negate_and_test(m_storage.value, order);
|
|
|
|
|
return extra_operations::negate_and_test(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::and_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
return extra_operations::and_and_test(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::or_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
return extra_operations::or_and_test(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::xor_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
return extra_operations::xor_and_test(this->storage(), atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::complement_and_test(m_storage.value, order);
|
|
|
|
|
return extra_operations::complement_and_test(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
|
|
|
|
|
return extra_operations::bit_test_and_set(m_storage.value, bit_number, order);
|
|
|
|
|
return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
|
|
|
|
|
return extra_operations::bit_test_and_reset(m_storage.value, bit_number, order);
|
|
|
|
|
return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
|
|
|
|
|
return extra_operations::bit_test_and_complement(m_storage.value, bit_number, order);
|
|
|
|
|
return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
|
@@ -519,7 +559,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -528,7 +568,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::integral_extend< operations::is_signed, storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::integral_truncate< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -536,7 +576,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -545,7 +585,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::integral_extend< operations::is_signed, storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::integral_truncate< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -553,27 +593,26 @@ private:
|
|
|
|
|
|
|
|
|
|
//! Implementation for bool
|
|
|
|
|
template< >
|
|
|
|
|
class base_atomic< bool, int >
|
|
|
|
|
class base_atomic< bool, int > :
|
|
|
|
|
public base_atomic_common< bool, false >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< bool, false > base_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef bool value_type;
|
|
|
|
|
typedef base_type::value_type value_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< 1u, false > operations;
|
|
|
|
|
typedef base_type::operations operations;
|
|
|
|
|
typedef base_type::storage_type storage_type;
|
|
|
|
|
typedef value_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || boost::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
|
|
|
|
|
|
|
|
|
|
// Standard methods
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -582,7 +621,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(m_storage.value, static_cast< storage_type >(v), order);
|
|
|
|
|
operations::store(this->storage(), static_cast< storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -590,12 +629,12 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return !!operations::load(m_storage.value, order);
|
|
|
|
|
return !!operations::load(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return !!operations::exchange(m_storage.value, static_cast< storage_type >(v), order);
|
|
|
|
|
return !!operations::exchange(this->storage(), static_cast< storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -633,7 +672,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -642,7 +681,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = static_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = !!old_value;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -650,7 +689,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -659,7 +698,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = static_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = !!old_value;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -670,33 +709,32 @@ private:
|
|
|
|
|
|
|
|
|
|
//! Implementation for floating point types
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic< T, float >
|
|
|
|
|
class base_atomic< T, float > :
|
|
|
|
|
public base_atomic_common< T, false >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< T, false > base_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef T value_type;
|
|
|
|
|
typedef T difference_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef value_type difference_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations;
|
|
|
|
|
typedef typename base_type::operations operations;
|
|
|
|
|
typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
|
|
|
|
|
typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations;
|
|
|
|
|
typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef value_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool,
|
|
|
|
|
atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) || boost::alignment_of< value_type >::value <= operations::storage_alignment
|
|
|
|
|
> use_bitwise_cast;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
@@ -704,7 +742,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(m_storage.value, atomics::detail::bitwise_fp_cast< storage_type >(v), order);
|
|
|
|
|
operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -712,22 +750,22 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return atomics::detail::bitwise_fp_cast< value_type >(operations::load(m_storage.value, order));
|
|
|
|
|
return atomics::detail::bitwise_fp_cast< value_type >(operations::load(this->storage(), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return fp_operations::fetch_add(m_storage.value, v, order);
|
|
|
|
|
return fp_operations::fetch_add(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return fp_operations::fetch_sub(m_storage.value, v, order);
|
|
|
|
|
return fp_operations::fetch_sub(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_fp_cast< storage_type >(v), order));
|
|
|
|
|
return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -761,37 +799,37 @@ public:
|
|
|
|
|
// Boost.Atomic extensions
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_fp_operations::fetch_negate(m_storage.value, order);
|
|
|
|
|
return extra_fp_operations::fetch_negate(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_fp_operations::add(m_storage.value, v, order);
|
|
|
|
|
return extra_fp_operations::add(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_fp_operations::sub(m_storage.value, v, order);
|
|
|
|
|
return extra_fp_operations::sub(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_fp_operations::negate(m_storage.value, order);
|
|
|
|
|
return extra_fp_operations::negate(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_fp_operations::opaque_add(m_storage.value, v, order);
|
|
|
|
|
extra_fp_operations::opaque_add(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_fp_operations::opaque_sub(m_storage.value, v, order);
|
|
|
|
|
extra_fp_operations::opaque_sub(this->storage(), v, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_fp_operations::opaque_negate(m_storage.value, order);
|
|
|
|
|
extra_fp_operations::opaque_negate(this->storage(), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
|
@@ -812,7 +850,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -821,7 +859,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -829,7 +867,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -838,7 +876,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -849,20 +887,22 @@ private:
|
|
|
|
|
|
|
|
|
|
//! Implementation for pointers to object types
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic< T*, void* >
|
|
|
|
|
class base_atomic< T*, void* > :
|
|
|
|
|
public base_atomic_common< T*, false >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_common< T*, false > base_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef T* value_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef std::ptrdiff_t difference_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations;
|
|
|
|
|
typedef typename base_type::operations operations;
|
|
|
|
|
typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
typedef value_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || boost::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
|
|
|
|
|
|
|
|
|
|
@@ -874,12 +914,9 @@ private:
|
|
|
|
|
typedef typename atomics::detail::make_storage_type< sizeof(value_type) >::type uintptr_storage_type;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -890,7 +927,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(m_storage.value, atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
|
|
|
|
|
operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -898,22 +935,22 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(m_storage.value, order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(this->storage(), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -947,34 +984,34 @@ public:
|
|
|
|
|
// Boost.Atomic extensions
|
|
|
|
|
BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
extra_operations::opaque_sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::add_and_test(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return extra_operations::sub_and_test(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
|
@@ -1015,7 +1052,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -1024,7 +1061,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -1032,7 +1069,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
|
|
|
|
|
return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -1041,7 +1078,7 @@ private:
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -1059,6 +1096,8 @@ private:
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
// Deprecated, use value_type instead
|
|
|
|
|
BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
|
|
|
|
|
typedef typename base_type::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
@@ -1091,10 +1130,15 @@ public:
|
|
|
|
|
return is_always_lock_free;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return this->m_storage.value; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return this->m_storage.value; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return this->m_storage.value; }
|
|
|
|
|
BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return this->m_storage.value; }
|
|
|
|
|
// Deprecated, use value() instead
|
|
|
|
|
BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
|
|
|
|
|
BOOST_FORCEINLINE typename base_type::storage_type& storage() BOOST_NOEXCEPT { return base_type::storage(); }
|
|
|
|
|
BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
|
|
|
|
|
BOOST_FORCEINLINE typename base_type::storage_type volatile& storage() volatile BOOST_NOEXCEPT { return base_type::storage(); }
|
|
|
|
|
BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
|
|
|
|
|
BOOST_FORCEINLINE typename base_type::storage_type const& storage() const BOOST_NOEXCEPT { return base_type::storage(); }
|
|
|
|
|
BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
|
|
|
|
|
BOOST_FORCEINLINE typename base_type::storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return base_type::storage(); }
|
|
|
|
|
|
|
|
|
|
BOOST_DELETED_FUNCTION(atomic(atomic const&))
|
|
|
|
|
BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&))
|
|
|
|
|
@@ -1130,6 +1174,9 @@ typedef atomic< boost::long_long_type > atomic_llong;
|
|
|
|
|
typedef atomic< void* > atomic_address;
|
|
|
|
|
typedef atomic< bool > atomic_bool;
|
|
|
|
|
typedef atomic< wchar_t > atomic_wchar_t;
|
|
|
|
|
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
|
|
|
|
|
typedef atomic< char8_t > atomic_char8_t;
|
|
|
|
|
#endif
|
|
|
|
|
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
|
|
|
|
typedef atomic< char16_t > atomic_char16_t;
|
|
|
|
|
#endif
|
|
|
|
|
|