# HG changeset patch # User iloehken # Date 1407854747 -7200 # Tue Aug 12 16:45:47 2014 +0200 # Branch 1.56 # Node ID 1a6edcfda31d5c14b218d8ee9d5eadc7cb016148 # Parent 43ef1037b73e427d5193ef04c83e7b358c2d266f [boost] atomic : added facet to handle enums atomic as ints diff -r 43ef1037b73e -r 1a6edcfda31d boost/atomic/detail/atomic_template.hpp --- a/boost/atomic/detail/atomic_template.hpp Mon Aug 11 23:25:15 2014 +0200 +++ b/boost/atomic/detail/atomic_template.hpp Tue Aug 12 16:45:47 2014 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -56,24 +57,143 @@ return (failure_order & 15u) <= (success_order & 15u); } -template< typename T, bool IsInt = boost::is_integral< T >::value > -struct classify +struct integral_type; +struct enum_type; +struct user_defined_type; +struct pointer_type; + +template ::value> +struct classify_integral_or_other { - typedef void type; + typedef user_defined_type type; }; template< typename T > -struct classify< T, true > { typedef int type; }; +struct classify_integral_or_other +{ + typedef integral_type type; +}; template< typename T > -struct classify< T*, false > { typedef void* type; }; +struct classify_integral_or_other +{ + typedef pointer_type type; +}; -template< typename T, typename Kind > +template ::value> +struct classify_enum_or_other +{ + typedef enum_type type; +}; + +template +struct classify_enum_or_other + : public classify_integral_or_other +{}; + +template +struct classify + : public classify_enum_or_other +{}; + + +template class base_atomic; + + +//! Implementation for enums ---> store as int +template +class base_atomic +{ +private: + typedef T value_type; + typedef T difference_type; + typedef atomics::detail::operations< storage_size_of::value, boost::is_signed::value > operations; + +protected: + typedef value_type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +protected: + storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {} + + BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(m_storage, static_cast< storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return static_cast< value_type >(operations::load(m_storage, order)); + } + + BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return static_cast< value_type >(operations::exchange(m_storage, 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_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + storage_type old_value = static_cast< storage_type >(expected); + const bool res = operations::compare_exchange_strong(m_storage, old_value, static_cast< storage_type >(desired), success_order, failure_order); + expected = static_cast< value_type >(old_value); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_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_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + storage_type old_value = static_cast< storage_type >(expected); + const bool res = operations::compare_exchange_weak(m_storage, old_value, static_cast< storage_type >(desired), success_order, failure_order); + expected = static_cast< value_type >(old_value); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_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 bool is_lock_free() const volatile BOOST_NOEXCEPT + { + return operations::is_lock_free(m_storage); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) +}; + + + //! Implementation for integers -template< typename T > -class base_atomic< T, int > +template +class base_atomic { private: typedef T value_type; @@ -228,9 +348,11 @@ BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; + + //! Implementation for bool template< > -class base_atomic< bool, int > +class base_atomic { private: typedef bool value_type; @@ -315,9 +437,10 @@ }; -//! Implementation for user-defined types, such as structs and enums -template< typename T > -class base_atomic< T, void > + +//! Implementation for user-defined types, such as structs +template +class base_atomic { private: typedef T value_type; @@ -403,9 +526,10 @@ }; + //! Implementation for pointers -template< typename T > -class base_atomic< T*, void* > +template +class base_atomic { private: typedef T* value_type; @@ -533,9 +657,10 @@ }; + //! Implementation for void pointers -template< > -class base_atomic< void*, void* > +template <> +class base_atomic { private: typedef void* value_type; @@ -664,9 +789,11 @@ } // namespace detail -template< typename T > + + +template class atomic : - public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > + public atomics::detail::base_atomic::type> { private: typedef T value_type;