File indexing completed on 2024-11-16 09:05:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_REF_IMPL_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_ATOMIC_REF_IMPL_HPP_INCLUDED_
0016
0017 #include <cstddef>
0018 #include <boost/assert.hpp>
0019 #include <boost/memory_order.hpp>
0020 #include <boost/atomic/detail/config.hpp>
0021 #include <boost/atomic/detail/addressof.hpp>
0022 #include <boost/atomic/detail/storage_traits.hpp>
0023 #include <boost/atomic/detail/bitwise_cast.hpp>
0024 #include <boost/atomic/detail/core_operations.hpp>
0025 #include <boost/atomic/detail/wait_operations.hpp>
0026 #include <boost/atomic/detail/extra_operations.hpp>
0027 #include <boost/atomic/detail/core_operations_emulated.hpp>
0028 #include <boost/atomic/detail/memory_order_utils.hpp>
0029 #include <boost/atomic/detail/type_traits/is_signed.hpp>
0030 #include <boost/atomic/detail/type_traits/remove_cv.hpp>
0031 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
0032 #include <boost/atomic/detail/type_traits/conditional.hpp>
0033 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
0034 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
0035 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
0036 #include <boost/atomic/detail/fp_operations.hpp>
0037 #include <boost/atomic/detail/extra_fp_operations.hpp>
0038 #endif
0039 #include <boost/atomic/detail/header.hpp>
0040
0041 #ifdef BOOST_HAS_PRAGMA_ONCE
0042 #pragma once
0043 #endif
0044
0045
0046
0047
0048
0049
0050 namespace boost {
0051 namespace atomics {
0052 namespace detail {
0053
0054 template< typename T, bool Signed, bool Interprocess >
0055 struct is_atomic_ref_lock_free
0056 {
0057 typedef T value_type;
0058 typedef atomics::detail::core_operations< sizeof(value_type), Signed, Interprocess > core_operations;
0059 typedef typename core_operations::storage_type storage_type;
0060
0061 static BOOST_CONSTEXPR_OR_CONST bool value = sizeof(value_type) == sizeof(storage_type) && core_operations::is_always_lock_free;
0062 };
0063
0064 template< typename T, bool Signed, bool Interprocess >
0065 class base_atomic_ref_common
0066 {
0067 public:
0068 typedef T value_type;
0069
0070 protected:
0071 typedef typename atomics::detail::remove_cv< value_type >::type unqualified_value_type;
0072 typedef typename atomics::detail::conditional<
0073 atomics::detail::is_atomic_ref_lock_free< T, Signed, Interprocess >::value,
0074 atomics::detail::core_operations< sizeof(value_type), Signed, Interprocess >,
0075 atomics::detail::core_operations_emulated< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, Signed, Interprocess >
0076 >::type core_operations;
0077 typedef atomics::detail::wait_operations< core_operations > wait_operations;
0078 typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
0079 typedef typename core_operations::storage_type storage_type;
0080 static_assert(sizeof(storage_type) == sizeof(value_type), "Boost.Atomic internal error: atomic_ref storage size doesn't match the value size");
0081
0082 public:
0083 static BOOST_CONSTEXPR_OR_CONST std::size_t required_alignment = atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment ? core_operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
0084 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
0085 static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
0086
0087 protected:
0088 value_type* m_value;
0089
0090 public:
0091 BOOST_FORCEINLINE explicit base_atomic_ref_common(value_type& v) BOOST_NOEXCEPT : m_value(atomics::detail::addressof(v))
0092 {
0093 BOOST_ATOMIC_DETAIL_CLEAR_PADDING(const_cast< unqualified_value_type* >(m_value));
0094 }
0095
0096 BOOST_FORCEINLINE value_type& value() const BOOST_NOEXCEPT { return *m_value; }
0097
0098 protected:
0099 BOOST_FORCEINLINE storage_type& storage() const BOOST_NOEXCEPT
0100 {
0101 return *reinterpret_cast< storage_type* >(const_cast< unqualified_value_type* >(m_value));
0102 }
0103
0104 public:
0105 BOOST_FORCEINLINE bool is_lock_free() const BOOST_NOEXCEPT
0106 {
0107
0108
0109
0110 return is_always_lock_free;
0111 }
0112
0113 BOOST_FORCEINLINE bool has_native_wait_notify() const BOOST_NOEXCEPT
0114 {
0115 return wait_operations::has_native_wait_notify(this->storage());
0116 }
0117
0118 BOOST_FORCEINLINE void notify_one() const BOOST_NOEXCEPT
0119 {
0120 wait_operations::notify_one(this->storage());
0121 }
0122
0123 BOOST_FORCEINLINE void notify_all() const BOOST_NOEXCEPT
0124 {
0125 wait_operations::notify_all(this->storage());
0126 }
0127 };
0128
0129 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0130 template< typename T, bool Signed, bool Interprocess >
0131 BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, Signed, Interprocess >::required_alignment;
0132 template< typename T, bool Signed, bool Interprocess >
0133 BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::is_always_lock_free;
0134 template< typename T, bool Signed, bool Interprocess >
0135 BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::always_has_native_wait_notify;
0136 #endif
0137
0138
0139 template< typename T, typename Kind, bool Interprocess >
0140 class base_atomic_ref;
0141
0142
0143 template< typename T, bool Interprocess >
0144 class base_atomic_ref< T, void, Interprocess > :
0145 public base_atomic_ref_common< T, false, Interprocess >
0146 {
0147 private:
0148 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
0149
0150 public:
0151 typedef typename base_type::value_type value_type;
0152
0153 protected:
0154 typedef typename base_type::core_operations core_operations;
0155 typedef typename base_type::wait_operations wait_operations;
0156 typedef typename base_type::storage_type storage_type;
0157 typedef typename base_type::value_arg_type value_arg_type;
0158
0159 private:
0160 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0161 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0162 #else
0163 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0164 #endif
0165
0166 public:
0167 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
0168 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
0169 {
0170 }
0171
0172 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0173 {
0174 BOOST_ASSERT(order != memory_order_consume);
0175 BOOST_ASSERT(order != memory_order_acquire);
0176 BOOST_ASSERT(order != memory_order_acq_rel);
0177
0178 core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
0179 }
0180
0181 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0182 {
0183 BOOST_ASSERT(order != memory_order_release);
0184 BOOST_ASSERT(order != memory_order_acq_rel);
0185
0186 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
0187 }
0188
0189 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0190 {
0191 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
0192 }
0193
0194 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0195 {
0196 BOOST_ASSERT(failure_order != memory_order_release);
0197 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0198 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0199
0200 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0201 }
0202
0203 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0204 {
0205 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0206 }
0207
0208 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0209 {
0210 BOOST_ASSERT(failure_order != memory_order_release);
0211 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0212 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0213
0214 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0215 }
0216
0217 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0218 {
0219 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0220 }
0221
0222 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0223 {
0224 BOOST_ASSERT(order != memory_order_release);
0225 BOOST_ASSERT(order != memory_order_acq_rel);
0226
0227 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
0228 }
0229
0230 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
0231
0232 private:
0233 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) const BOOST_NOEXCEPT
0234 {
0235 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0236 }
0237
0238 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) const BOOST_NOEXCEPT
0239 {
0240 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
0241 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0242 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0243 return res;
0244 }
0245
0246 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) const BOOST_NOEXCEPT
0247 {
0248 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0249 }
0250
0251 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) const BOOST_NOEXCEPT
0252 {
0253 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
0254 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0255 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0256 return res;
0257 }
0258 };
0259
0260
0261
0262 template< typename T, bool Interprocess >
0263 class base_atomic_ref< T, const int, Interprocess > :
0264 public base_atomic_ref_common< T, false, Interprocess >
0265 {
0266 private:
0267 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
0268
0269 public:
0270 typedef typename base_type::value_type value_type;
0271
0272 protected:
0273 typedef typename base_type::core_operations core_operations;
0274 typedef typename base_type::wait_operations wait_operations;
0275 typedef typename base_type::storage_type storage_type;
0276 typedef typename base_type::value_arg_type value_arg_type;
0277
0278 private:
0279 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0280 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0281 #else
0282 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0283 #endif
0284
0285 public:
0286 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
0287 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
0288 {
0289 }
0290
0291 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0292 {
0293 BOOST_ASSERT(order != memory_order_consume);
0294 BOOST_ASSERT(order != memory_order_acquire);
0295 BOOST_ASSERT(order != memory_order_acq_rel);
0296
0297 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0298 }
0299
0300 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0301 {
0302 BOOST_ASSERT(order != memory_order_release);
0303 BOOST_ASSERT(order != memory_order_acq_rel);
0304
0305 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
0306 }
0307
0308 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0309 {
0310 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
0311 }
0312
0313 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0314 {
0315 BOOST_ASSERT(failure_order != memory_order_release);
0316 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0317 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0318
0319 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0320 }
0321
0322 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0323 {
0324 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0325 }
0326
0327 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0328 {
0329 BOOST_ASSERT(failure_order != memory_order_release);
0330 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0331 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0332
0333 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0334 }
0335
0336 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0337 {
0338 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0339 }
0340
0341 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0342 {
0343 BOOST_ASSERT(order != memory_order_release);
0344 BOOST_ASSERT(order != memory_order_acq_rel);
0345
0346 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
0347 }
0348
0349 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
0350
0351 private:
0352 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) const BOOST_NOEXCEPT
0353 {
0354 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0355 }
0356
0357 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) const BOOST_NOEXCEPT
0358 {
0359 storage_type old_value = static_cast< storage_type >(expected);
0360 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0361 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0362 return res;
0363 }
0364
0365 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) const BOOST_NOEXCEPT
0366 {
0367 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0368 }
0369
0370 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) const BOOST_NOEXCEPT
0371 {
0372 storage_type old_value = static_cast< storage_type >(expected);
0373 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0374 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0375 return res;
0376 }
0377 };
0378
0379
0380
0381 template< typename T, bool Interprocess >
0382 class base_atomic_ref< T, int, Interprocess > :
0383 public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess >
0384 {
0385 private:
0386 typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
0387
0388 public:
0389 typedef typename base_type::value_type value_type;
0390 typedef typename base_type::value_type difference_type;
0391
0392 protected:
0393 typedef typename base_type::core_operations core_operations;
0394 typedef typename base_type::wait_operations wait_operations;
0395 typedef atomics::detail::extra_operations< core_operations > extra_operations;
0396 typedef typename base_type::storage_type storage_type;
0397 typedef value_type value_arg_type;
0398
0399 private:
0400 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0401 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0402 #else
0403 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0404 #endif
0405
0406 public:
0407 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
0408 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
0409 {
0410 }
0411
0412
0413 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0414 {
0415 BOOST_ASSERT(order != memory_order_consume);
0416 BOOST_ASSERT(order != memory_order_acquire);
0417 BOOST_ASSERT(order != memory_order_acq_rel);
0418
0419 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0420 }
0421
0422 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0423 {
0424 BOOST_ASSERT(order != memory_order_release);
0425 BOOST_ASSERT(order != memory_order_acq_rel);
0426
0427 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
0428 }
0429
0430 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0431 {
0432 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
0433 }
0434
0435 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0436 {
0437 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
0438 }
0439
0440 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0441 {
0442 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
0443 }
0444
0445 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0446 {
0447 BOOST_ASSERT(failure_order != memory_order_release);
0448 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0449 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0450
0451 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0452 }
0453
0454 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0455 {
0456 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0457 }
0458
0459 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0460 {
0461 BOOST_ASSERT(failure_order != memory_order_release);
0462 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0463 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0464
0465 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0466 }
0467
0468 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0469 {
0470 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0471 }
0472
0473 BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0474 {
0475 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
0476 }
0477
0478 BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0479 {
0480 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
0481 }
0482
0483 BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0484 {
0485 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
0486 }
0487
0488
0489 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0490 {
0491 return atomics::detail::bitwise_cast< value_type >(extra_operations::fetch_negate(this->storage(), order));
0492 }
0493
0494 BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0495 {
0496 return atomics::detail::bitwise_cast< value_type >(extra_operations::fetch_complement(this->storage(), order));
0497 }
0498
0499 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0500 {
0501 return atomics::detail::bitwise_cast< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
0502 }
0503
0504 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0505 {
0506 return atomics::detail::bitwise_cast< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
0507 }
0508
0509 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0510 {
0511 return atomics::detail::bitwise_cast< value_type >(extra_operations::negate(this->storage(), order));
0512 }
0513
0514 BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0515 {
0516 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
0517 }
0518
0519 BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0520 {
0521 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
0522 }
0523
0524 BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0525 {
0526 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
0527 }
0528
0529 BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0530 {
0531 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_complement(this->storage(), order));
0532 }
0533
0534 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0535 {
0536 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
0537 }
0538
0539 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0540 {
0541 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
0542 }
0543
0544 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0545 {
0546 extra_operations::opaque_negate(this->storage(), order);
0547 }
0548
0549 BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0550 {
0551 extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
0552 }
0553
0554 BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0555 {
0556 extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
0557 }
0558
0559 BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0560 {
0561 extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
0562 }
0563
0564 BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0565 {
0566 extra_operations::opaque_complement(this->storage(), order);
0567 }
0568
0569 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0570 {
0571 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
0572 }
0573
0574 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0575 {
0576 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
0577 }
0578
0579 BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0580 {
0581 return extra_operations::negate_and_test(this->storage(), order);
0582 }
0583
0584 BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0585 {
0586 return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
0587 }
0588
0589 BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0590 {
0591 return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
0592 }
0593
0594 BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0595 {
0596 return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
0597 }
0598
0599 BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0600 {
0601 return extra_operations::complement_and_test(this->storage(), order);
0602 }
0603
0604 BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0605 {
0606 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0607 return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
0608 }
0609
0610 BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0611 {
0612 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0613 return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
0614 }
0615
0616 BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0617 {
0618 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0619 return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
0620 }
0621
0622
0623 BOOST_FORCEINLINE value_type operator++(int) const BOOST_NOEXCEPT
0624 {
0625 return fetch_add(1);
0626 }
0627
0628 BOOST_FORCEINLINE value_type operator++() const BOOST_NOEXCEPT
0629 {
0630 return add(1);
0631 }
0632
0633 BOOST_FORCEINLINE value_type operator--(int) const BOOST_NOEXCEPT
0634 {
0635 return fetch_sub(1);
0636 }
0637
0638 BOOST_FORCEINLINE value_type operator--() const BOOST_NOEXCEPT
0639 {
0640 return sub(1);
0641 }
0642
0643 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
0644 {
0645 return add(v);
0646 }
0647
0648 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
0649 {
0650 return sub(v);
0651 }
0652
0653 BOOST_FORCEINLINE value_type operator&=(value_type v) const BOOST_NOEXCEPT
0654 {
0655 return bitwise_and(v);
0656 }
0657
0658 BOOST_FORCEINLINE value_type operator|=(value_type v) const BOOST_NOEXCEPT
0659 {
0660 return bitwise_or(v);
0661 }
0662
0663 BOOST_FORCEINLINE value_type operator^=(value_type v) const BOOST_NOEXCEPT
0664 {
0665 return bitwise_xor(v);
0666 }
0667
0668 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0669 {
0670 BOOST_ASSERT(order != memory_order_release);
0671 BOOST_ASSERT(order != memory_order_acq_rel);
0672
0673 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
0674 }
0675
0676 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
0677
0678 private:
0679 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) const BOOST_NOEXCEPT
0680 {
0681 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0682 }
0683
0684 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) const BOOST_NOEXCEPT
0685 {
0686 storage_type old_value = static_cast< storage_type >(expected);
0687 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0688 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0689 return res;
0690 }
0691
0692 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) const BOOST_NOEXCEPT
0693 {
0694 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0695 }
0696
0697 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) const BOOST_NOEXCEPT
0698 {
0699 storage_type old_value = static_cast< storage_type >(expected);
0700 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0701 expected = atomics::detail::bitwise_cast< value_type >(old_value);
0702 return res;
0703 }
0704 };
0705
0706
0707 template< bool Interprocess >
0708 class base_atomic_ref< bool, int, Interprocess > :
0709 public base_atomic_ref_common< bool, false, Interprocess >
0710 {
0711 private:
0712 typedef base_atomic_ref_common< bool, false, Interprocess > base_type;
0713
0714 public:
0715 typedef bool value_type;
0716
0717 protected:
0718 typedef typename base_type::core_operations core_operations;
0719 typedef typename base_type::wait_operations wait_operations;
0720 typedef typename base_type::storage_type storage_type;
0721 typedef value_type value_arg_type;
0722
0723 private:
0724 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0725 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0726 #else
0727 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0728 #endif
0729
0730 public:
0731 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
0732 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
0733 {
0734 }
0735
0736
0737 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0738 {
0739 BOOST_ASSERT(order != memory_order_consume);
0740 BOOST_ASSERT(order != memory_order_acquire);
0741 BOOST_ASSERT(order != memory_order_acq_rel);
0742
0743 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0744 }
0745
0746 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0747 {
0748 BOOST_ASSERT(order != memory_order_release);
0749 BOOST_ASSERT(order != memory_order_acq_rel);
0750
0751 return !!core_operations::load(this->storage(), order);
0752 }
0753
0754 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0755 {
0756 return !!core_operations::exchange(this->storage(), static_cast< storage_type >(v), order);
0757 }
0758
0759 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0760 {
0761 BOOST_ASSERT(failure_order != memory_order_release);
0762 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0763 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0764
0765 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0766 }
0767
0768 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0769 {
0770 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0771 }
0772
0773 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0774 {
0775 BOOST_ASSERT(failure_order != memory_order_release);
0776 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0777 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0778
0779 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0780 }
0781
0782 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0783 {
0784 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0785 }
0786
0787 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0788 {
0789 BOOST_ASSERT(order != memory_order_release);
0790 BOOST_ASSERT(order != memory_order_acq_rel);
0791
0792 return !!wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order);
0793 }
0794
0795 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
0796
0797 private:
0798 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) const BOOST_NOEXCEPT
0799 {
0800 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0801 }
0802
0803 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) const BOOST_NOEXCEPT
0804 {
0805 storage_type old_value = static_cast< storage_type >(expected);
0806 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0807 expected = !!old_value;
0808 return res;
0809 }
0810
0811 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) const BOOST_NOEXCEPT
0812 {
0813 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0814 }
0815
0816 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) const BOOST_NOEXCEPT
0817 {
0818 storage_type old_value = static_cast< storage_type >(expected);
0819 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0820 expected = !!old_value;
0821 return res;
0822 }
0823 };
0824
0825
0826 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
0827
0828
0829 template< typename T, bool Interprocess >
0830 class base_atomic_ref< T, float, Interprocess > :
0831 public base_atomic_ref_common< T, false, Interprocess >
0832 {
0833 private:
0834 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
0835
0836 public:
0837 typedef typename base_type::value_type value_type;
0838 typedef typename base_type::value_type difference_type;
0839
0840 protected:
0841 typedef typename base_type::core_operations core_operations;
0842 typedef typename base_type::wait_operations wait_operations;
0843 typedef atomics::detail::extra_operations< core_operations > extra_operations;
0844 typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations;
0845 typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations;
0846 typedef typename base_type::storage_type storage_type;
0847 typedef value_type value_arg_type;
0848
0849 private:
0850 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0851 typedef atomics::detail::integral_constant< bool, atomics::detail::value_size_of< value_type >::value != sizeof(storage_type) > has_padding_bits;
0852 #endif
0853 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0854 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0855 #else
0856 typedef atomics::detail::integral_constant< bool, has_padding_bits::value || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0857 #endif
0858
0859 public:
0860 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
0861 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
0862 {
0863
0864
0865 #if defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0866 this->clear_padding_bits(has_padding_bits());
0867 #endif
0868 }
0869
0870 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0871 {
0872 BOOST_ASSERT(order != memory_order_consume);
0873 BOOST_ASSERT(order != memory_order_acquire);
0874 BOOST_ASSERT(order != memory_order_acq_rel);
0875
0876 core_operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
0877 }
0878
0879 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0880 {
0881 BOOST_ASSERT(order != memory_order_release);
0882 BOOST_ASSERT(order != memory_order_acq_rel);
0883
0884 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::load(this->storage(), order));
0885 }
0886
0887 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0888 {
0889 return fp_operations::fetch_add(this->storage(), v, order);
0890 }
0891
0892 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0893 {
0894 return fp_operations::fetch_sub(this->storage(), v, order);
0895 }
0896
0897 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0898 {
0899 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
0900 }
0901
0902 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0903 {
0904 BOOST_ASSERT(failure_order != memory_order_release);
0905 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0906 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0907
0908 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0909 }
0910
0911 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0912 {
0913 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0914 }
0915
0916 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
0917 {
0918 BOOST_ASSERT(failure_order != memory_order_release);
0919 BOOST_ASSERT(failure_order != memory_order_acq_rel);
0920 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0921
0922 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0923 }
0924
0925 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0926 {
0927 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0928 }
0929
0930
0931 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0932 {
0933 return extra_fp_operations::fetch_negate(this->storage(), order);
0934 }
0935
0936 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0937 {
0938 return extra_fp_operations::add(this->storage(), v, order);
0939 }
0940
0941 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0942 {
0943 return extra_fp_operations::sub(this->storage(), v, order);
0944 }
0945
0946 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0947 {
0948 return extra_fp_operations::negate(this->storage(), order);
0949 }
0950
0951 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0952 {
0953 extra_fp_operations::opaque_add(this->storage(), v, order);
0954 }
0955
0956 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0957 {
0958 extra_fp_operations::opaque_sub(this->storage(), v, order);
0959 }
0960
0961 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0962 {
0963 extra_fp_operations::opaque_negate(this->storage(), order);
0964 }
0965
0966
0967 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
0968 {
0969 return add(v);
0970 }
0971
0972 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
0973 {
0974 return sub(v);
0975 }
0976
0977 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
0978 {
0979 BOOST_ASSERT(order != memory_order_release);
0980 BOOST_ASSERT(order != memory_order_acq_rel);
0981
0982 return atomics::detail::bitwise_fp_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(old_val), order));
0983 }
0984
0985 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
0986
0987 private:
0988 #if defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0989 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::false_type) const BOOST_NOEXCEPT
0990 {
0991 }
0992
0993 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::true_type) const BOOST_NOEXCEPT
0994 {
0995 atomics::detail::clear_tail_padding_bits< atomics::detail::value_size_of< value_type >::value >(this->storage());
0996 }
0997 #endif
0998
0999 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) const BOOST_NOEXCEPT
1000 {
1001 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1002 }
1003
1004 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) const BOOST_NOEXCEPT
1005 {
1006 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
1007 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1008 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1009 return res;
1010 }
1011
1012 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) const BOOST_NOEXCEPT
1013 {
1014 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1015 }
1016
1017 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) const BOOST_NOEXCEPT
1018 {
1019 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
1020 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1021 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1022 return res;
1023 }
1024 };
1025
1026 #endif
1027
1028
1029
1030 template< typename T, bool Interprocess >
1031 class base_atomic_ref< T*, void*, Interprocess > :
1032 public base_atomic_ref_common< T*, false, Interprocess >
1033 {
1034 private:
1035 typedef base_atomic_ref_common< T*, false, Interprocess > base_type;
1036
1037 public:
1038 typedef typename base_type::value_type value_type;
1039 typedef std::ptrdiff_t difference_type;
1040
1041 protected:
1042 typedef typename base_type::core_operations core_operations;
1043 typedef typename base_type::wait_operations wait_operations;
1044 typedef atomics::detail::extra_operations< core_operations > extra_operations;
1045 typedef typename base_type::storage_type storage_type;
1046 typedef value_type value_arg_type;
1047
1048 private:
1049 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
1050 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
1051 #else
1052 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
1053 #endif
1054
1055 public:
1056 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
1057 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
1058 {
1059 }
1060
1061
1062 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1063 {
1064 BOOST_ASSERT(order != memory_order_consume);
1065 BOOST_ASSERT(order != memory_order_acquire);
1066 BOOST_ASSERT(order != memory_order_acq_rel);
1067
1068 core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
1069 }
1070
1071 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1072 {
1073 BOOST_ASSERT(order != memory_order_release);
1074 BOOST_ASSERT(order != memory_order_acq_rel);
1075
1076 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
1077 }
1078
1079 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1080 {
1081 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
1082 }
1083
1084 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1085 {
1086 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
1087 }
1088
1089 BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1090 {
1091 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
1092 }
1093
1094 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
1095 {
1096 BOOST_ASSERT(failure_order != memory_order_release);
1097 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1098 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1099
1100 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
1101 }
1102
1103 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1104 {
1105 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
1106 }
1107
1108 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
1109 {
1110 BOOST_ASSERT(failure_order != memory_order_release);
1111 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1112 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1113
1114 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
1115 }
1116
1117 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1118 {
1119 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
1120 }
1121
1122
1123 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1124 {
1125 return atomics::detail::bitwise_cast< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
1126 }
1127
1128 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1129 {
1130 return atomics::detail::bitwise_cast< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
1131 }
1132
1133 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1134 {
1135 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
1136 }
1137
1138 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1139 {
1140 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
1141 }
1142
1143 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1144 {
1145 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
1146 }
1147
1148 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1149 {
1150 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
1151 }
1152
1153
1154 BOOST_FORCEINLINE value_type operator++(int) const BOOST_NOEXCEPT
1155 {
1156 return fetch_add(1);
1157 }
1158
1159 BOOST_FORCEINLINE value_type operator++() const BOOST_NOEXCEPT
1160 {
1161 return add(1);
1162 }
1163
1164 BOOST_FORCEINLINE value_type operator--(int) const BOOST_NOEXCEPT
1165 {
1166 return fetch_sub(1);
1167 }
1168
1169 BOOST_FORCEINLINE value_type operator--() const BOOST_NOEXCEPT
1170 {
1171 return sub(1);
1172 }
1173
1174 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
1175 {
1176 return add(v);
1177 }
1178
1179 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
1180 {
1181 return sub(v);
1182 }
1183
1184 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1185 {
1186 BOOST_ASSERT(order != memory_order_release);
1187 BOOST_ASSERT(order != memory_order_acq_rel);
1188
1189 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
1190 }
1191
1192 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
1193
1194 private:
1195 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) const BOOST_NOEXCEPT
1196 {
1197 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1198 }
1199
1200 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) const BOOST_NOEXCEPT
1201 {
1202 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
1203 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1204 expected = atomics::detail::bitwise_cast< value_type >(old_value);
1205 return res;
1206 }
1207
1208 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) const BOOST_NOEXCEPT
1209 {
1210 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1211 }
1212
1213 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) const BOOST_NOEXCEPT
1214 {
1215 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
1216 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1217 expected = atomics::detail::bitwise_cast< value_type >(old_value);
1218 return res;
1219 }
1220 };
1221
1222 }
1223 }
1224 }
1225
1226 #include <boost/atomic/detail/footer.hpp>
1227
1228 #endif