• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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