2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
6 * Copyright (c) 2011 Helge Bahmann
7 * Copyright (c) 2013 Tim Blechmann
8 * Copyright (c) 2014-2020 Andrey Semashev
11 * \file atomic/detail/atomic_impl.hpp
13 * This header contains implementation of \c atomic template.
16 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
20 #include <boost/assert.hpp>
21 #include <boost/memory_order.hpp>
22 #include <boost/atomic/detail/config.hpp>
23 #include <boost/atomic/detail/intptr.hpp>
24 #include <boost/atomic/detail/storage_traits.hpp>
25 #include <boost/atomic/detail/bitwise_cast.hpp>
26 #include <boost/atomic/detail/integral_conversions.hpp>
27 #include <boost/atomic/detail/core_operations.hpp>
28 #include <boost/atomic/detail/wait_operations.hpp>
29 #include <boost/atomic/detail/extra_operations.hpp>
30 #include <boost/atomic/detail/memory_order_utils.hpp>
31 #include <boost/atomic/detail/aligned_variable.hpp>
32 #include <boost/atomic/detail/type_traits/is_signed.hpp>
33 #include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
34 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
35 #include <boost/atomic/detail/type_traits/conditional.hpp>
36 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
37 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
38 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
39 #include <boost/atomic/detail/fp_operations.hpp>
40 #include <boost/atomic/detail/extra_fp_operations.hpp>
42 #include <boost/atomic/detail/header.hpp>
44 #ifdef BOOST_HAS_PRAGMA_ONCE
49 * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
50 * see comment for convert_memory_order_to_gcc in gcc_atomic_memory_order_utils.hpp.
57 template< typename T, bool Signed, bool Interprocess >
58 class base_atomic_common
64 typedef atomics::detail::core_operations< storage_size_of< value_type >::value, Signed, Interprocess > core_operations;
65 typedef atomics::detail::wait_operations< core_operations > wait_operations;
66 typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
67 typedef typename core_operations::storage_type storage_type;
70 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;
73 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
74 static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
77 BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(storage_alignment, storage_type, m_storage);
80 BOOST_DEFAULTED_FUNCTION(base_atomic_common() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
81 BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic_common(storage_type v) BOOST_NOEXCEPT : m_storage(v)
85 BOOST_FORCEINLINE value_type& value() BOOST_NOEXCEPT { return *reinterpret_cast< value_type* >(&m_storage); }
86 BOOST_FORCEINLINE value_type volatile& value() volatile BOOST_NOEXCEPT { return *reinterpret_cast< volatile value_type* >(&m_storage); }
87 BOOST_FORCEINLINE value_type const& value() const BOOST_NOEXCEPT { return *reinterpret_cast< const value_type* >(&m_storage); }
88 BOOST_FORCEINLINE value_type const volatile& value() const volatile BOOST_NOEXCEPT { return *reinterpret_cast< const volatile value_type* >(&m_storage); }
91 BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return m_storage; }
92 BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return m_storage; }
93 BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return m_storage; }
94 BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return m_storage; }
97 BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
99 // C++17 requires all instances of atomic<> return a value consistent with is_always_lock_free here.
100 // Boost.Atomic also enforces the required alignment of the atomic storage, so we can always return is_always_lock_free.
101 return is_always_lock_free;
104 BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
106 return wait_operations::has_native_wait_notify(this->storage());
109 BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
111 wait_operations::notify_one(this->storage());
114 BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
116 wait_operations::notify_all(this->storage());
120 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
121 template< typename T, bool Signed, bool Interprocess >
122 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::is_always_lock_free;
123 template< typename T, bool Signed, bool Interprocess >
124 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::always_has_native_wait_notify;
128 template< typename T, bool Interprocess, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
129 class base_atomic_generic;
131 template< typename T, bool Interprocess >
132 class base_atomic_generic< T, Interprocess, true > :
133 public base_atomic_common< T, false, Interprocess >
136 typedef base_atomic_common< T, false, Interprocess > base_type;
139 typedef typename base_type::storage_type storage_type;
140 typedef typename base_type::value_arg_type value_arg_type;
143 BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
144 BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
149 template< typename T, bool Interprocess >
150 class base_atomic_generic< T, Interprocess, false > :
151 public base_atomic_common< T, false, Interprocess >
154 typedef base_atomic_common< T, false, Interprocess > base_type;
157 typedef typename base_type::value_type value_type;
160 typedef typename base_type::storage_type storage_type;
161 typedef typename base_type::value_arg_type value_arg_type;
164 BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
170 template< typename T, typename Kind, bool Interprocess >
173 //! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
174 template< typename T, bool Interprocess >
175 class base_atomic< T, void, Interprocess > :
176 public base_atomic_generic< T, Interprocess >
179 typedef base_atomic_generic< T, Interprocess > base_type;
182 typedef typename base_type::value_type value_type;
185 typedef typename base_type::core_operations core_operations;
186 typedef typename base_type::wait_operations wait_operations;
187 typedef typename base_type::storage_type storage_type;
188 typedef typename base_type::value_arg_type value_arg_type;
191 typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
194 BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
195 BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v)
199 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
201 BOOST_ASSERT(order != memory_order_consume);
202 BOOST_ASSERT(order != memory_order_acquire);
203 BOOST_ASSERT(order != memory_order_acq_rel);
205 core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
208 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
210 BOOST_ASSERT(order != memory_order_release);
211 BOOST_ASSERT(order != memory_order_acq_rel);
213 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
216 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
218 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
221 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
223 BOOST_ASSERT(failure_order != memory_order_release);
224 BOOST_ASSERT(failure_order != memory_order_acq_rel);
225 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
227 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
230 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
232 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
235 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
237 BOOST_ASSERT(failure_order != memory_order_release);
238 BOOST_ASSERT(failure_order != memory_order_acq_rel);
239 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
241 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
244 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
246 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
249 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
251 BOOST_ASSERT(order != memory_order_release);
252 BOOST_ASSERT(order != memory_order_acq_rel);
254 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
257 BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
258 BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
261 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
263 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
264 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
266 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
270 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
272 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
273 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
274 expected = atomics::detail::bitwise_cast< value_type >(old_value);
278 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
280 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
281 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
283 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
287 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
289 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
290 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
291 expected = atomics::detail::bitwise_cast< value_type >(old_value);
297 //! Implementation for integers
298 template< typename T, bool Interprocess >
299 class base_atomic< T, int, Interprocess > :
300 public base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess >
303 typedef base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
306 typedef typename base_type::value_type value_type;
307 typedef value_type difference_type;
310 typedef typename base_type::core_operations core_operations;
311 typedef typename base_type::wait_operations wait_operations;
312 typedef atomics::detail::extra_operations< core_operations > extra_operations;
313 typedef typename base_type::storage_type storage_type;
314 typedef value_type value_arg_type;
317 typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
320 BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
321 BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
324 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
326 BOOST_ASSERT(order != memory_order_consume);
327 BOOST_ASSERT(order != memory_order_acquire);
328 BOOST_ASSERT(order != memory_order_acq_rel);
330 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
333 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
335 BOOST_ASSERT(order != memory_order_release);
336 BOOST_ASSERT(order != memory_order_acq_rel);
338 return atomics::detail::integral_truncate< value_type >(core_operations::load(this->storage(), order));
341 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
343 return atomics::detail::integral_truncate< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
346 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
348 return atomics::detail::integral_truncate< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
351 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
353 return atomics::detail::integral_truncate< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
356 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
358 BOOST_ASSERT(failure_order != memory_order_release);
359 BOOST_ASSERT(failure_order != memory_order_acq_rel);
360 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
362 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
365 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
367 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
370 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
372 BOOST_ASSERT(failure_order != memory_order_release);
373 BOOST_ASSERT(failure_order != memory_order_acq_rel);
374 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
376 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
379 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
381 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
384 BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
386 return atomics::detail::integral_truncate< value_type >(core_operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
389 BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
391 return atomics::detail::integral_truncate< value_type >(core_operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
394 BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
396 return atomics::detail::integral_truncate< value_type >(core_operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
399 // Boost.Atomic extensions
400 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
402 return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
405 BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
407 return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
410 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
412 return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
415 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
417 return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
420 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
422 return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
425 BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
427 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
430 BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
432 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
435 BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
437 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
440 BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
442 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
445 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
447 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
450 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
452 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
455 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
457 extra_operations::opaque_negate(this->storage(), order);
460 BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
462 extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
465 BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
467 extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
470 BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
472 extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
475 BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
477 extra_operations::opaque_complement(this->storage(), order);
480 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
482 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
485 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
487 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
490 BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
492 return extra_operations::negate_and_test(this->storage(), order);
495 BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
497 return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
500 BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
502 return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
505 BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
507 return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
510 BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
512 return extra_operations::complement_and_test(this->storage(), order);
515 BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
517 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
518 return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
521 BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
523 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
524 return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
527 BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
529 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
530 return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
534 BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
539 BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
544 BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
549 BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
554 BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
559 BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
564 BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT
566 return bitwise_and(v);
569 BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT
571 return bitwise_or(v);
574 BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT
576 return bitwise_xor(v);
579 BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
581 BOOST_ASSERT(order != memory_order_release);
582 BOOST_ASSERT(order != memory_order_acq_rel);
584 return atomics::detail::integral_truncate< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
587 BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
588 BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
591 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
593 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
594 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
596 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
600 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
602 storage_type old_value = static_cast< storage_type >(expected);
603 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
604 expected = atomics::detail::integral_truncate< value_type >(old_value);
608 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
610 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
611 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
613 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
617 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
619 storage_type old_value = static_cast< storage_type >(expected);
620 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
621 expected = atomics::detail::integral_truncate< value_type >(old_value);
626 //! Implementation for bool
627 template< bool Interprocess >
628 class base_atomic< bool, int, Interprocess > :
629 public base_atomic_common< bool, false, Interprocess >
632 typedef base_atomic_common< bool, false, Interprocess > base_type;
635 typedef typename base_type::value_type value_type;
638 typedef typename base_type::core_operations core_operations;
639 typedef typename base_type::wait_operations wait_operations;
640 typedef typename base_type::storage_type storage_type;
641 typedef value_type value_arg_type;
644 typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
647 BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
648 BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
651 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
653 BOOST_ASSERT(order != memory_order_consume);
654 BOOST_ASSERT(order != memory_order_acquire);
655 BOOST_ASSERT(order != memory_order_acq_rel);
657 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
660 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
662 BOOST_ASSERT(order != memory_order_release);
663 BOOST_ASSERT(order != memory_order_acq_rel);
665 return !!core_operations::load(this->storage(), order);
668 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
670 return !!core_operations::exchange(this->storage(), static_cast< storage_type >(v), order);
673 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
675 BOOST_ASSERT(failure_order != memory_order_release);
676 BOOST_ASSERT(failure_order != memory_order_acq_rel);
677 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
679 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
682 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
684 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
687 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
689 BOOST_ASSERT(failure_order != memory_order_release);
690 BOOST_ASSERT(failure_order != memory_order_acq_rel);
691 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
693 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
696 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
698 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
701 BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
703 BOOST_ASSERT(order != memory_order_release);
704 BOOST_ASSERT(order != memory_order_acq_rel);
706 return !!wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order);
709 BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
710 BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
713 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
715 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
716 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
718 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
722 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
724 storage_type old_value = static_cast< storage_type >(expected);
725 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
726 expected = !!old_value;
730 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
732 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
733 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
735 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
739 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
741 storage_type old_value = static_cast< storage_type >(expected);
742 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
743 expected = !!old_value;
749 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
751 //! Implementation for floating point types
752 template< typename T, bool Interprocess >
753 class base_atomic< T, float, Interprocess > :
754 public base_atomic_common< T, false, Interprocess >
757 typedef base_atomic_common< T, false, Interprocess > base_type;
760 typedef typename base_type::value_type value_type;
761 typedef value_type difference_type;
764 typedef typename base_type::core_operations core_operations;
765 typedef typename base_type::wait_operations wait_operations;
766 typedef atomics::detail::extra_operations< core_operations > extra_operations;
767 typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations;
768 typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations;
769 typedef typename base_type::storage_type storage_type;
770 typedef value_type value_arg_type;
773 typedef atomics::detail::integral_constant< bool,
774 atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment
778 BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
779 BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
781 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
783 BOOST_ASSERT(order != memory_order_consume);
784 BOOST_ASSERT(order != memory_order_acquire);
785 BOOST_ASSERT(order != memory_order_acq_rel);
787 core_operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
790 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
792 BOOST_ASSERT(order != memory_order_release);
793 BOOST_ASSERT(order != memory_order_acq_rel);
795 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::load(this->storage(), order));
798 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
800 return fp_operations::fetch_add(this->storage(), v, order);
803 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
805 return fp_operations::fetch_sub(this->storage(), v, order);
808 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
810 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
813 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
815 BOOST_ASSERT(failure_order != memory_order_release);
816 BOOST_ASSERT(failure_order != memory_order_acq_rel);
817 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
819 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
822 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
824 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
827 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
829 BOOST_ASSERT(failure_order != memory_order_release);
830 BOOST_ASSERT(failure_order != memory_order_acq_rel);
831 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
833 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
836 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
838 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
841 // Boost.Atomic extensions
842 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
844 return extra_fp_operations::fetch_negate(this->storage(), order);
847 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
849 return extra_fp_operations::add(this->storage(), v, order);
852 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
854 return extra_fp_operations::sub(this->storage(), v, order);
857 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
859 return extra_fp_operations::negate(this->storage(), order);
862 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
864 extra_fp_operations::opaque_add(this->storage(), v, order);
867 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
869 extra_fp_operations::opaque_sub(this->storage(), v, order);
872 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
874 extra_fp_operations::opaque_negate(this->storage(), order);
878 BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
883 BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
888 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
890 BOOST_ASSERT(order != memory_order_release);
891 BOOST_ASSERT(order != memory_order_acq_rel);
893 return atomics::detail::bitwise_fp_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(old_val), order));
896 BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
897 BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
900 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
902 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
903 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);
905 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
909 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
911 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
912 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
913 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
917 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
919 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
920 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);
922 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
926 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
928 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
929 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
930 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
935 #endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
938 //! Implementation for pointers to object types
939 template< typename T, bool Interprocess >
940 class base_atomic< T*, void*, Interprocess > :
941 public base_atomic_common< T*, false, Interprocess >
944 typedef base_atomic_common< T*, false, Interprocess > base_type;
947 typedef typename base_type::value_type value_type;
948 typedef std::ptrdiff_t difference_type;
951 typedef typename base_type::core_operations core_operations;
952 typedef typename base_type::wait_operations wait_operations;
953 typedef atomics::detail::extra_operations< core_operations > extra_operations;
954 typedef typename base_type::storage_type storage_type;
955 typedef value_type value_arg_type;
958 typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
960 // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
961 // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
962 typedef atomics::detail::uintptr_t uintptr_storage_type;
965 BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
966 BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
971 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
973 BOOST_ASSERT(order != memory_order_consume);
974 BOOST_ASSERT(order != memory_order_acquire);
975 BOOST_ASSERT(order != memory_order_acq_rel);
977 core_operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
980 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
982 BOOST_ASSERT(order != memory_order_release);
983 BOOST_ASSERT(order != memory_order_acq_rel);
985 return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::load(this->storage(), order)));
988 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
990 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)));
993 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
995 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)));
998 BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1000 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)));
1003 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1005 BOOST_ASSERT(failure_order != memory_order_release);
1006 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1007 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1009 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
1012 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1014 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
1017 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1019 BOOST_ASSERT(failure_order != memory_order_release);
1020 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1021 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1023 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
1026 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1028 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
1031 // Boost.Atomic extensions
1032 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1034 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)));
1037 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1039 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)));
1042 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1044 extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1047 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1049 extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1052 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1054 return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1057 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1059 return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1063 BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
1065 return fetch_add(1);
1068 BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
1073 BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
1075 return fetch_sub(1);
1078 BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
1083 BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
1088 BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
1093 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1095 BOOST_ASSERT(order != memory_order_release);
1096 BOOST_ASSERT(order != memory_order_acq_rel);
1098 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)));
1101 BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
1102 BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
1105 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
1107 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1108 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);
1110 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1114 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
1116 storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1117 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1118 expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1122 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
1124 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1125 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);
1127 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1131 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
1133 storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1134 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1135 expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1140 } // namespace detail
1141 } // namespace atomics
1142 } // namespace boost
1144 #include <boost/atomic/detail/footer.hpp>
1146 #endif // BOOST_ATOMIC_DETAIL_ATOMIC_IMPl_HPP_INCLUDED_