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