|
|
|
|
@@ -31,6 +31,7 @@
|
|
|
|
|
#include <boost/atomic/detail/type_traits/is_floating_point.hpp>
|
|
|
|
|
#include <boost/atomic/detail/type_traits/conditional.hpp>
|
|
|
|
|
#include <boost/atomic/detail/type_traits/integral_constant.hpp>
|
|
|
|
|
#include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
|
|
|
|
|
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
|
|
|
|
#include <boost/atomic/detail/bitwise_fp_cast.hpp>
|
|
|
|
|
#include <boost/atomic/detail/fp_operations_fwd.hpp>
|
|
|
|
|
@@ -113,12 +114,21 @@ template< typename T, typename U >
|
|
|
|
|
struct classify< T U::*, false, false > { typedef void type; };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T, typename Kind >
|
|
|
|
|
class base_atomic;
|
|
|
|
|
#if defined(BOOST_INTEL)
|
|
|
|
|
// Intel compiler (at least 18.0 update 1) breaks if noexcept specification is used in defaulted function declarations:
|
|
|
|
|
// error: the default constructor of "boost::atomics::atomic<T>" cannot be referenced -- it is a deleted function
|
|
|
|
|
#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL
|
|
|
|
|
#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL BOOST_NOEXCEPT
|
|
|
|
|
#else
|
|
|
|
|
#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL BOOST_NOEXCEPT
|
|
|
|
|
#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
|
|
|
|
|
class base_atomic_generic;
|
|
|
|
|
|
|
|
|
|
//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic< T, void >
|
|
|
|
|
class base_atomic_generic< T, true >
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef T value_type;
|
|
|
|
|
@@ -130,14 +140,64 @@ protected:
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_storage;
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic_generic< T, false >
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef T 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;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef typename operations::storage_type storage_type;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(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 : m_storage(atomics::detail::bitwise_cast< storage_type >(v))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T, typename Kind >
|
|
|
|
|
class base_atomic;
|
|
|
|
|
|
|
|
|
|
//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
|
|
|
|
|
template< typename T >
|
|
|
|
|
class base_atomic< T, void > :
|
|
|
|
|
public base_atomic_generic< T >
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef base_atomic_generic< T > base_type;
|
|
|
|
|
|
|
|
|
|
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::value_arg_type value_arg_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_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 : base_type(v)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -147,7 +207,7 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
operations::store(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order);
|
|
|
|
|
operations::store(this->m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
|
|
|
|
@@ -155,12 +215,12 @@ public:
|
|
|
|
|
BOOST_ASSERT(order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acq_rel);
|
|
|
|
|
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::load(m_storage.value, order));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::load(this->m_storage.value, 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(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order));
|
|
|
|
|
return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->m_storage.value, 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
|
|
|
|
|
@@ -198,7 +258,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
|
|
|
|
|
{
|
|
|
|
|
#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< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
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);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -207,7 +267,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
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_strong(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -215,7 +275,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
|
|
|
|
|
{
|
|
|
|
|
#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< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
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);
|
|
|
|
|
#else
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type());
|
|
|
|
|
#endif
|
|
|
|
|
@@ -224,7 +284,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
|
|
|
|
|
{
|
|
|
|
|
storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
const bool res = operations::compare_exchange_weak(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
|
|
|
|
|
expected = atomics::detail::bitwise_cast< value_type >(old_value);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
@@ -254,11 +314,11 @@ protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_NOEXCEPT, {})
|
|
|
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
|
|
|
|
|
// Standard methods
|
|
|
|
|
BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(order != memory_order_consume);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
@@ -285,12 +345,12 @@ public:
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -299,12 +359,12 @@ public:
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -313,22 +373,22 @@ public:
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
@@ -359,17 +419,17 @@ public:
|
|
|
|
|
return atomics::detail::integral_truncate< value_type >(extra_operations::negate(m_storage.value, order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type bitwise_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
@@ -394,17 +454,17 @@ public:
|
|
|
|
|
extra_operations::opaque_negate(m_storage.value, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE void opaque_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
@@ -432,19 +492,19 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool and_and_test(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool or_and_test(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
|
|
|
|
|
BOOST_FORCEINLINE bool xor_and_test(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
@@ -578,11 +638,11 @@ protected:
|
|
|
|
|
operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_NOEXCEPT, {})
|
|
|
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {}
|
|
|
|
|
|
|
|
|
|
// Standard methods
|
|
|
|
|
BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(order != memory_order_consume);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
@@ -599,12 +659,12 @@ public:
|
|
|
|
|
return !!operations::load(m_storage.value, order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -613,12 +673,12 @@ public:
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -627,7 +687,7 @@ public:
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
@@ -699,8 +759,8 @@ protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_NOEXCEPT, {})
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
|
|
|
|
|
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 void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
@@ -882,13 +942,13 @@ protected:
|
|
|
|
|
typename operations::aligned_storage_type m_storage;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_NOEXCEPT, {})
|
|
|
|
|
BOOST_FORCEINLINE explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Standard methods
|
|
|
|
|
BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(order != memory_order_consume);
|
|
|
|
|
BOOST_ASSERT(order != memory_order_acquire);
|
|
|
|
|
@@ -920,7 +980,7 @@ public:
|
|
|
|
|
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)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -929,12 +989,12 @@ public:
|
|
|
|
|
return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_release);
|
|
|
|
|
BOOST_ASSERT(failure_order != memory_order_acq_rel);
|
|
|
|
|
@@ -943,7 +1003,7 @@ public:
|
|
|
|
|
return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
|
|
|
|
|
}
|
|
|
|
|
@@ -1069,7 +1129,7 @@ public:
|
|
|
|
|
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = base_type::operations::is_always_lock_free;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(atomic() BOOST_NOEXCEPT, {})
|
|
|
|
|
BOOST_DEFAULTED_FUNCTION(atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
|
|
|
|
|
|
|
|
|
// NOTE: The constructor is made explicit because gcc 4.7 complains that
|
|
|
|
|
// operator=(value_arg_type) is considered ambiguous with operator=(atomic const&)
|
|
|
|
|
@@ -1107,6 +1167,9 @@ public:
|
|
|
|
|
template< typename T >
|
|
|
|
|
BOOST_CONSTEXPR_OR_CONST bool atomic< T >::is_always_lock_free;
|
|
|
|
|
|
|
|
|
|
#undef BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL
|
|
|
|
|
#undef BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL
|
|
|
|
|
|
|
|
|
|
typedef atomic< char > atomic_char;
|
|
|
|
|
typedef atomic< unsigned char > atomic_uchar;
|
|
|
|
|
typedef atomic< signed char > atomic_schar;
|
|
|
|
|
|