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