• 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-2020 Andrey Semashev
9  */
10 /*!
11  * \file   atomic/detail/atomic_impl.hpp
12  *
13  * This header contains implementation of \c atomic template.
14  */
15 
16 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
18 
19 #include <cstddef>
20 #include <boost/assert.hpp>
21 #include <boost/memory_order.hpp>
22 #include <boost/atomic/detail/config.hpp>
23 #include <boost/atomic/detail/intptr.hpp>
24 #include <boost/atomic/detail/storage_traits.hpp>
25 #include <boost/atomic/detail/bitwise_cast.hpp>
26 #include <boost/atomic/detail/integral_conversions.hpp>
27 #include <boost/atomic/detail/core_operations.hpp>
28 #include <boost/atomic/detail/wait_operations.hpp>
29 #include <boost/atomic/detail/extra_operations.hpp>
30 #include <boost/atomic/detail/memory_order_utils.hpp>
31 #include <boost/atomic/detail/aligned_variable.hpp>
32 #include <boost/atomic/detail/type_traits/is_signed.hpp>
33 #include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
34 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
35 #include <boost/atomic/detail/type_traits/conditional.hpp>
36 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
37 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
38 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
39 #include <boost/atomic/detail/fp_operations.hpp>
40 #include <boost/atomic/detail/extra_fp_operations.hpp>
41 #endif
42 #include <boost/atomic/detail/header.hpp>
43 
44 #ifdef BOOST_HAS_PRAGMA_ONCE
45 #pragma once
46 #endif
47 
48 /*
49  * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
50  *                      see comment for convert_memory_order_to_gcc in gcc_atomic_memory_order_utils.hpp.
51  */
52 
53 namespace boost {
54 namespace atomics {
55 namespace detail {
56 
57 template< typename T, bool Signed, bool Interprocess >
58 class base_atomic_common
59 {
60 public:
61     typedef T value_type;
62 
63 protected:
64     typedef atomics::detail::core_operations< storage_size_of< value_type >::value, Signed, Interprocess > core_operations;
65     typedef atomics::detail::wait_operations< core_operations > wait_operations;
66     typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
67     typedef typename core_operations::storage_type storage_type;
68 
69 protected:
70     static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment ? core_operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
71 
72 public:
73     static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
74     static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
75 
76 protected:
77     BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(storage_alignment, storage_type, m_storage);
78 
79 public:
BOOST_DEFAULTED_FUNCTION(base_atomic_common ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})80     BOOST_DEFAULTED_FUNCTION(base_atomic_common() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
81     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic_common(storage_type v) BOOST_NOEXCEPT : m_storage(v)
82     {
83     }
84 
value()85     BOOST_FORCEINLINE value_type& value() BOOST_NOEXCEPT { return *reinterpret_cast< value_type* >(&m_storage); }
value()86     BOOST_FORCEINLINE value_type volatile& value() volatile BOOST_NOEXCEPT { return *reinterpret_cast< volatile value_type* >(&m_storage); }
value() const87     BOOST_FORCEINLINE value_type const& value() const BOOST_NOEXCEPT { return *reinterpret_cast< const value_type* >(&m_storage); }
value() const88     BOOST_FORCEINLINE value_type const volatile& value() const volatile BOOST_NOEXCEPT { return *reinterpret_cast< const volatile value_type* >(&m_storage); }
89 
90 protected:
storage()91     BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return m_storage; }
storage()92     BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return m_storage; }
storage() const93     BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return m_storage; }
storage() const94     BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return m_storage; }
95 
96 public:
is_lock_free() const97     BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
98     {
99         // C++17 requires all instances of atomic<> return a value consistent with is_always_lock_free here.
100         // Boost.Atomic also enforces the required alignment of the atomic storage, so we can always return is_always_lock_free.
101         return is_always_lock_free;
102     }
103 
has_native_wait_notify() const104     BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
105     {
106         return wait_operations::has_native_wait_notify(this->storage());
107     }
108 
notify_one()109     BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
110     {
111         wait_operations::notify_one(this->storage());
112     }
113 
notify_all()114     BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
115     {
116         wait_operations::notify_all(this->storage());
117     }
118 };
119 
120 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
121 template< typename T, bool Signed, bool Interprocess >
122 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::is_always_lock_free;
123 template< typename T, bool Signed, bool Interprocess >
124 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::always_has_native_wait_notify;
125 #endif
126 
127 
128 template< typename T, bool Interprocess, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
129 class base_atomic_generic;
130 
131 template< typename T, bool Interprocess >
132 class base_atomic_generic< T, Interprocess, true > :
133     public base_atomic_common< T, false, Interprocess >
134 {
135 private:
136     typedef base_atomic_common< T, false, Interprocess > base_type;
137 
138 protected:
139     typedef typename base_type::storage_type storage_type;
140     typedef typename base_type::value_arg_type value_arg_type;
141 
142 public:
BOOST_DEFAULTED_FUNCTION(base_atomic_generic ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})143     BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
144     BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
145     {
146     }
147 };
148 
149 template< typename T, bool Interprocess >
150 class base_atomic_generic< T, Interprocess, false > :
151     public base_atomic_common< T, false, Interprocess >
152 {
153 private:
154     typedef base_atomic_common< T, false, Interprocess > base_type;
155 
156 public:
157     typedef typename base_type::value_type value_type;
158 
159 protected:
160     typedef typename base_type::storage_type storage_type;
161     typedef typename base_type::value_arg_type value_arg_type;
162 
163 public:
base_atomic_generic(value_arg_type v=value_type ())164     BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
165     {
166     }
167 };
168 
169 
170 template< typename T, typename Kind, bool Interprocess >
171 class base_atomic;
172 
173 //! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
174 template< typename T, bool Interprocess >
175 class base_atomic< T, void, Interprocess > :
176     public base_atomic_generic< T, Interprocess >
177 {
178 private:
179     typedef base_atomic_generic< T, Interprocess > base_type;
180 
181 public:
182     typedef typename base_type::value_type value_type;
183 
184 protected:
185     typedef typename base_type::core_operations core_operations;
186     typedef typename base_type::wait_operations wait_operations;
187     typedef typename base_type::storage_type storage_type;
188     typedef typename base_type::value_arg_type value_arg_type;
189 
190 private:
191     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
192 
193 public:
BOOST_DEFAULTED_FUNCTION(base_atomic ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})194     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
195     BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v)
196     {
197     }
198 
store(value_arg_type v,memory_order order=memory_order_seq_cst)199     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
200     {
201         BOOST_ASSERT(order != memory_order_consume);
202         BOOST_ASSERT(order != memory_order_acquire);
203         BOOST_ASSERT(order != memory_order_acq_rel);
204 
205         core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
206     }
207 
load(memory_order order=memory_order_seq_cst) const208     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
209     {
210         BOOST_ASSERT(order != memory_order_release);
211         BOOST_ASSERT(order != memory_order_acq_rel);
212 
213         return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
214     }
215 
exchange(value_arg_type v,memory_order order=memory_order_seq_cst)216     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
217     {
218         return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
219     }
220 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)221     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
222     {
223         BOOST_ASSERT(failure_order != memory_order_release);
224         BOOST_ASSERT(failure_order != memory_order_acq_rel);
225         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
226 
227         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
228     }
229 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)230     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
231     {
232         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
233     }
234 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)235     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
236     {
237         BOOST_ASSERT(failure_order != memory_order_release);
238         BOOST_ASSERT(failure_order != memory_order_acq_rel);
239         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
240 
241         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
242     }
243 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)244     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
245     {
246         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
247     }
248 
wait(value_arg_type old_val,memory_order order=memory_order_seq_cst) const249     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
250     {
251         BOOST_ASSERT(order != memory_order_release);
252         BOOST_ASSERT(order != memory_order_acq_rel);
253 
254         return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), 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::false_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::false_type) volatile BOOST_NOEXCEPT
262     {
263 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
264         return core_operations::compare_exchange_strong(this->storage(), 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::true_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::true_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::true_type) volatile BOOST_NOEXCEPT
271     {
272         storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
273         const bool res = core_operations::compare_exchange_strong(this->storage(), 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::false_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::false_type) volatile BOOST_NOEXCEPT
279     {
280 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
281         return core_operations::compare_exchange_weak(this->storage(), 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::true_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::true_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::true_type) volatile BOOST_NOEXCEPT
288     {
289         storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
290         const bool res = core_operations::compare_exchange_weak(this->storage(), 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, bool Interprocess >
299 class base_atomic< T, int, Interprocess > :
300     public base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess >
301 {
302 private:
303     typedef base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
304 
305 public:
306     typedef typename base_type::value_type value_type;
307     typedef value_type difference_type;
308 
309 protected:
310     typedef typename base_type::core_operations core_operations;
311     typedef typename base_type::wait_operations wait_operations;
312     typedef atomics::detail::extra_operations< core_operations > extra_operations;
313     typedef typename base_type::storage_type storage_type;
314     typedef value_type value_arg_type;
315 
316 private:
317     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
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_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(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         core_operations::store(this->storage(), static_cast< 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 >(core_operations::load(this->storage(), 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 >(core_operations::fetch_add(this->storage(), static_cast< 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 >(core_operations::fetch_sub(this->storage(), static_cast< 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 >(core_operations::exchange(this->storage(), static_cast< 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, use_bitwise_cast());
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, use_bitwise_cast());
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 >(core_operations::fetch_and(this->storage(), static_cast< 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 >(core_operations::fetch_or(this->storage(), static_cast< 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 >(core_operations::fetch_xor(this->storage(), static_cast< 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(this->storage(), 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(this->storage(), 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), static_cast< 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(this->storage(), order);
478     }
479 
add_and_test(difference_type v,memory_order order=memory_order_seq_cst)480     BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
481     {
482         return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
483     }
484 
sub_and_test(difference_type v,memory_order order=memory_order_seq_cst)485     BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
486     {
487         return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
488     }
489 
negate_and_test(memory_order order=memory_order_seq_cst)490     BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
491     {
492         return extra_operations::negate_and_test(this->storage(), order);
493     }
494 
and_and_test(value_arg_type v,memory_order order=memory_order_seq_cst)495     BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
496     {
497         return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
498     }
499 
or_and_test(value_arg_type v,memory_order order=memory_order_seq_cst)500     BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
501     {
502         return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
503     }
504 
xor_and_test(value_arg_type v,memory_order order=memory_order_seq_cst)505     BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
506     {
507         return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
508     }
509 
complement_and_test(memory_order order=memory_order_seq_cst)510     BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
511     {
512         return extra_operations::complement_and_test(this->storage(), order);
513     }
514 
bit_test_and_set(unsigned int bit_number,memory_order order=memory_order_seq_cst)515     BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
516     {
517         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
518         return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
519     }
520 
bit_test_and_reset(unsigned int bit_number,memory_order order=memory_order_seq_cst)521     BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
522     {
523         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
524         return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
525     }
526 
bit_test_and_complement(unsigned int bit_number,memory_order order=memory_order_seq_cst)527     BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
528     {
529         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
530         return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
531     }
532 
533     // Operators
operator ++(int)534     BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
535     {
536         return fetch_add(1);
537     }
538 
operator ++()539     BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
540     {
541         return add(1);
542     }
543 
operator --(int)544     BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
545     {
546         return fetch_sub(1);
547     }
548 
operator --()549     BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
550     {
551         return sub(1);
552     }
553 
operator +=(difference_type v)554     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
555     {
556         return add(v);
557     }
558 
operator -=(difference_type v)559     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
560     {
561         return sub(v);
562     }
563 
operator &=(value_type v)564     BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT
565     {
566         return bitwise_and(v);
567     }
568 
operator |=(value_type v)569     BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT
570     {
571         return bitwise_or(v);
572     }
573 
operator ^=(value_type v)574     BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT
575     {
576         return bitwise_xor(v);
577     }
578 
wait(value_type old_val,memory_order order=memory_order_seq_cst) const579     BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
580     {
581         BOOST_ASSERT(order != memory_order_release);
582         BOOST_ASSERT(order != memory_order_acq_rel);
583 
584         return atomics::detail::integral_truncate< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
585     }
586 
587     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
588     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
589 
590 private:
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)591     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
592     {
593 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
594         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
595 #else
596         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
597 #endif
598     }
599 
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)600     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
601     {
602         storage_type old_value = static_cast< storage_type >(expected);
603         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
604         expected = atomics::detail::integral_truncate< value_type >(old_value);
605         return res;
606     }
607 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)608     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
609     {
610 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
611         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
612 #else
613         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
614 #endif
615     }
616 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)617     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
618     {
619         storage_type old_value = static_cast< storage_type >(expected);
620         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
621         expected = atomics::detail::integral_truncate< value_type >(old_value);
622         return res;
623     }
624 };
625 
626 //! Implementation for bool
627 template< bool Interprocess >
628 class base_atomic< bool, int, Interprocess > :
629     public base_atomic_common< bool, false, Interprocess >
630 {
631 private:
632     typedef base_atomic_common< bool, false, Interprocess > base_type;
633 
634 public:
635     typedef typename base_type::value_type value_type;
636 
637 protected:
638     typedef typename base_type::core_operations core_operations;
639     typedef typename base_type::wait_operations wait_operations;
640     typedef typename base_type::storage_type storage_type;
641     typedef value_type value_arg_type;
642 
643 private:
644     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
645 
646 public:
BOOST_DEFAULTED_FUNCTION(base_atomic ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})647     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
648     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
649 
650     // Standard methods
store(value_arg_type v,memory_order order=memory_order_seq_cst)651     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
652     {
653         BOOST_ASSERT(order != memory_order_consume);
654         BOOST_ASSERT(order != memory_order_acquire);
655         BOOST_ASSERT(order != memory_order_acq_rel);
656 
657         core_operations::store(this->storage(), static_cast< storage_type >(v), order);
658     }
659 
load(memory_order order=memory_order_seq_cst) const660     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
661     {
662         BOOST_ASSERT(order != memory_order_release);
663         BOOST_ASSERT(order != memory_order_acq_rel);
664 
665         return !!core_operations::load(this->storage(), order);
666     }
667 
exchange(value_arg_type v,memory_order order=memory_order_seq_cst)668     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
669     {
670         return !!core_operations::exchange(this->storage(), static_cast< storage_type >(v), order);
671     }
672 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)673     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
674     {
675         BOOST_ASSERT(failure_order != memory_order_release);
676         BOOST_ASSERT(failure_order != memory_order_acq_rel);
677         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
678 
679         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
680     }
681 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)682     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
683     {
684         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
685     }
686 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)687     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
688     {
689         BOOST_ASSERT(failure_order != memory_order_release);
690         BOOST_ASSERT(failure_order != memory_order_acq_rel);
691         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
692 
693         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
694     }
695 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)696     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
697     {
698         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
699     }
700 
wait(value_type old_val,memory_order order=memory_order_seq_cst) const701     BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
702     {
703         BOOST_ASSERT(order != memory_order_release);
704         BOOST_ASSERT(order != memory_order_acq_rel);
705 
706         return !!wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order);
707     }
708 
709     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
710     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
711 
712 private:
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)713     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
714     {
715 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
716         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
717 #else
718         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
719 #endif
720     }
721 
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)722     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
723     {
724         storage_type old_value = static_cast< storage_type >(expected);
725         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
726         expected = !!old_value;
727         return res;
728     }
729 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)730     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
731     {
732 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
733         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
734 #else
735         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
736 #endif
737     }
738 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)739     BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
740     {
741         storage_type old_value = static_cast< storage_type >(expected);
742         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
743         expected = !!old_value;
744         return res;
745     }
746 };
747 
748 
749 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
750 
751 //! Implementation for floating point types
752 template< typename T, bool Interprocess >
753 class base_atomic< T, float, Interprocess > :
754     public base_atomic_common< T, false, Interprocess >
755 {
756 private:
757     typedef base_atomic_common< T, false, Interprocess > base_type;
758 
759 public:
760     typedef typename base_type::value_type value_type;
761     typedef value_type difference_type;
762 
763 protected:
764     typedef typename base_type::core_operations core_operations;
765     typedef typename base_type::wait_operations wait_operations;
766     typedef atomics::detail::extra_operations< core_operations > extra_operations;
767     typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations;
768     typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations;
769     typedef typename base_type::storage_type storage_type;
770     typedef value_type value_arg_type;
771 
772 private:
773     typedef atomics::detail::integral_constant< bool,
774         atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment
775     > use_bitwise_cast;
776 
777 public:
BOOST_DEFAULTED_FUNCTION(base_atomic ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})778     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
779     BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
780 
store(value_arg_type v,memory_order order=memory_order_seq_cst)781     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
782     {
783         BOOST_ASSERT(order != memory_order_consume);
784         BOOST_ASSERT(order != memory_order_acquire);
785         BOOST_ASSERT(order != memory_order_acq_rel);
786 
787         core_operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
788     }
789 
load(memory_order order=memory_order_seq_cst) const790     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
791     {
792         BOOST_ASSERT(order != memory_order_release);
793         BOOST_ASSERT(order != memory_order_acq_rel);
794 
795         return atomics::detail::bitwise_fp_cast< value_type >(core_operations::load(this->storage(), order));
796     }
797 
fetch_add(difference_type v,memory_order order=memory_order_seq_cst)798     BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
799     {
800         return fp_operations::fetch_add(this->storage(), v, order);
801     }
802 
fetch_sub(difference_type v,memory_order order=memory_order_seq_cst)803     BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
804     {
805         return fp_operations::fetch_sub(this->storage(), v, order);
806     }
807 
exchange(value_arg_type v,memory_order order=memory_order_seq_cst)808     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
809     {
810         return atomics::detail::bitwise_fp_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
811     }
812 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)813     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
814     {
815         BOOST_ASSERT(failure_order != memory_order_release);
816         BOOST_ASSERT(failure_order != memory_order_acq_rel);
817         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
818 
819         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
820     }
821 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)822     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
823     {
824         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
825     }
826 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)827     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
828     {
829         BOOST_ASSERT(failure_order != memory_order_release);
830         BOOST_ASSERT(failure_order != memory_order_acq_rel);
831         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
832 
833         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
834     }
835 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)836     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
837     {
838         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
839     }
840 
841     // Boost.Atomic extensions
fetch_negate(memory_order order=memory_order_seq_cst)842     BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
843     {
844         return extra_fp_operations::fetch_negate(this->storage(), order);
845     }
846 
add(difference_type v,memory_order order=memory_order_seq_cst)847     BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
848     {
849         return extra_fp_operations::add(this->storage(), v, order);
850     }
851 
sub(difference_type v,memory_order order=memory_order_seq_cst)852     BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
853     {
854         return extra_fp_operations::sub(this->storage(), v, order);
855     }
856 
negate(memory_order order=memory_order_seq_cst)857     BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
858     {
859         return extra_fp_operations::negate(this->storage(), order);
860     }
861 
opaque_add(difference_type v,memory_order order=memory_order_seq_cst)862     BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
863     {
864         extra_fp_operations::opaque_add(this->storage(), v, order);
865     }
866 
opaque_sub(difference_type v,memory_order order=memory_order_seq_cst)867     BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
868     {
869         extra_fp_operations::opaque_sub(this->storage(), v, order);
870     }
871 
opaque_negate(memory_order order=memory_order_seq_cst)872     BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
873     {
874         extra_fp_operations::opaque_negate(this->storage(), order);
875     }
876 
877     // Operators
operator +=(difference_type v)878     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
879     {
880         return add(v);
881     }
882 
operator -=(difference_type v)883     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
884     {
885         return sub(v);
886     }
887 
wait(value_arg_type old_val,memory_order order=memory_order_seq_cst) const888     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
889     {
890         BOOST_ASSERT(order != memory_order_release);
891         BOOST_ASSERT(order != memory_order_acq_rel);
892 
893         return atomics::detail::bitwise_fp_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(old_val), order));
894     }
895 
896     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
897     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
898 
899 private:
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)900     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
901     {
902 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
903         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
904 #else
905         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
906 #endif
907     }
908 
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)909     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
910     {
911         storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
912         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
913         expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
914         return res;
915     }
916 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)917     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
918     {
919 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
920         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
921 #else
922         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
923 #endif
924     }
925 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)926     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
927     {
928         storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
929         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
930         expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
931         return res;
932     }
933 };
934 
935 #endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
936 
937 
938 //! Implementation for pointers to object types
939 template< typename T, bool Interprocess >
940 class base_atomic< T*, void*, Interprocess > :
941     public base_atomic_common< T*, false, Interprocess >
942 {
943 private:
944     typedef base_atomic_common< T*, false, Interprocess > base_type;
945 
946 public:
947     typedef typename base_type::value_type value_type;
948     typedef std::ptrdiff_t difference_type;
949 
950 protected:
951     typedef typename base_type::core_operations core_operations;
952     typedef typename base_type::wait_operations wait_operations;
953     typedef atomics::detail::extra_operations< core_operations > extra_operations;
954     typedef typename base_type::storage_type storage_type;
955     typedef value_type value_arg_type;
956 
957 private:
958     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > use_bitwise_cast;
959 
960     // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
961     // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
962     typedef atomics::detail::uintptr_t uintptr_storage_type;
963 
964 public:
BOOST_DEFAULTED_FUNCTION(base_atomic ()BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL,BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL{})965     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
966     BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
967     {
968     }
969 
970     // Standard methods
store(value_arg_type v,memory_order order=memory_order_seq_cst)971     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
972     {
973         BOOST_ASSERT(order != memory_order_consume);
974         BOOST_ASSERT(order != memory_order_acquire);
975         BOOST_ASSERT(order != memory_order_acq_rel);
976 
977         core_operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
978     }
979 
load(memory_order order=memory_order_seq_cst) const980     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
981     {
982         BOOST_ASSERT(order != memory_order_release);
983         BOOST_ASSERT(order != memory_order_acq_rel);
984 
985         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::load(this->storage(), order)));
986     }
987 
fetch_add(difference_type v,memory_order order=memory_order_seq_cst)988     BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
989     {
990         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
991     }
992 
fetch_sub(difference_type v,memory_order order=memory_order_seq_cst)993     BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
994     {
995         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
996     }
997 
exchange(value_type v,memory_order order=memory_order_seq_cst)998     BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
999     {
1000         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
1001     }
1002 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)1003     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1004     {
1005         BOOST_ASSERT(failure_order != memory_order_release);
1006         BOOST_ASSERT(failure_order != memory_order_acq_rel);
1007         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1008 
1009         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
1010     }
1011 
compare_exchange_strong(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)1012     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1013     {
1014         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
1015     }
1016 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order)1017     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1018     {
1019         BOOST_ASSERT(failure_order != memory_order_release);
1020         BOOST_ASSERT(failure_order != memory_order_acq_rel);
1021         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1022 
1023         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
1024     }
1025 
compare_exchange_weak(value_type & expected,value_arg_type desired,memory_order order=memory_order_seq_cst)1026     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1027     {
1028         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
1029     }
1030 
1031     // Boost.Atomic extensions
add(difference_type v,memory_order order=memory_order_seq_cst)1032     BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1033     {
1034         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1035     }
1036 
sub(difference_type v,memory_order order=memory_order_seq_cst)1037     BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1038     {
1039         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1040     }
1041 
opaque_add(difference_type v,memory_order order=memory_order_seq_cst)1042     BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1043     {
1044         extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1045     }
1046 
opaque_sub(difference_type v,memory_order order=memory_order_seq_cst)1047     BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1048     {
1049         extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1050     }
1051 
add_and_test(difference_type v,memory_order order=memory_order_seq_cst)1052     BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1053     {
1054         return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1055     }
1056 
sub_and_test(difference_type v,memory_order order=memory_order_seq_cst)1057     BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1058     {
1059         return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1060     }
1061 
1062     // Operators
operator ++(int)1063     BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
1064     {
1065         return fetch_add(1);
1066     }
1067 
operator ++()1068     BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
1069     {
1070         return add(1);
1071     }
1072 
operator --(int)1073     BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
1074     {
1075         return fetch_sub(1);
1076     }
1077 
operator --()1078     BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
1079     {
1080         return sub(1);
1081     }
1082 
operator +=(difference_type v)1083     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
1084     {
1085         return add(v);
1086     }
1087 
operator -=(difference_type v)1088     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
1089     {
1090         return sub(v);
1091     }
1092 
wait(value_arg_type old_val,memory_order order=memory_order_seq_cst) const1093     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1094     {
1095         BOOST_ASSERT(order != memory_order_release);
1096         BOOST_ASSERT(order != memory_order_acq_rel);
1097 
1098         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(old_val), order)));
1099     }
1100 
1101     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
1102     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
1103 
1104 private:
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)1105     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
1106     {
1107 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1108         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1109 #else
1110         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1111 #endif
1112     }
1113 
compare_exchange_strong_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)1114     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
1115     {
1116         storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1117         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1118         expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1119         return res;
1120     }
1121 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::false_type)1122     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
1123     {
1124 #if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
1125         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1126 #else
1127         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
1128 #endif
1129     }
1130 
compare_exchange_weak_impl(value_type & expected,value_arg_type desired,memory_order success_order,memory_order failure_order,atomics::detail::true_type)1131     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
1132     {
1133         storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1134         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1135         expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1136         return res;
1137     }
1138 };
1139 
1140 } // namespace detail
1141 } // namespace atomics
1142 } // namespace boost
1143 
1144 #include <boost/atomic/detail/footer.hpp>
1145 
1146 #endif // BOOST_ATOMIC_DETAIL_ATOMIC_IMPl_HPP_INCLUDED_
1147