File indexing completed on 2025-01-30 09:33:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
0016
0017 #include <cstddef>
0018 #include <boost/memory_order.hpp>
0019 #include <boost/atomic/detail/config.hpp>
0020 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
0021 #include <boost/atomic/detail/storage_traits.hpp>
0022 #include <boost/atomic/detail/extra_fp_operations_fwd.hpp>
0023 #include <boost/atomic/detail/type_traits/is_iec559.hpp>
0024 #include <boost/atomic/detail/type_traits/is_integral.hpp>
0025 #include <boost/atomic/detail/header.hpp>
0026
0027 #ifdef BOOST_HAS_PRAGMA_ONCE
0028 #pragma once
0029 #endif
0030
0031 #if defined(BOOST_GCC) && BOOST_GCC >= 60000
0032 #pragma GCC diagnostic push
0033
0034 #pragma GCC diagnostic ignored "-Wignored-attributes"
0035 #endif
0036
0037 namespace boost {
0038 namespace atomics {
0039 namespace detail {
0040
0041
0042 template<
0043 typename Base,
0044 typename Value,
0045 std::size_t Size
0046 #if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
0047 , bool = atomics::detail::is_iec559< Value >::value && atomics::detail::is_integral< typename Base::storage_type >::value
0048 #endif
0049 >
0050 struct extra_fp_negate_generic :
0051 public Base
0052 {
0053 typedef Base base_type;
0054 typedef typename base_type::storage_type storage_type;
0055 typedef Value value_type;
0056
0057 static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0058 {
0059 storage_type old_storage, new_storage;
0060 value_type old_val, new_val;
0061 atomics::detail::non_atomic_load(storage, old_storage);
0062 do
0063 {
0064 old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
0065 new_val = -old_val;
0066 new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
0067 }
0068 while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
0069 return old_val;
0070 }
0071
0072 static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0073 {
0074 storage_type old_storage, new_storage;
0075 value_type old_val, new_val;
0076 atomics::detail::non_atomic_load(storage, old_storage);
0077 do
0078 {
0079 old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
0080 new_val = -old_val;
0081 new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
0082 }
0083 while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
0084 return new_val;
0085 }
0086
0087 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0088 {
0089 fetch_negate(storage, order);
0090 }
0091 };
0092
0093 #if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
0094
0095
0096 template< typename Base, typename Value, std::size_t Size >
0097 struct extra_fp_negate_generic< Base, Value, Size, true > :
0098 public Base
0099 {
0100 typedef Base base_type;
0101 typedef typename base_type::storage_type storage_type;
0102 typedef Value value_type;
0103
0104
0105 static BOOST_CONSTEXPR_OR_CONST storage_type sign_mask = static_cast< storage_type >(1u) << (atomics::detail::value_size_of< value_type >::value * 8u - 1u);
0106
0107 static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0108 {
0109 return atomics::detail::bitwise_fp_cast< value_type >(base_type::fetch_xor(storage, sign_mask, order));
0110 }
0111
0112 static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0113 {
0114 return atomics::detail::bitwise_fp_cast< value_type >(base_type::bitwise_xor(storage, sign_mask, order));
0115 }
0116
0117 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0118 {
0119 base_type::opaque_xor(storage, sign_mask, order);
0120 }
0121 };
0122
0123 #endif
0124
0125
0126 template< typename Base, typename Value, std::size_t Size >
0127 struct extra_fp_operations_generic :
0128 public extra_fp_negate_generic< Base, Value, Size >
0129 {
0130 typedef extra_fp_negate_generic< Base, Value, Size > base_type;
0131 typedef typename base_type::storage_type storage_type;
0132 typedef Value value_type;
0133
0134 static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
0135 {
0136 storage_type old_storage, new_storage;
0137 value_type old_val, new_val;
0138 atomics::detail::non_atomic_load(storage, old_storage);
0139 do
0140 {
0141 old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
0142 new_val = old_val + v;
0143 new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
0144 }
0145 while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
0146 return new_val;
0147 }
0148
0149 static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
0150 {
0151 storage_type old_storage, new_storage;
0152 value_type old_val, new_val;
0153 atomics::detail::non_atomic_load(storage, old_storage);
0154 do
0155 {
0156 old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
0157 new_val = old_val - v;
0158 new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
0159 }
0160 while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
0161 return new_val;
0162 }
0163
0164 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
0165 {
0166 base_type::fetch_add(storage, v, order);
0167 }
0168
0169 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
0170 {
0171 base_type::fetch_sub(storage, v, order);
0172 }
0173 };
0174
0175
0176 template< typename Base, typename Value, std::size_t Size >
0177 struct extra_fp_operations< Base, Value, Size, true > :
0178 public extra_fp_operations_generic< Base, Value, Size >
0179 {
0180 };
0181
0182 }
0183 }
0184 }
0185
0186 #if defined(BOOST_GCC) && BOOST_GCC >= 60000
0187 #pragma GCC diagnostic pop
0188 #endif
0189
0190 #include <boost/atomic/detail/footer.hpp>
0191
0192 #endif