diff --git a/include/boost/atomic/detail/atomic_template.hpp b/include/boost/atomic/detail/atomic_template.hpp index a7ba338..bdff9c2 100644 --- a/include/boost/atomic/detail/atomic_template.hpp +++ b/include/boost/atomic/detail/atomic_template.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) #include #include @@ -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" 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; diff --git a/include/boost/atomic/detail/config.hpp b/include/boost/atomic/detail/config.hpp index f46a049..d2a6afd 100644 --- a/include/boost/atomic/detail/config.hpp +++ b/include/boost/atomic/detail/config.hpp @@ -49,8 +49,8 @@ #if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) #if !(defined(BOOST_LIBSTDCXX11) && (BOOST_LIBSTDCXX_VERSION+0) >= 40700) /* libstdc++ from gcc >= 4.7 in C++11 mode */ -// This macro indicates that there is no standard header that is sufficient for Boost.Atomic needs. -#define BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS +// This macro indicates that there is not even a basic standard header that is sufficient for most Boost.Atomic needs. +#define BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS #endif #endif // defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) diff --git a/include/boost/atomic/detail/type_traits/conditional.hpp b/include/boost/atomic/detail/type_traits/conditional.hpp index 71397ab..6b9e896 100644 --- a/include/boost/atomic/detail/type_traits/conditional.hpp +++ b/include/boost/atomic/detail/type_traits/conditional.hpp @@ -15,7 +15,7 @@ #define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_ #include -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) #include #else #include @@ -29,7 +29,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) using std::conditional; #else using boost::conditional; diff --git a/include/boost/atomic/detail/type_traits/integral_constant.hpp b/include/boost/atomic/detail/type_traits/integral_constant.hpp index 8fbc0d5..eac8649 100644 --- a/include/boost/atomic/detail/type_traits/integral_constant.hpp +++ b/include/boost/atomic/detail/type_traits/integral_constant.hpp @@ -15,7 +15,7 @@ #define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_ #include -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) #include #else #include @@ -29,7 +29,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) using std::integral_constant; using std::true_type; using std::false_type; diff --git a/include/boost/atomic/detail/type_traits/is_floating_point.hpp b/include/boost/atomic/detail/type_traits/is_floating_point.hpp index cdcf269..c425112 100644 --- a/include/boost/atomic/detail/type_traits/is_floating_point.hpp +++ b/include/boost/atomic/detail/type_traits/is_floating_point.hpp @@ -15,7 +15,7 @@ #define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_ #include -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) #include #else #include @@ -29,7 +29,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) using std::is_floating_point; #else using boost::is_floating_point; diff --git a/include/boost/atomic/detail/type_traits/is_function.hpp b/include/boost/atomic/detail/type_traits/is_function.hpp index 7b82840..e720535 100644 --- a/include/boost/atomic/detail/type_traits/is_function.hpp +++ b/include/boost/atomic/detail/type_traits/is_function.hpp @@ -15,7 +15,7 @@ #define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_ #include -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) #include #else #include @@ -29,7 +29,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) using std::is_function; #else using boost::is_function; diff --git a/include/boost/atomic/detail/type_traits/is_integral.hpp b/include/boost/atomic/detail/type_traits/is_integral.hpp index 5deb120..ef3e2e3 100644 --- a/include/boost/atomic/detail/type_traits/is_integral.hpp +++ b/include/boost/atomic/detail/type_traits/is_integral.hpp @@ -16,7 +16,7 @@ #include // Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) #include #else #include @@ -30,7 +30,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) using std::is_integral; #else using boost::is_integral; diff --git a/include/boost/atomic/detail/type_traits/is_signed.hpp b/include/boost/atomic/detail/type_traits/is_signed.hpp index bf95163..2dc1df7 100644 --- a/include/boost/atomic/detail/type_traits/is_signed.hpp +++ b/include/boost/atomic/detail/type_traits/is_signed.hpp @@ -16,7 +16,7 @@ #include // Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) #include #else #include @@ -30,7 +30,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) using std::is_signed; #else using boost::is_signed; diff --git a/include/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp b/include/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp new file mode 100644 index 0000000..5f88b88 --- /dev/null +++ b/include/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp @@ -0,0 +1,46 @@ +/* + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_trivially_default_constructible.hpp + * + * This header defines \c is_trivially_default_constructible type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ + +#include +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +using std::is_trivially_default_constructible; +#elif !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template< typename T > +using is_trivially_default_constructible = boost::has_trivial_constructor< T >; +#else +template< typename T > +struct is_trivially_default_constructible : public boost::has_trivial_constructor< T > {}; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ diff --git a/include/boost/atomic/detail/type_traits/make_signed.hpp b/include/boost/atomic/detail/type_traits/make_signed.hpp index 831efdc..82f61b3 100644 --- a/include/boost/atomic/detail/type_traits/make_signed.hpp +++ b/include/boost/atomic/detail/type_traits/make_signed.hpp @@ -16,7 +16,7 @@ #include // Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) #include #else #include @@ -30,7 +30,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) using std::make_signed; #else using boost::make_signed; diff --git a/include/boost/atomic/detail/type_traits/make_unsigned.hpp b/include/boost/atomic/detail/type_traits/make_unsigned.hpp index c4eb020..573a161 100644 --- a/include/boost/atomic/detail/type_traits/make_unsigned.hpp +++ b/include/boost/atomic/detail/type_traits/make_unsigned.hpp @@ -16,7 +16,7 @@ #include // Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) #include #else #include @@ -30,7 +30,7 @@ namespace boost { namespace atomics { namespace detail { -#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) using std::make_unsigned; #else using boost::make_unsigned;