]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/atomic/detail/atomic_ref_impl.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / atomic / detail / atomic_ref_impl.hpp
CommitLineData
f67539c2
TL
1/*
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)
5 *
6 * Copyright (c) 2020 Andrey Semashev
7 */
8/*!
20effc67 9 * \file atomic/detail/atomic_ref_impl.hpp
f67539c2 10 *
20effc67 11 * This header contains implementation of \c atomic_ref template.
f67539c2
TL
12 */
13
20effc67
TL
14#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_REF_IMPL_HPP_INCLUDED_
15#define BOOST_ATOMIC_DETAIL_ATOMIC_REF_IMPL_HPP_INCLUDED_
f67539c2
TL
16
17#include <cstddef>
f67539c2 18#include <boost/assert.hpp>
f67539c2
TL
19#include <boost/memory_order.hpp>
20#include <boost/atomic/detail/config.hpp>
f67539c2
TL
21#include <boost/atomic/detail/addressof.hpp>
22#include <boost/atomic/detail/storage_traits.hpp>
23#include <boost/atomic/detail/bitwise_cast.hpp>
20effc67
TL
24#include <boost/atomic/detail/core_operations.hpp>
25#include <boost/atomic/detail/wait_operations.hpp>
f67539c2 26#include <boost/atomic/detail/extra_operations.hpp>
20effc67 27#include <boost/atomic/detail/core_operations_emulated.hpp>
f67539c2
TL
28#include <boost/atomic/detail/memory_order_utils.hpp>
29#include <boost/atomic/detail/type_traits/is_signed.hpp>
f67539c2
TL
30#include <boost/atomic/detail/type_traits/alignment_of.hpp>
31#include <boost/atomic/detail/type_traits/conditional.hpp>
32#include <boost/atomic/detail/type_traits/integral_constant.hpp>
33#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
34#include <boost/atomic/detail/bitwise_fp_cast.hpp>
35#include <boost/atomic/detail/fp_operations.hpp>
36#include <boost/atomic/detail/extra_fp_operations.hpp>
37#endif
20effc67 38#include <boost/atomic/detail/header.hpp>
f67539c2
TL
39
40#ifdef BOOST_HAS_PRAGMA_ONCE
41#pragma once
42#endif
43
f67539c2
TL
44/*
45 * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
20effc67 46 * see comment for convert_memory_order_to_gcc in gcc_atomic_memory_order_utils.hpp.
f67539c2
TL
47 */
48
49namespace boost {
50namespace atomics {
51namespace detail {
52
20effc67 53template< typename T, bool Signed, bool Interprocess >
f67539c2
TL
54struct is_atomic_ref_lock_free
55{
56 typedef T value_type;
20effc67
TL
57 typedef atomics::detail::core_operations< sizeof(value_type), Signed, Interprocess > core_operations;
58 typedef typename core_operations::storage_type storage_type;
f67539c2 59
20effc67 60 static BOOST_CONSTEXPR_OR_CONST bool value = sizeof(value_type) == sizeof(storage_type) && core_operations::is_always_lock_free;
f67539c2
TL
61};
62
20effc67 63template< typename T, bool Signed, bool Interprocess >
f67539c2
TL
64class base_atomic_ref_common
65{
66public:
67 typedef T value_type;
68
69protected:
70 typedef typename atomics::detail::conditional<
20effc67
TL
71 atomics::detail::is_atomic_ref_lock_free< T, Signed, Interprocess >::value,
72 atomics::detail::core_operations< sizeof(value_type), Signed, Interprocess >,
73 atomics::detail::core_operations_emulated< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, Signed, Interprocess >
74 >::type core_operations;
75 typedef atomics::detail::wait_operations< core_operations > wait_operations;
f67539c2 76 typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
20effc67
TL
77 typedef typename core_operations::storage_type storage_type;
78 BOOST_STATIC_ASSERT_MSG(sizeof(storage_type) == sizeof(value_type), "Boost.Atomic internal error: atomic_ref storage size doesn't match the value size");
f67539c2
TL
79
80public:
20effc67
TL
81 static BOOST_CONSTEXPR_OR_CONST std::size_t required_alignment = atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment ? core_operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
82 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
83 static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
f67539c2
TL
84
85protected:
86 value_type* m_value;
87
88public:
89 BOOST_FORCEINLINE explicit base_atomic_ref_common(value_type& v) BOOST_NOEXCEPT : m_value(atomics::detail::addressof(v))
90 {
1e59de90 91 BOOST_ATOMIC_DETAIL_CLEAR_PADDING(this->m_value);
f67539c2
TL
92 }
93
20effc67
TL
94 BOOST_FORCEINLINE value_type& value() const BOOST_NOEXCEPT { return *m_value; }
95
f67539c2
TL
96protected:
97 BOOST_FORCEINLINE storage_type& storage() const BOOST_NOEXCEPT
98 {
99 return *reinterpret_cast< storage_type* >(m_value);
100 }
20effc67
TL
101
102public:
103 BOOST_FORCEINLINE bool is_lock_free() const BOOST_NOEXCEPT
104 {
105 // C++20 specifies that is_lock_free returns true if operations on *all* objects of the atomic_ref<T> type are lock-free.
106 // This does not allow to return true or false depending on the referenced object runtime alignment. Currently, Boost.Atomic
107 // follows this specification, although we may support runtime alignment checking in the future.
108 return is_always_lock_free;
109 }
110
111 BOOST_FORCEINLINE bool has_native_wait_notify() const BOOST_NOEXCEPT
112 {
113 return wait_operations::has_native_wait_notify(this->storage());
114 }
115
116 BOOST_FORCEINLINE void notify_one() const BOOST_NOEXCEPT
117 {
118 wait_operations::notify_one(this->storage());
119 }
120
121 BOOST_FORCEINLINE void notify_all() const BOOST_NOEXCEPT
122 {
123 wait_operations::notify_all(this->storage());
124 }
f67539c2
TL
125};
126
127#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
20effc67
TL
128template< typename T, bool Signed, bool Interprocess >
129BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, Signed, Interprocess >::required_alignment;
130template< typename T, bool Signed, bool Interprocess >
131BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::is_always_lock_free;
132template< typename T, bool Signed, bool Interprocess >
133BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::always_has_native_wait_notify;
f67539c2
TL
134#endif
135
136
20effc67 137template< typename T, typename Kind, bool Interprocess >
f67539c2
TL
138class base_atomic_ref;
139
1e59de90 140//! General template. Implementation for user-defined types, such as structs, and pointers to non-object types
20effc67
TL
141template< typename T, bool Interprocess >
142class base_atomic_ref< T, void, Interprocess > :
143 public base_atomic_ref_common< T, false, Interprocess >
f67539c2
TL
144{
145private:
20effc67 146 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
f67539c2
TL
147
148public:
149 typedef typename base_type::value_type value_type;
150
151protected:
20effc67
TL
152 typedef typename base_type::core_operations core_operations;
153 typedef typename base_type::wait_operations wait_operations;
f67539c2
TL
154 typedef typename base_type::storage_type storage_type;
155 typedef typename base_type::value_arg_type value_arg_type;
156
157private:
1e59de90
TL
158#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
159 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
160#else
161 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
162#endif
f67539c2
TL
163
164public:
165 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)) {})
166 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
167 {
168 }
169
170 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
171 {
172 BOOST_ASSERT(order != memory_order_consume);
173 BOOST_ASSERT(order != memory_order_acquire);
174 BOOST_ASSERT(order != memory_order_acq_rel);
175
20effc67 176 core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
f67539c2
TL
177 }
178
179 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
180 {
181 BOOST_ASSERT(order != memory_order_release);
182 BOOST_ASSERT(order != memory_order_acq_rel);
183
20effc67 184 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
f67539c2
TL
185 }
186
187 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
188 {
20effc67 189 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
f67539c2
TL
190 }
191
192 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
193 {
194 BOOST_ASSERT(failure_order != memory_order_release);
195 BOOST_ASSERT(failure_order != memory_order_acq_rel);
196 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
197
1e59de90 198 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
199 }
200
201 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
202 {
203 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
204 }
205
206 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
207 {
208 BOOST_ASSERT(failure_order != memory_order_release);
209 BOOST_ASSERT(failure_order != memory_order_acq_rel);
210 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
211
1e59de90 212 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
213 }
214
215 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
216 {
217 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
218 }
219
20effc67
TL
220 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
221 {
222 BOOST_ASSERT(order != memory_order_release);
223 BOOST_ASSERT(order != memory_order_acq_rel);
224
225 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
226 }
227
f67539c2
TL
228 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
229
230private:
231 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
232 {
20effc67 233 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
234 }
235
236 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
237 {
238 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
20effc67 239 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
240 expected = atomics::detail::bitwise_cast< value_type >(old_value);
241 return res;
242 }
243
244 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
245 {
20effc67 246 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
247 }
248
249 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
250 {
251 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
20effc67 252 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
253 expected = atomics::detail::bitwise_cast< value_type >(old_value);
254 return res;
255 }
256};
257
258
1e59de90
TL
259//! Implementation for enums
260template< typename T, bool Interprocess >
261class base_atomic_ref< T, const int, Interprocess > :
262 public base_atomic_ref_common< T, false, Interprocess >
263{
264private:
265 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
266
267public:
268 typedef typename base_type::value_type value_type;
269
270protected:
271 typedef typename base_type::core_operations core_operations;
272 typedef typename base_type::wait_operations wait_operations;
273 typedef typename base_type::storage_type storage_type;
274 typedef typename base_type::value_arg_type value_arg_type;
275
276private:
277#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
278 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
279#else
280 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
281#endif
282
283public:
284 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)) {})
285 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
286 {
287 }
288
289 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
290 {
291 BOOST_ASSERT(order != memory_order_consume);
292 BOOST_ASSERT(order != memory_order_acquire);
293 BOOST_ASSERT(order != memory_order_acq_rel);
294
295 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
296 }
297
298 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
299 {
300 BOOST_ASSERT(order != memory_order_release);
301 BOOST_ASSERT(order != memory_order_acq_rel);
302
303 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
304 }
305
306 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
307 {
308 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
309 }
310
311 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
312 {
313 BOOST_ASSERT(failure_order != memory_order_release);
314 BOOST_ASSERT(failure_order != memory_order_acq_rel);
315 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
316
317 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
318 }
319
320 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
321 {
322 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
323 }
324
325 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
326 {
327 BOOST_ASSERT(failure_order != memory_order_release);
328 BOOST_ASSERT(failure_order != memory_order_acq_rel);
329 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
330
331 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
332 }
333
334 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
335 {
336 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
337 }
338
339 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
340 {
341 BOOST_ASSERT(order != memory_order_release);
342 BOOST_ASSERT(order != memory_order_acq_rel);
343
344 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
345 }
346
347 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
348
349private:
350 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
351 {
352 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
353 }
354
355 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
356 {
357 storage_type old_value = static_cast< storage_type >(expected);
358 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
359 expected = atomics::detail::bitwise_cast< value_type >(old_value);
360 return res;
361 }
362
363 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
364 {
365 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
366 }
367
368 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
369 {
370 storage_type old_value = static_cast< storage_type >(expected);
371 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
372 expected = atomics::detail::bitwise_cast< value_type >(old_value);
373 return res;
374 }
375};
376
377
f67539c2 378//! Implementation for integers
20effc67
TL
379template< typename T, bool Interprocess >
380class base_atomic_ref< T, int, Interprocess > :
381 public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess >
f67539c2
TL
382{
383private:
20effc67 384 typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
f67539c2
TL
385
386public:
387 typedef typename base_type::value_type value_type;
388 typedef typename base_type::value_type difference_type;
389
390protected:
20effc67
TL
391 typedef typename base_type::core_operations core_operations;
392 typedef typename base_type::wait_operations wait_operations;
393 typedef atomics::detail::extra_operations< core_operations > extra_operations;
f67539c2
TL
394 typedef typename base_type::storage_type storage_type;
395 typedef value_type value_arg_type;
396
397private:
1e59de90
TL
398#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
399 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
400#else
401 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
402#endif
f67539c2
TL
403
404public:
405 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)) {})
406 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
407 {
408 }
409
410 // Standard methods
20effc67 411 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
412 {
413 BOOST_ASSERT(order != memory_order_consume);
414 BOOST_ASSERT(order != memory_order_acquire);
415 BOOST_ASSERT(order != memory_order_acq_rel);
416
20effc67 417 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
f67539c2
TL
418 }
419
420 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
421 {
422 BOOST_ASSERT(order != memory_order_release);
423 BOOST_ASSERT(order != memory_order_acq_rel);
424
20effc67 425 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
f67539c2
TL
426 }
427
20effc67 428 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 429 {
20effc67 430 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
431 }
432
20effc67 433 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 434 {
20effc67 435 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
436 }
437
20effc67 438 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 439 {
20effc67 440 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
441 }
442
20effc67 443 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
444 {
445 BOOST_ASSERT(failure_order != memory_order_release);
446 BOOST_ASSERT(failure_order != memory_order_acq_rel);
447 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
448
1e59de90 449 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
450 }
451
20effc67 452 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
453 {
454 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
455 }
456
20effc67 457 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
458 {
459 BOOST_ASSERT(failure_order != memory_order_release);
460 BOOST_ASSERT(failure_order != memory_order_acq_rel);
461 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
462
1e59de90 463 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
464 }
465
20effc67 466 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
467 {
468 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
469 }
470
20effc67 471 BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 472 {
20effc67 473 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
474 }
475
20effc67 476 BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 477 {
20effc67 478 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
479 }
480
20effc67 481 BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 482 {
20effc67 483 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
484 }
485
486 // Boost.Atomic extensions
20effc67 487 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 488 {
20effc67 489 return atomics::detail::bitwise_cast< value_type >(extra_operations::fetch_negate(this->storage(), order));
f67539c2
TL
490 }
491
20effc67 492 BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 493 {
20effc67 494 return atomics::detail::bitwise_cast< value_type >(extra_operations::fetch_complement(this->storage(), order));
f67539c2
TL
495 }
496
20effc67 497 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 498 {
20effc67 499 return atomics::detail::bitwise_cast< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
500 }
501
20effc67 502 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 503 {
20effc67 504 return atomics::detail::bitwise_cast< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
505 }
506
20effc67 507 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 508 {
20effc67 509 return atomics::detail::bitwise_cast< value_type >(extra_operations::negate(this->storage(), order));
f67539c2
TL
510 }
511
20effc67 512 BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 513 {
20effc67 514 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
515 }
516
20effc67 517 BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 518 {
20effc67 519 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
520 }
521
20effc67 522 BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 523 {
20effc67 524 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
f67539c2
TL
525 }
526
20effc67 527 BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 528 {
20effc67 529 return atomics::detail::bitwise_cast< value_type >(extra_operations::bitwise_complement(this->storage(), order));
f67539c2
TL
530 }
531
20effc67 532 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
533 {
534 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
535 }
536
20effc67 537 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
538 {
539 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
540 }
541
20effc67 542 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
543 {
544 extra_operations::opaque_negate(this->storage(), order);
545 }
546
20effc67 547 BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
548 {
549 extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
550 }
551
20effc67 552 BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
553 {
554 extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
555 }
556
20effc67 557 BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
558 {
559 extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
560 }
561
20effc67 562 BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
563 {
564 extra_operations::opaque_complement(this->storage(), order);
565 }
566
20effc67 567 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
568 {
569 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
570 }
571
20effc67 572 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
573 {
574 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
575 }
576
20effc67 577 BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
578 {
579 return extra_operations::negate_and_test(this->storage(), order);
580 }
581
20effc67 582 BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
583 {
584 return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
585 }
586
20effc67 587 BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
588 {
589 return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
590 }
591
20effc67 592 BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
593 {
594 return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
595 }
596
20effc67 597 BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
598 {
599 return extra_operations::complement_and_test(this->storage(), order);
600 }
601
20effc67 602 BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
603 {
604 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
605 return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
606 }
607
20effc67 608 BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
609 {
610 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
611 return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
612 }
613
20effc67 614 BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
615 {
616 BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
617 return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
618 }
619
620 // Operators
20effc67 621 BOOST_FORCEINLINE value_type operator++(int) const BOOST_NOEXCEPT
f67539c2
TL
622 {
623 return fetch_add(1);
624 }
625
20effc67 626 BOOST_FORCEINLINE value_type operator++() const BOOST_NOEXCEPT
f67539c2
TL
627 {
628 return add(1);
629 }
630
20effc67 631 BOOST_FORCEINLINE value_type operator--(int) const BOOST_NOEXCEPT
f67539c2
TL
632 {
633 return fetch_sub(1);
634 }
635
20effc67 636 BOOST_FORCEINLINE value_type operator--() const BOOST_NOEXCEPT
f67539c2
TL
637 {
638 return sub(1);
639 }
640
20effc67 641 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
642 {
643 return add(v);
644 }
645
20effc67 646 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
647 {
648 return sub(v);
649 }
650
20effc67 651 BOOST_FORCEINLINE value_type operator&=(value_type v) const BOOST_NOEXCEPT
f67539c2
TL
652 {
653 return bitwise_and(v);
654 }
655
20effc67 656 BOOST_FORCEINLINE value_type operator|=(value_type v) const BOOST_NOEXCEPT
f67539c2
TL
657 {
658 return bitwise_or(v);
659 }
660
20effc67 661 BOOST_FORCEINLINE value_type operator^=(value_type v) const BOOST_NOEXCEPT
f67539c2
TL
662 {
663 return bitwise_xor(v);
664 }
665
20effc67
TL
666 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
667 {
668 BOOST_ASSERT(order != memory_order_release);
669 BOOST_ASSERT(order != memory_order_acq_rel);
670
671 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
672 }
673
f67539c2
TL
674 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
675
676private:
677 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
678 {
20effc67 679 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
680 }
681
682 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
683 {
684 storage_type old_value = static_cast< storage_type >(expected);
20effc67
TL
685 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
686 expected = atomics::detail::bitwise_cast< value_type >(old_value);
f67539c2
TL
687 return res;
688 }
689
690 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
691 {
20effc67 692 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
693 }
694
695 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
696 {
697 storage_type old_value = static_cast< storage_type >(expected);
20effc67
TL
698 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
699 expected = atomics::detail::bitwise_cast< value_type >(old_value);
f67539c2
TL
700 return res;
701 }
702};
703
704//! Implementation for bool
20effc67
TL
705template< bool Interprocess >
706class base_atomic_ref< bool, int, Interprocess > :
707 public base_atomic_ref_common< bool, false, Interprocess >
f67539c2
TL
708{
709private:
20effc67 710 typedef base_atomic_ref_common< bool, false, Interprocess > base_type;
f67539c2
TL
711
712public:
713 typedef bool value_type;
714
715protected:
20effc67
TL
716 typedef typename base_type::core_operations core_operations;
717 typedef typename base_type::wait_operations wait_operations;
718 typedef typename base_type::storage_type storage_type;
f67539c2
TL
719 typedef value_type value_arg_type;
720
721private:
1e59de90
TL
722#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
723 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
724#else
725 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
726#endif
f67539c2
TL
727
728public:
729 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)) {})
730 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
731 {
732 }
733
734 // Standard methods
20effc67 735 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
736 {
737 BOOST_ASSERT(order != memory_order_consume);
738 BOOST_ASSERT(order != memory_order_acquire);
739 BOOST_ASSERT(order != memory_order_acq_rel);
740
20effc67 741 core_operations::store(this->storage(), static_cast< storage_type >(v), order);
f67539c2
TL
742 }
743
744 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
745 {
746 BOOST_ASSERT(order != memory_order_release);
747 BOOST_ASSERT(order != memory_order_acq_rel);
748
20effc67 749 return !!core_operations::load(this->storage(), order);
f67539c2
TL
750 }
751
20effc67 752 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 753 {
20effc67 754 return !!core_operations::exchange(this->storage(), static_cast< storage_type >(v), order);
f67539c2
TL
755 }
756
20effc67 757 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
758 {
759 BOOST_ASSERT(failure_order != memory_order_release);
760 BOOST_ASSERT(failure_order != memory_order_acq_rel);
761 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
762
1e59de90 763 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
764 }
765
20effc67 766 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
767 {
768 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
769 }
770
20effc67 771 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
772 {
773 BOOST_ASSERT(failure_order != memory_order_release);
774 BOOST_ASSERT(failure_order != memory_order_acq_rel);
775 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
776
1e59de90 777 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
778 }
779
20effc67 780 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
781 {
782 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
783 }
784
20effc67
TL
785 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
786 {
787 BOOST_ASSERT(order != memory_order_release);
788 BOOST_ASSERT(order != memory_order_acq_rel);
789
790 return !!wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order);
791 }
792
f67539c2
TL
793 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
794
795private:
796 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
797 {
20effc67 798 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
799 }
800
801 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
802 {
803 storage_type old_value = static_cast< storage_type >(expected);
20effc67 804 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
805 expected = !!old_value;
806 return res;
807 }
808
809 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
810 {
20effc67 811 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
812 }
813
814 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
815 {
816 storage_type old_value = static_cast< storage_type >(expected);
20effc67 817 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
818 expected = !!old_value;
819 return res;
820 }
821};
822
823
824#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
825
826//! Implementation for floating point types
20effc67
TL
827template< typename T, bool Interprocess >
828class base_atomic_ref< T, float, Interprocess > :
829 public base_atomic_ref_common< T, false, Interprocess >
f67539c2
TL
830{
831private:
20effc67 832 typedef base_atomic_ref_common< T, false, Interprocess > base_type;
f67539c2
TL
833
834public:
835 typedef typename base_type::value_type value_type;
836 typedef typename base_type::value_type difference_type;
837
838protected:
20effc67
TL
839 typedef typename base_type::core_operations core_operations;
840 typedef typename base_type::wait_operations wait_operations;
841 typedef atomics::detail::extra_operations< core_operations > extra_operations;
842 typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations;
843 typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations;
f67539c2
TL
844 typedef typename base_type::storage_type storage_type;
845 typedef value_type value_arg_type;
846
847private:
1e59de90
TL
848#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
849 typedef atomics::detail::integral_constant< bool, atomics::detail::value_size_of< value_type >::value != sizeof(storage_type) > has_padding_bits;
850#endif
851#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
852 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
853#else
854 typedef atomics::detail::integral_constant< bool, has_padding_bits::value || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
855#endif
f67539c2
TL
856
857public:
858 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)) {})
859 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
860 {
1e59de90
TL
861 // We only need to call clear_padding_bits if the compiler does not implement
862 // BOOST_ATOMIC_DETAIL_CLEAR_PADDING, which is called in the base class constructor.
863#if defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
f67539c2 864 this->clear_padding_bits(has_padding_bits());
1e59de90 865#endif // defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
f67539c2
TL
866 }
867
20effc67 868 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
869 {
870 BOOST_ASSERT(order != memory_order_consume);
871 BOOST_ASSERT(order != memory_order_acquire);
872 BOOST_ASSERT(order != memory_order_acq_rel);
873
20effc67 874 core_operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
f67539c2
TL
875 }
876
877 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
878 {
879 BOOST_ASSERT(order != memory_order_release);
880 BOOST_ASSERT(order != memory_order_acq_rel);
881
20effc67 882 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::load(this->storage(), order));
f67539c2
TL
883 }
884
20effc67 885 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
886 {
887 return fp_operations::fetch_add(this->storage(), v, order);
888 }
889
20effc67 890 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
891 {
892 return fp_operations::fetch_sub(this->storage(), v, order);
893 }
894
20effc67 895 BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 896 {
20effc67 897 return atomics::detail::bitwise_fp_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
f67539c2
TL
898 }
899
20effc67 900 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
901 {
902 BOOST_ASSERT(failure_order != memory_order_release);
903 BOOST_ASSERT(failure_order != memory_order_acq_rel);
904 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
905
1e59de90 906 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
907 }
908
20effc67 909 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
910 {
911 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
912 }
913
20effc67 914 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
915 {
916 BOOST_ASSERT(failure_order != memory_order_release);
917 BOOST_ASSERT(failure_order != memory_order_acq_rel);
918 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
919
1e59de90 920 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
921 }
922
20effc67 923 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
924 {
925 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
926 }
927
928 // Boost.Atomic extensions
20effc67 929 BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
930 {
931 return extra_fp_operations::fetch_negate(this->storage(), order);
932 }
933
20effc67 934 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
935 {
936 return extra_fp_operations::add(this->storage(), v, order);
937 }
938
20effc67 939 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
940 {
941 return extra_fp_operations::sub(this->storage(), v, order);
942 }
943
20effc67 944 BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
945 {
946 return extra_fp_operations::negate(this->storage(), order);
947 }
948
20effc67 949 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
950 {
951 extra_fp_operations::opaque_add(this->storage(), v, order);
952 }
953
20effc67 954 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
955 {
956 extra_fp_operations::opaque_sub(this->storage(), v, order);
957 }
958
20effc67 959 BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
960 {
961 extra_fp_operations::opaque_negate(this->storage(), order);
962 }
963
964 // Operators
20effc67 965 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
966 {
967 return add(v);
968 }
969
20effc67 970 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
971 {
972 return sub(v);
973 }
974
20effc67
TL
975 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
976 {
977 BOOST_ASSERT(order != memory_order_release);
978 BOOST_ASSERT(order != memory_order_acq_rel);
979
980 return atomics::detail::bitwise_fp_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(old_val), order));
981 }
982
f67539c2
TL
983 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
984
985private:
1e59de90 986#if defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
f67539c2
TL
987 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::false_type) const BOOST_NOEXCEPT
988 {
989 }
990
991 BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::true_type) const BOOST_NOEXCEPT
992 {
1e59de90 993 atomics::detail::clear_tail_padding_bits< atomics::detail::value_size_of< value_type >::value >(this->storage());
f67539c2 994 }
1e59de90 995#endif // defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
f67539c2
TL
996
997 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
998 {
20effc67 999 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);
f67539c2
TL
1000 }
1001
1002 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
1003 {
1004 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
20effc67 1005 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
1006 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1007 return res;
1008 }
1009
1010 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
1011 {
20effc67 1012 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);
f67539c2
TL
1013 }
1014
1015 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
1016 {
1017 storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
20effc67 1018 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
1019 expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1020 return res;
1021 }
1022};
1023
1024#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
1025
1026
1027//! Implementation for pointers to object types
20effc67
TL
1028template< typename T, bool Interprocess >
1029class base_atomic_ref< T*, void*, Interprocess > :
1030 public base_atomic_ref_common< T*, false, Interprocess >
f67539c2
TL
1031{
1032private:
20effc67 1033 typedef base_atomic_ref_common< T*, false, Interprocess > base_type;
f67539c2
TL
1034
1035public:
1036 typedef typename base_type::value_type value_type;
1037 typedef std::ptrdiff_t difference_type;
1038
1039protected:
20effc67
TL
1040 typedef typename base_type::core_operations core_operations;
1041 typedef typename base_type::wait_operations wait_operations;
1042 typedef atomics::detail::extra_operations< core_operations > extra_operations;
f67539c2
TL
1043 typedef typename base_type::storage_type storage_type;
1044 typedef value_type value_arg_type;
1045
1046private:
1e59de90
TL
1047#if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
1048 typedef atomics::detail::true_type cxchg_use_bitwise_cast;
1049#else
1050 typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
1051#endif
f67539c2
TL
1052
1053public:
1054 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)) {})
1055 BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
1056 {
1057 }
1058
1059 // Standard methods
20effc67 1060 BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
1061 {
1062 BOOST_ASSERT(order != memory_order_consume);
1063 BOOST_ASSERT(order != memory_order_acquire);
1064 BOOST_ASSERT(order != memory_order_acq_rel);
1065
20effc67 1066 core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
f67539c2
TL
1067 }
1068
1069 BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1070 {
1071 BOOST_ASSERT(order != memory_order_release);
1072 BOOST_ASSERT(order != memory_order_acq_rel);
1073
20effc67 1074 return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
f67539c2
TL
1075 }
1076
20effc67 1077 BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1078 {
20effc67 1079 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
f67539c2
TL
1080 }
1081
20effc67 1082 BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1083 {
20effc67 1084 return atomics::detail::bitwise_cast< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
f67539c2
TL
1085 }
1086
20effc67 1087 BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1088 {
20effc67 1089 return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
f67539c2
TL
1090 }
1091
20effc67 1092 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
1093 {
1094 BOOST_ASSERT(failure_order != memory_order_release);
1095 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1096 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1097
1e59de90 1098 return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
1099 }
1100
20effc67 1101 BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
1102 {
1103 return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
1104 }
1105
20effc67 1106 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
f67539c2
TL
1107 {
1108 BOOST_ASSERT(failure_order != memory_order_release);
1109 BOOST_ASSERT(failure_order != memory_order_acq_rel);
1110 BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1111
1e59de90 1112 return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
f67539c2
TL
1113 }
1114
20effc67 1115 BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2
TL
1116 {
1117 return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
1118 }
1119
1120 // Boost.Atomic extensions
20effc67 1121 BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1122 {
20effc67 1123 return atomics::detail::bitwise_cast< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
f67539c2
TL
1124 }
1125
20effc67 1126 BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1127 {
20effc67 1128 return atomics::detail::bitwise_cast< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order));
f67539c2
TL
1129 }
1130
20effc67 1131 BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1132 {
20effc67 1133 extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
f67539c2
TL
1134 }
1135
20effc67 1136 BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1137 {
20effc67 1138 extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
f67539c2
TL
1139 }
1140
20effc67 1141 BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1142 {
20effc67 1143 return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
f67539c2
TL
1144 }
1145
20effc67 1146 BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
f67539c2 1147 {
20effc67 1148 return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v * sizeof(T)), order);
f67539c2
TL
1149 }
1150
1151 // Operators
20effc67 1152 BOOST_FORCEINLINE value_type operator++(int) const BOOST_NOEXCEPT
f67539c2
TL
1153 {
1154 return fetch_add(1);
1155 }
1156
20effc67 1157 BOOST_FORCEINLINE value_type operator++() const BOOST_NOEXCEPT
f67539c2
TL
1158 {
1159 return add(1);
1160 }
1161
20effc67 1162 BOOST_FORCEINLINE value_type operator--(int) const BOOST_NOEXCEPT
f67539c2
TL
1163 {
1164 return fetch_sub(1);
1165 }
1166
20effc67 1167 BOOST_FORCEINLINE value_type operator--() const BOOST_NOEXCEPT
f67539c2
TL
1168 {
1169 return sub(1);
1170 }
1171
20effc67 1172 BOOST_FORCEINLINE value_type operator+=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
1173 {
1174 return add(v);
1175 }
1176
20effc67 1177 BOOST_FORCEINLINE value_type operator-=(difference_type v) const BOOST_NOEXCEPT
f67539c2
TL
1178 {
1179 return sub(v);
1180 }
1181
20effc67
TL
1182 BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
1183 {
1184 BOOST_ASSERT(order != memory_order_release);
1185 BOOST_ASSERT(order != memory_order_acq_rel);
1186
1187 return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
1188 }
1189
f67539c2
TL
1190 BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
1191
1192private:
1193 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
1194 {
20effc67 1195 return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
1196 }
1197
1198 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
1199 {
20effc67
TL
1200 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
1201 const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1202 expected = atomics::detail::bitwise_cast< value_type >(old_value);
f67539c2
TL
1203 return res;
1204 }
1205
1206 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
1207 {
20effc67 1208 return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
f67539c2
TL
1209 }
1210
1211 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
1212 {
20effc67
TL
1213 storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
1214 const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
1215 expected = atomics::detail::bitwise_cast< value_type >(old_value);
f67539c2
TL
1216 return res;
1217 }
1218};
1219
1220} // namespace detail
f67539c2
TL
1221} // namespace atomics
1222} // namespace boost
1223
20effc67 1224#include <boost/atomic/detail/footer.hpp>
f67539c2 1225
20effc67 1226#endif // BOOST_ATOMIC_DETAIL_ATOMIC_REF_IMPL_HPP_INCLUDED_