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) 2020 Andrey Semashev
9 * \file atomic/detail/atomic_ref_template.hpp
11 * This header contains interface definition of \c atomic_ref template.
14 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_
18 #include <boost/cstdint.hpp>
19 #include <boost/assert.hpp>
20 #include <boost/static_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/classify.hpp>
25 #include <boost/atomic/detail/addressof.hpp>
26 #include <boost/atomic/detail/storage_traits.hpp>
27 #include <boost/atomic/detail/bitwise_cast.hpp>
28 #include <boost/atomic/detail/integral_conversions.hpp>
29 #include <boost/atomic/detail/operations.hpp>
30 #include <boost/atomic/detail/extra_operations.hpp>
31 #include <boost/atomic/detail/memory_order_utils.hpp>
32 #include <boost/atomic/detail/type_traits/is_signed.hpp>
33 #include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp>
34 #include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
35 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
36 #include <boost/atomic/detail/type_traits/conditional.hpp>
37 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
38 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
39 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
40 #include <boost/atomic/detail/fp_operations.hpp>
41 #include <boost/atomic/detail/extra_fp_operations.hpp>
44 #ifdef BOOST_HAS_PRAGMA_ONCE
48 #if defined(BOOST_MSVC)
50 // 'boost::atomics::atomic_ref<T>' : multiple assignment operators specified
51 #pragma warning(disable: 4522)
55 * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
56 * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
63 template< typename T, bool IsSigned >
64 struct is_atomic_ref_lock_free
67 typedef atomics::detail::operations< sizeof(value_type), IsSigned > operations;
68 typedef typename operations::storage_type storage_type;
70 static BOOST_CONSTEXPR_OR_CONST bool value = sizeof(value_type) == sizeof(storage_type) && operations::is_always_lock_free;
73 template< typename T, bool IsSigned >
74 class base_atomic_ref_common
80 typedef typename atomics::detail::conditional<
81 atomics::detail::is_atomic_ref_lock_free< T, IsSigned >::value,
82 atomics::detail::operations< sizeof(value_type), IsSigned >,
83 atomics::detail::emulated_operations< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, IsSigned >
85 typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
86 typedef typename operations::storage_type storage_type;
89 static BOOST_CONSTEXPR_OR_CONST std::size_t required_alignment = atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment ? operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
90 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = operations::is_always_lock_free;
96 BOOST_FORCEINLINE explicit base_atomic_ref_common(value_type& v) BOOST_NOEXCEPT : m_value(atomics::detail::addressof(v))
101 BOOST_FORCEINLINE storage_type& storage() const BOOST_NOEXCEPT
103 return *reinterpret_cast< storage_type* >(m_value);
107 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
108 template< typename T, bool IsSigned >
109 BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, IsSigned >::required_alignment;
110 template< typename T, bool IsSigned >
111 BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, IsSigned >::is_always_lock_free;
115 template< typename T, typename Kind >
116 class base_atomic_ref;
118 //! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
119 template< typename T >
120 class base_atomic_ref< T, void > :
121 public base_atomic_ref_common< T, false >
124 typedef base_atomic_ref_common< T, false > base_type;
127 typedef typename base_type::value_type value_type;
130 typedef typename base_type::operations operations;
131 typedef typename base_type::storage_type storage_type;
132 typedef typename base_type::value_arg_type value_arg_type;
135 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
138 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
139 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
143 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
145 BOOST_ASSERT(order != memory_order_consume);
146 BOOST_ASSERT(order != memory_order_acquire);
147 BOOST_ASSERT(order != memory_order_acq_rel);
149 operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
152 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
154 BOOST_ASSERT(order != memory_order_release);
155 BOOST_ASSERT(order != memory_order_acq_rel);
157 return atomics::detail::bitwise_cast< value_type >(operations::load(this->storage(), order));
160 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
162 return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
165 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
167 BOOST_ASSERT(failure_order != memory_order_release);
168 BOOST_ASSERT(failure_order != memory_order_acq_rel);
169 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
171 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
174 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
176 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
179 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
181 BOOST_ASSERT(failure_order != memory_order_release);
182 BOOST_ASSERT(failure_order != memory_order_acq_rel);
183 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
185 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
188 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
190 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
193 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
196 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
198 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
199 return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
201 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
205 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
207 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
208 const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
209 expected = atomics::detail::bitwise_cast< value_type >(old_value);
213 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
215 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
216 return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
218 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
222 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
224 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
225 const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
226 expected = atomics::detail::bitwise_cast< value_type >(old_value);
232 //! Implementation for integers
233 template< typename T >
234 class base_atomic_ref< T, int > :
235 public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value >
238 typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value > base_type;
241 typedef typename base_type::value_type value_type;
242 typedef typename base_type::value_type difference_type;
245 typedef typename base_type::operations operations;
246 typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
247 typedef typename base_type::storage_type storage_type;
248 typedef value_type value_arg_type;
251 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
254 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
255 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
260 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
262 BOOST_ASSERT(order != memory_order_consume);
263 BOOST_ASSERT(order != memory_order_acquire);
264 BOOST_ASSERT(order != memory_order_acq_rel);
266 operations::store(this->storage(), static_cast< storage_type >(v), order);
269 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
271 BOOST_ASSERT(order != memory_order_release);
272 BOOST_ASSERT(order != memory_order_acq_rel);
274 return atomics::detail::integral_truncate< value_type >(operations::load(this->storage(), order));
277 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
279 return atomics::detail::integral_truncate< value_type >(operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
282 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
284 return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
287 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
289 return atomics::detail::integral_truncate< value_type >(operations::exchange(this->storage(), static_cast< storage_type >(v), order));
292 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
294 BOOST_ASSERT(failure_order != memory_order_release);
295 BOOST_ASSERT(failure_order != memory_order_acq_rel);
296 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
298 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
301 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
303 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
306 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
308 BOOST_ASSERT(failure_order != memory_order_release);
309 BOOST_ASSERT(failure_order != memory_order_acq_rel);
310 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
312 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
315 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
317 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
320 BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
322 return atomics::detail::integral_truncate< value_type >(operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
325 BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
327 return atomics::detail::integral_truncate< value_type >(operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
330 BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
332 return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
335 // Boost.Atomic extensions
336 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
338 return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
341 BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
343 return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
346 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
348 return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
351 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
353 return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
356 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
358 return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
361 BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
363 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
366 BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
368 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
371 BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
373 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
376 BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
378 return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
381 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
383 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
386 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
388 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
391 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
393 extra_operations::opaque_negate(this->storage(), order);
396 BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
398 extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
401 BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
403 extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
406 BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
408 extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
411 BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
413 extra_operations::opaque_complement(this->storage(), order);
416 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
418 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
421 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
423 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
426 BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
428 return extra_operations::negate_and_test(this->storage(), order);
431 BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
433 return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
436 BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
438 return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
441 BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
443 return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
446 BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
448 return extra_operations::complement_and_test(this->storage(), order);
451 BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
453 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
454 return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
457 BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
459 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
460 return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
463 BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
465 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
466 return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
470 BOOST_FORCEINLINE value_type operator++(int) BOOST_NOEXCEPT
475 BOOST_FORCEINLINE value_type operator++() BOOST_NOEXCEPT
480 BOOST_FORCEINLINE value_type operator--(int) BOOST_NOEXCEPT
485 BOOST_FORCEINLINE value_type operator--() BOOST_NOEXCEPT
490 BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
495 BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
500 BOOST_FORCEINLINE value_type operator&=(value_type v) BOOST_NOEXCEPT
502 return bitwise_and(v);
505 BOOST_FORCEINLINE value_type operator|=(value_type v) BOOST_NOEXCEPT
507 return bitwise_or(v);
510 BOOST_FORCEINLINE value_type operator^=(value_type v) BOOST_NOEXCEPT
512 return bitwise_xor(v);
515 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
518 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
520 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
521 return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
523 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
527 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
529 storage_type old_value = static_cast< storage_type >(expected);
530 const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
531 expected = atomics::detail::integral_truncate< value_type >(old_value);
535 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
537 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
538 return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
540 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
544 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
546 storage_type old_value = static_cast< storage_type >(expected);
547 const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
548 expected = atomics::detail::integral_truncate< value_type >(old_value);
553 //! Implementation for bool
555 class base_atomic_ref< bool, int > :
556 public base_atomic_ref_common< bool, false >
559 typedef base_atomic_ref_common< bool, false > base_type;
562 typedef bool value_type;
565 typedef base_type::operations operations;
566 typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
567 typedef base_type::storage_type storage_type;
568 typedef value_type value_arg_type;
571 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
574 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
575 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
580 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
582 BOOST_ASSERT(order != memory_order_consume);
583 BOOST_ASSERT(order != memory_order_acquire);
584 BOOST_ASSERT(order != memory_order_acq_rel);
586 operations::store(this->storage(), static_cast< storage_type >(v), order);
589 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
591 BOOST_ASSERT(order != memory_order_release);
592 BOOST_ASSERT(order != memory_order_acq_rel);
594 return !!operations::load(this->storage(), order);
597 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
599 return !!operations::exchange(this->storage(), static_cast< storage_type >(v), order);
602 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
604 BOOST_ASSERT(failure_order != memory_order_release);
605 BOOST_ASSERT(failure_order != memory_order_acq_rel);
606 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
608 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
611 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
613 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
616 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
618 BOOST_ASSERT(failure_order != memory_order_release);
619 BOOST_ASSERT(failure_order != memory_order_acq_rel);
620 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
622 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
625 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
627 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
630 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
633 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
635 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
636 return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
638 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
642 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
644 storage_type old_value = static_cast< storage_type >(expected);
645 const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
646 expected = !!old_value;
650 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
652 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
653 return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
655 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
659 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
661 storage_type old_value = static_cast< storage_type >(expected);
662 const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
663 expected = !!old_value;
669 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
671 //! Implementation for floating point types
672 template< typename T >
673 class base_atomic_ref< T, float > :
674 public base_atomic_ref_common< T, false >
677 typedef base_atomic_ref_common< T, false > base_type;
680 typedef typename base_type::value_type value_type;
681 typedef typename base_type::value_type difference_type;
684 typedef typename base_type::operations operations;
685 typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
686 typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations;
687 typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations;
688 typedef typename base_type::storage_type storage_type;
689 typedef value_type value_arg_type;
692 typedef atomics::detail::integral_constant< bool, atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) > has_padding_bits;
693 typedef atomics::detail::integral_constant< bool, has_padding_bits::value || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
696 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
697 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
699 this->clear_padding_bits(has_padding_bits());
702 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
704 BOOST_ASSERT(order != memory_order_consume);
705 BOOST_ASSERT(order != memory_order_acquire);
706 BOOST_ASSERT(order != memory_order_acq_rel);
708 operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
711 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
713 BOOST_ASSERT(order != memory_order_release);
714 BOOST_ASSERT(order != memory_order_acq_rel);
716 return atomics::detail::bitwise_fp_cast< value_type >(operations::load(this->storage(), order));
719 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
721 return fp_operations::fetch_add(this->storage(), v, order);
724 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
726 return fp_operations::fetch_sub(this->storage(), v, order);
729 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
731 return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
734 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
736 BOOST_ASSERT(failure_order != memory_order_release);
737 BOOST_ASSERT(failure_order != memory_order_acq_rel);
738 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
740 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
743 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
745 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
748 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
750 BOOST_ASSERT(failure_order != memory_order_release);
751 BOOST_ASSERT(failure_order != memory_order_acq_rel);
752 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
754 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
757 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
759 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
762 // Boost.Atomic extensions
763 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
765 return extra_fp_operations::fetch_negate(this->storage(), order);
768 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
770 return extra_fp_operations::add(this->storage(), v, order);
773 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
775 return extra_fp_operations::sub(this->storage(), v, order);
778 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
780 return extra_fp_operations::negate(this->storage(), order);
783 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
785 extra_fp_operations::opaque_add(this->storage(), v, order);
788 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
790 extra_fp_operations::opaque_sub(this->storage(), v, order);
793 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
795 extra_fp_operations::opaque_negate(this->storage(), order);
799 BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
804 BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
809 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
812 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::false_type) const BOOST_NOEXCEPT
816 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::true_type) const BOOST_NOEXCEPT
818 storage_type old_value = operations::load(this->storage(), boost::memory_order_relaxed);
821 storage_type new_value = old_value;
822 atomics::detail::clear_tail_padding_bits< atomics::detail::value_sizeof< value_type >::value >(new_value);
823 bool res = operations::compare_exchange_weak(this->storage(), old_value, new_value, boost::memory_order_relaxed, boost::memory_order_relaxed);
824 if (BOOST_LIKELY(res))
829 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
831 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
832 return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
834 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
838 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
840 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
841 const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
842 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
846 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
848 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
849 return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
851 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
855 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
857 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
858 const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
859 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
864 #endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
867 //! Implementation for pointers to object types
868 template< typename T >
869 class base_atomic_ref< T*, void* > :
870 public base_atomic_ref_common< T*, false >
873 typedef base_atomic_ref_common< T*, false > base_type;
876 typedef typename base_type::value_type value_type;
877 typedef std::ptrdiff_t difference_type;
880 typedef typename base_type::operations operations;
881 typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
882 typedef typename base_type::storage_type storage_type;
883 typedef value_type value_arg_type;
886 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
888 // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
889 // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
890 typedef atomics::detail::uintptr_t uintptr_storage_type;
893 BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
894 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
899 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
901 BOOST_ASSERT(order != memory_order_consume);
902 BOOST_ASSERT(order != memory_order_acquire);
903 BOOST_ASSERT(order != memory_order_acq_rel);
905 operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
908 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
910 BOOST_ASSERT(order != memory_order_release);
911 BOOST_ASSERT(order != memory_order_acq_rel);
913 return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(this->storage(), order)));
916 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
918 return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
921 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
923 return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
926 BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
928 return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
931 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
933 BOOST_ASSERT(failure_order != memory_order_release);
934 BOOST_ASSERT(failure_order != memory_order_acq_rel);
935 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
937 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
940 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
942 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
945 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
947 BOOST_ASSERT(failure_order != memory_order_release);
948 BOOST_ASSERT(failure_order != memory_order_acq_rel);
949 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
951 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
954 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
956 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
959 // Boost.Atomic extensions
960 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
962 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)));
965 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
967 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)));
970 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
972 extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
975 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
977 extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
980 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
982 return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
985 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
987 return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
991 BOOST_FORCEINLINE value_type operator++(int) BOOST_NOEXCEPT
996 BOOST_FORCEINLINE value_type operator++() BOOST_NOEXCEPT
1001 BOOST_FORCEINLINE value_type operator--(int) BOOST_NOEXCEPT
1003 return fetch_sub(1);
1006 BOOST_FORCEINLINE value_type operator--() BOOST_NOEXCEPT
1011 BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
1016 BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
1021 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
1024 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
1026 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1027 return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1029 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1033 BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
1035 storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1036 const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1037 expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1041 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
1043 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1044 return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1046 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1050 BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
1052 storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1053 const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1054 expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1059 } // namespace detail
1061 template< typename T >
1063 public atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type >
1066 typedef atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type > base_type;
1067 typedef typename base_type::value_arg_type value_arg_type;
1070 typedef typename base_type::value_type value_type;
1072 BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::atomic_ref<T> requires T to be a complete type");
1073 #if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
1074 BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::atomic_ref<T> requires T to be a trivially copyable type");
1078 typedef typename base_type::storage_type storage_type;
1081 BOOST_DEFAULTED_FUNCTION(atomic_ref(atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
1082 BOOST_FORCEINLINE explicit atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
1084 // Check that referenced object alignment satisfies required alignment
1085 BOOST_ASSERT((((atomics::detail::uintptr_t)this->m_value) & (base_type::required_alignment - 1u)) == 0u);
1088 BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT
1094 BOOST_FORCEINLINE operator value_type() const BOOST_NOEXCEPT
1096 return this->load();
1099 BOOST_FORCEINLINE bool is_lock_free() const BOOST_NOEXCEPT
1101 // C++20 specifies that is_lock_free returns true if operations on *all* objects of the atomic_ref<T> type are lock-free.
1102 // This does not allow to return true or false depending on the referenced object runtime alignment. Currently, Boost.Atomic
1103 // follows this specification, although we may support runtime alignment checking in the future.
1104 return base_type::is_always_lock_free;
1107 BOOST_FORCEINLINE value_type& value() const BOOST_NOEXCEPT { return *this->m_value; }
1109 BOOST_DELETED_FUNCTION(atomic_ref& operator= (atomic_ref const&))
1112 } // namespace atomics
1113 } // namespace boost
1115 #if defined(BOOST_MSVC)
1116 #pragma warning(pop)
1119 #endif // BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_