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