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