Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:49

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2011 Helge Bahmann
0007  * Copyright (c) 2013 Tim Blechmann
0008  * Copyright (c) 2014-2020 Andrey Semashev
0009  */
0010 /*!
0011  * \file   atomic/detail/atomic_impl.hpp
0012  *
0013  * This header contains implementation of \c atomic template.
0014  */
0015 
0016 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
0017 #define BOOST_ATOMIC_DETAIL_ATOMIC_IMPL_HPP_INCLUDED_
0018 
0019 #include <cstddef>
0020 #include <boost/assert.hpp>
0021 #include <boost/memory_order.hpp>
0022 #include <boost/atomic/detail/config.hpp>
0023 #include <boost/atomic/detail/intptr.hpp>
0024 #include <boost/atomic/detail/storage_traits.hpp>
0025 #include <boost/atomic/detail/bitwise_cast.hpp>
0026 #include <boost/atomic/detail/integral_conversions.hpp>
0027 #include <boost/atomic/detail/core_operations.hpp>
0028 #include <boost/atomic/detail/wait_operations.hpp>
0029 #include <boost/atomic/detail/extra_operations.hpp>
0030 #include <boost/atomic/detail/memory_order_utils.hpp>
0031 #include <boost/atomic/detail/aligned_variable.hpp>
0032 #include <boost/atomic/detail/type_traits/is_signed.hpp>
0033 #include <boost/atomic/detail/type_traits/is_nothrow_default_constructible.hpp>
0034 #include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
0035 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
0036 #include <boost/atomic/detail/type_traits/conditional.hpp>
0037 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
0038 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
0039 #include <boost/atomic/detail/bitwise_fp_cast.hpp>
0040 #include <boost/atomic/detail/fp_operations.hpp>
0041 #include <boost/atomic/detail/extra_fp_operations.hpp>
0042 #endif
0043 #include <boost/atomic/detail/header.hpp>
0044 
0045 #ifdef BOOST_HAS_PRAGMA_ONCE
0046 #pragma once
0047 #endif
0048 
0049 #if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT) && !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_BITWISE_CAST)
0050 #define BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR BOOST_CONSTEXPR
0051 #else
0052 #define BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR
0053 #endif
0054 
0055 /*
0056  * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
0057  *                      see comment for convert_memory_order_to_gcc in gcc_atomic_memory_order_utils.hpp.
0058  */
0059 
0060 namespace boost {
0061 namespace atomics {
0062 namespace detail {
0063 
0064 template< typename T, bool Signed, bool Interprocess >
0065 class base_atomic_common
0066 {
0067 public:
0068     typedef T value_type;
0069 
0070 protected:
0071     typedef atomics::detail::core_operations< storage_size_of< value_type >::value, Signed, Interprocess > core_operations;
0072     typedef atomics::detail::wait_operations< core_operations > wait_operations;
0073     typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
0074     typedef typename core_operations::storage_type storage_type;
0075 
0076 protected:
0077     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;
0078 
0079 public:
0080     static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
0081     static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
0082 
0083 protected:
0084     BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(storage_alignment, storage_type, m_storage);
0085 
0086 public:
0087     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT base_atomic_common() BOOST_NOEXCEPT : m_storage()
0088     {
0089     }
0090 
0091     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic_common(storage_type v) BOOST_NOEXCEPT : m_storage(v)
0092     {
0093     }
0094 
0095     BOOST_FORCEINLINE value_type& value() BOOST_NOEXCEPT { return *reinterpret_cast< value_type* >(&m_storage); }
0096     BOOST_FORCEINLINE value_type volatile& value() volatile BOOST_NOEXCEPT { return *reinterpret_cast< volatile value_type* >(&m_storage); }
0097     BOOST_FORCEINLINE value_type const& value() const BOOST_NOEXCEPT { return *reinterpret_cast< const value_type* >(&m_storage); }
0098     BOOST_FORCEINLINE value_type const volatile& value() const volatile BOOST_NOEXCEPT { return *reinterpret_cast< const volatile value_type* >(&m_storage); }
0099 
0100 protected:
0101     BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return m_storage; }
0102     BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return m_storage; }
0103     BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return m_storage; }
0104     BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return m_storage; }
0105 
0106 public:
0107     BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
0108     {
0109         // C++17 requires all instances of atomic<> return a value consistent with is_always_lock_free here.
0110         // Boost.Atomic also enforces the required alignment of the atomic storage, so we can always return is_always_lock_free.
0111         return is_always_lock_free;
0112     }
0113 
0114     BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
0115     {
0116         return wait_operations::has_native_wait_notify(this->storage());
0117     }
0118 
0119     BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
0120     {
0121         wait_operations::notify_one(this->storage());
0122     }
0123 
0124     BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
0125     {
0126         wait_operations::notify_all(this->storage());
0127     }
0128 };
0129 
0130 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0131 template< typename T, bool Signed, bool Interprocess >
0132 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::is_always_lock_free;
0133 template< typename T, bool Signed, bool Interprocess >
0134 BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::always_has_native_wait_notify;
0135 #endif
0136 
0137 
0138 template< typename T, bool Interprocess, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
0139 class base_atomic_generic;
0140 
0141 template< typename T, bool Interprocess >
0142 class base_atomic_generic< T, Interprocess, true > :
0143     public base_atomic_common< T, false, Interprocess >
0144 {
0145 private:
0146     typedef base_atomic_common< T, false, Interprocess > base_type;
0147 
0148 protected:
0149     typedef typename base_type::storage_type storage_type;
0150     typedef typename base_type::value_arg_type value_arg_type;
0151 
0152 public:
0153     BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
0154     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT :
0155         base_type(atomics::detail::bitwise_cast< storage_type >(v))
0156     {
0157     }
0158 };
0159 
0160 template< typename T, bool Interprocess >
0161 class base_atomic_generic< T, Interprocess, false > :
0162     public base_atomic_common< T, false, Interprocess >
0163 {
0164 private:
0165     typedef base_atomic_common< T, false, Interprocess > base_type;
0166 
0167 public:
0168     typedef typename base_type::value_type value_type;
0169 
0170 protected:
0171     typedef typename base_type::storage_type storage_type;
0172     typedef typename base_type::value_arg_type value_arg_type;
0173 
0174 public:
0175     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT :
0176         base_type(atomics::detail::bitwise_cast< storage_type >(v))
0177     {
0178     }
0179 };
0180 
0181 
0182 template< typename T, typename Kind, bool Interprocess >
0183 class base_atomic;
0184 
0185 //! General template. Implementation for user-defined types, such as structs, and pointers to non-object types
0186 template< typename T, bool Interprocess >
0187 class base_atomic< T, void, Interprocess > :
0188     public base_atomic_generic< T, Interprocess >
0189 {
0190 private:
0191     typedef base_atomic_generic< T, Interprocess > base_type;
0192 
0193 public:
0194     typedef typename base_type::value_type value_type;
0195 
0196 protected:
0197     typedef typename base_type::core_operations core_operations;
0198     typedef typename base_type::wait_operations wait_operations;
0199     typedef typename base_type::storage_type storage_type;
0200     typedef typename base_type::value_arg_type value_arg_type;
0201 
0202 private:
0203 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0204     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0205 #else
0206     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0207 #endif
0208 
0209 public:
0210     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR base_atomic() BOOST_NOEXCEPT_IF(atomics::detail::is_nothrow_default_constructible< value_type >::value) : base_type()
0211     {
0212     }
0213 
0214     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v)
0215     {
0216     }
0217 
0218     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0219     {
0220         BOOST_ASSERT(order != memory_order_consume);
0221         BOOST_ASSERT(order != memory_order_acquire);
0222         BOOST_ASSERT(order != memory_order_acq_rel);
0223 
0224         core_operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
0225     }
0226 
0227     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0228     {
0229         BOOST_ASSERT(order != memory_order_release);
0230         BOOST_ASSERT(order != memory_order_acq_rel);
0231 
0232         return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
0233     }
0234 
0235     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0236     {
0237         return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
0238     }
0239 
0240     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0241     {
0242         BOOST_ASSERT(failure_order != memory_order_release);
0243         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0244         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0245 
0246         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0247     }
0248 
0249     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0250     {
0251         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0252     }
0253 
0254     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0255     {
0256         BOOST_ASSERT(failure_order != memory_order_release);
0257         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0258         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0259 
0260         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0261     }
0262 
0263     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0264     {
0265         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0266     }
0267 
0268     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0269     {
0270         BOOST_ASSERT(order != memory_order_release);
0271         BOOST_ASSERT(order != memory_order_acq_rel);
0272 
0273         return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< storage_type >(old_val), order));
0274     }
0275 
0276     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
0277     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
0278 
0279 private:
0280     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
0281     {
0282         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0283     }
0284 
0285     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
0286     {
0287         storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
0288         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0289         expected = atomics::detail::bitwise_cast< value_type >(old_value);
0290         return res;
0291     }
0292 
0293     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
0294     {
0295         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0296     }
0297 
0298     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
0299     {
0300         storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
0301         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
0302         expected = atomics::detail::bitwise_cast< value_type >(old_value);
0303         return res;
0304     }
0305 };
0306 
0307 
0308 //! Implementation for enums
0309 template< typename T, bool Interprocess >
0310 class base_atomic< T, const int, Interprocess > :
0311     public base_atomic_common< T, false, Interprocess >
0312 {
0313 private:
0314     typedef base_atomic_common< T, false, Interprocess > base_type;
0315 
0316 public:
0317     typedef typename base_type::value_type value_type;
0318 
0319 protected:
0320     typedef typename base_type::core_operations core_operations;
0321     typedef typename base_type::wait_operations wait_operations;
0322     typedef typename base_type::storage_type storage_type;
0323     typedef typename base_type::value_arg_type value_arg_type;
0324 
0325 private:
0326 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0327     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0328 #else
0329     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0330 #endif
0331 
0332 public:
0333     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
0334     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v))
0335     {
0336     }
0337 
0338     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0339     {
0340         BOOST_ASSERT(order != memory_order_consume);
0341         BOOST_ASSERT(order != memory_order_acquire);
0342         BOOST_ASSERT(order != memory_order_acq_rel);
0343 
0344         core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0345     }
0346 
0347     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0348     {
0349         BOOST_ASSERT(order != memory_order_release);
0350         BOOST_ASSERT(order != memory_order_acq_rel);
0351 
0352         return atomics::detail::bitwise_cast< value_type >(core_operations::load(this->storage(), order));
0353     }
0354 
0355     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0356     {
0357         return atomics::detail::bitwise_cast< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
0358     }
0359 
0360     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0361     {
0362         BOOST_ASSERT(failure_order != memory_order_release);
0363         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0364         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0365 
0366         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0367     }
0368 
0369     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0370     {
0371         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0372     }
0373 
0374     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0375     {
0376         BOOST_ASSERT(failure_order != memory_order_release);
0377         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0378         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0379 
0380         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0381     }
0382 
0383     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0384     {
0385         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0386     }
0387 
0388     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0389     {
0390         BOOST_ASSERT(order != memory_order_release);
0391         BOOST_ASSERT(order != memory_order_acq_rel);
0392 
0393         return atomics::detail::bitwise_cast< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
0394     }
0395 
0396     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
0397     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
0398 
0399 private:
0400     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
0401     {
0402         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0403     }
0404 
0405     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
0406     {
0407         storage_type old_value = static_cast< storage_type >(expected);
0408         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0409         expected = atomics::detail::bitwise_cast< value_type >(old_value);
0410         return res;
0411     }
0412 
0413     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
0414     {
0415         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0416     }
0417 
0418     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
0419     {
0420         storage_type old_value = static_cast< storage_type >(expected);
0421         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0422         expected = atomics::detail::bitwise_cast< value_type >(old_value);
0423         return res;
0424     }
0425 };
0426 
0427 
0428 //! Implementation for integers
0429 template< typename T, bool Interprocess >
0430 class base_atomic< T, int, Interprocess > :
0431     public base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess >
0432 {
0433 private:
0434     typedef base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
0435 
0436 public:
0437     typedef typename base_type::value_type value_type;
0438     typedef value_type difference_type;
0439 
0440 protected:
0441     typedef typename base_type::core_operations core_operations;
0442     typedef typename base_type::wait_operations wait_operations;
0443     typedef atomics::detail::extra_operations< core_operations > extra_operations;
0444     typedef typename base_type::storage_type storage_type;
0445     typedef value_type value_arg_type;
0446 
0447 private:
0448 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0449     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0450 #else
0451     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0452 #endif
0453 
0454 public:
0455     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
0456     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
0457 
0458     // Standard methods
0459     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0460     {
0461         BOOST_ASSERT(order != memory_order_consume);
0462         BOOST_ASSERT(order != memory_order_acquire);
0463         BOOST_ASSERT(order != memory_order_acq_rel);
0464 
0465         core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0466     }
0467 
0468     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0469     {
0470         BOOST_ASSERT(order != memory_order_release);
0471         BOOST_ASSERT(order != memory_order_acq_rel);
0472 
0473         return atomics::detail::integral_truncate< value_type >(core_operations::load(this->storage(), order));
0474     }
0475 
0476     BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0477     {
0478         return atomics::detail::integral_truncate< value_type >(core_operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
0479     }
0480 
0481     BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0482     {
0483         return atomics::detail::integral_truncate< value_type >(core_operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
0484     }
0485 
0486     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0487     {
0488         return atomics::detail::integral_truncate< value_type >(core_operations::exchange(this->storage(), static_cast< storage_type >(v), order));
0489     }
0490 
0491     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0492     {
0493         BOOST_ASSERT(failure_order != memory_order_release);
0494         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0495         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0496 
0497         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0498     }
0499 
0500     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0501     {
0502         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0503     }
0504 
0505     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0506     {
0507         BOOST_ASSERT(failure_order != memory_order_release);
0508         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0509         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0510 
0511         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0512     }
0513 
0514     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0515     {
0516         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0517     }
0518 
0519     BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0520     {
0521         return atomics::detail::integral_truncate< value_type >(core_operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
0522     }
0523 
0524     BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0525     {
0526         return atomics::detail::integral_truncate< value_type >(core_operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
0527     }
0528 
0529     BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0530     {
0531         return atomics::detail::integral_truncate< value_type >(core_operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
0532     }
0533 
0534     // Boost.Atomic extensions
0535     BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0536     {
0537         return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
0538     }
0539 
0540     BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0541     {
0542         return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
0543     }
0544 
0545     BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0546     {
0547         return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
0548     }
0549 
0550     BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0551     {
0552         return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
0553     }
0554 
0555     BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0556     {
0557         return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
0558     }
0559 
0560     BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0561     {
0562         return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
0563     }
0564 
0565     BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0566     {
0567         return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
0568     }
0569 
0570     BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0571     {
0572         return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
0573     }
0574 
0575     BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0576     {
0577         return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
0578     }
0579 
0580     BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0581     {
0582         extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
0583     }
0584 
0585     BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0586     {
0587         extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
0588     }
0589 
0590     BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0591     {
0592         extra_operations::opaque_negate(this->storage(), order);
0593     }
0594 
0595     BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0596     {
0597         extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
0598     }
0599 
0600     BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0601     {
0602         extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
0603     }
0604 
0605     BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0606     {
0607         extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
0608     }
0609 
0610     BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0611     {
0612         extra_operations::opaque_complement(this->storage(), order);
0613     }
0614 
0615     BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0616     {
0617         return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
0618     }
0619 
0620     BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0621     {
0622         return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
0623     }
0624 
0625     BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0626     {
0627         return extra_operations::negate_and_test(this->storage(), order);
0628     }
0629 
0630     BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0631     {
0632         return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
0633     }
0634 
0635     BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0636     {
0637         return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
0638     }
0639 
0640     BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0641     {
0642         return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
0643     }
0644 
0645     BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0646     {
0647         return extra_operations::complement_and_test(this->storage(), order);
0648     }
0649 
0650     BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0651     {
0652         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0653         return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
0654     }
0655 
0656     BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0657     {
0658         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0659         return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
0660     }
0661 
0662     BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0663     {
0664         BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
0665         return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
0666     }
0667 
0668     // Operators
0669     BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
0670     {
0671         return fetch_add(1);
0672     }
0673 
0674     BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
0675     {
0676         return add(1);
0677     }
0678 
0679     BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
0680     {
0681         return fetch_sub(1);
0682     }
0683 
0684     BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
0685     {
0686         return sub(1);
0687     }
0688 
0689     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
0690     {
0691         return add(v);
0692     }
0693 
0694     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
0695     {
0696         return sub(v);
0697     }
0698 
0699     BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT
0700     {
0701         return bitwise_and(v);
0702     }
0703 
0704     BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT
0705     {
0706         return bitwise_or(v);
0707     }
0708 
0709     BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT
0710     {
0711         return bitwise_xor(v);
0712     }
0713 
0714     BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0715     {
0716         BOOST_ASSERT(order != memory_order_release);
0717         BOOST_ASSERT(order != memory_order_acq_rel);
0718 
0719         return atomics::detail::integral_truncate< value_type >(wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order));
0720     }
0721 
0722     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
0723     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
0724 
0725 private:
0726     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
0727     {
0728         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0729     }
0730 
0731     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
0732     {
0733         storage_type old_value = static_cast< storage_type >(expected);
0734         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0735         expected = atomics::detail::integral_truncate< value_type >(old_value);
0736         return res;
0737     }
0738 
0739     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
0740     {
0741         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0742     }
0743 
0744     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
0745     {
0746         storage_type old_value = static_cast< storage_type >(expected);
0747         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0748         expected = atomics::detail::integral_truncate< value_type >(old_value);
0749         return res;
0750     }
0751 };
0752 
0753 //! Implementation for bool
0754 template< bool Interprocess >
0755 class base_atomic< bool, int, Interprocess > :
0756     public base_atomic_common< bool, false, Interprocess >
0757 {
0758 private:
0759     typedef base_atomic_common< bool, false, Interprocess > base_type;
0760 
0761 public:
0762     typedef typename base_type::value_type value_type;
0763 
0764 protected:
0765     typedef typename base_type::core_operations core_operations;
0766     typedef typename base_type::wait_operations wait_operations;
0767     typedef typename base_type::storage_type storage_type;
0768     typedef value_type value_arg_type;
0769 
0770 private:
0771 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0772     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0773 #else
0774     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
0775 #endif
0776 
0777 public:
0778     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
0779     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
0780 
0781     // Standard methods
0782     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0783     {
0784         BOOST_ASSERT(order != memory_order_consume);
0785         BOOST_ASSERT(order != memory_order_acquire);
0786         BOOST_ASSERT(order != memory_order_acq_rel);
0787 
0788         core_operations::store(this->storage(), static_cast< storage_type >(v), order);
0789     }
0790 
0791     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0792     {
0793         BOOST_ASSERT(order != memory_order_release);
0794         BOOST_ASSERT(order != memory_order_acq_rel);
0795 
0796         return !!core_operations::load(this->storage(), order);
0797     }
0798 
0799     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0800     {
0801         return !!core_operations::exchange(this->storage(), static_cast< storage_type >(v), order);
0802     }
0803 
0804     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0805     {
0806         BOOST_ASSERT(failure_order != memory_order_release);
0807         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0808         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0809 
0810         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0811     }
0812 
0813     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0814     {
0815         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0816     }
0817 
0818     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0819     {
0820         BOOST_ASSERT(failure_order != memory_order_release);
0821         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0822         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0823 
0824         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0825     }
0826 
0827     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0828     {
0829         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0830     }
0831 
0832     BOOST_FORCEINLINE value_type wait(value_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0833     {
0834         BOOST_ASSERT(order != memory_order_release);
0835         BOOST_ASSERT(order != memory_order_acq_rel);
0836 
0837         return !!wait_operations::wait(this->storage(), static_cast< storage_type >(old_val), order);
0838     }
0839 
0840     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
0841     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
0842 
0843 private:
0844     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
0845     {
0846         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0847     }
0848 
0849     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
0850     {
0851         storage_type old_value = static_cast< storage_type >(expected);
0852         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0853         expected = !!old_value;
0854         return res;
0855     }
0856 
0857     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
0858     {
0859         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
0860     }
0861 
0862     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
0863     {
0864         storage_type old_value = static_cast< storage_type >(expected);
0865         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
0866         expected = !!old_value;
0867         return res;
0868     }
0869 };
0870 
0871 
0872 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
0873 
0874 //! Implementation for floating point types
0875 template< typename T, bool Interprocess >
0876 class base_atomic< T, float, Interprocess > :
0877     public base_atomic_common< T, false, Interprocess >
0878 {
0879 private:
0880     typedef base_atomic_common< T, false, Interprocess > base_type;
0881 
0882 public:
0883     typedef typename base_type::value_type value_type;
0884     typedef value_type difference_type;
0885 
0886 protected:
0887     typedef typename base_type::core_operations core_operations;
0888     typedef typename base_type::wait_operations wait_operations;
0889     typedef atomics::detail::extra_operations< core_operations > extra_operations;
0890     typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations;
0891     typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations;
0892     typedef typename base_type::storage_type storage_type;
0893     typedef value_type value_arg_type;
0894 
0895 private:
0896 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
0897     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
0898 #else
0899     typedef atomics::detail::integral_constant< bool,
0900         atomics::detail::value_size_of< value_type >::value != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment
0901     > cxchg_use_bitwise_cast;
0902 #endif
0903 
0904 public:
0905     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
0906     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT :
0907         base_type(atomics::detail::bitwise_fp_cast< storage_type >(v))
0908     {
0909     }
0910 
0911     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0912     {
0913         BOOST_ASSERT(order != memory_order_consume);
0914         BOOST_ASSERT(order != memory_order_acquire);
0915         BOOST_ASSERT(order != memory_order_acq_rel);
0916 
0917         core_operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
0918     }
0919 
0920     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0921     {
0922         BOOST_ASSERT(order != memory_order_release);
0923         BOOST_ASSERT(order != memory_order_acq_rel);
0924 
0925         return atomics::detail::bitwise_fp_cast< value_type >(core_operations::load(this->storage(), order));
0926     }
0927 
0928     BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0929     {
0930         return fp_operations::fetch_add(this->storage(), v, order);
0931     }
0932 
0933     BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0934     {
0935         return fp_operations::fetch_sub(this->storage(), v, order);
0936     }
0937 
0938     BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0939     {
0940         return atomics::detail::bitwise_fp_cast< value_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
0941     }
0942 
0943     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0944     {
0945         BOOST_ASSERT(failure_order != memory_order_release);
0946         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0947         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0948 
0949         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0950     }
0951 
0952     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0953     {
0954         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
0955     }
0956 
0957     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
0958     {
0959         BOOST_ASSERT(failure_order != memory_order_release);
0960         BOOST_ASSERT(failure_order != memory_order_acq_rel);
0961         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
0962 
0963         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
0964     }
0965 
0966     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0967     {
0968         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
0969     }
0970 
0971     // Boost.Atomic extensions
0972     BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0973     {
0974         return extra_fp_operations::fetch_negate(this->storage(), order);
0975     }
0976 
0977     BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0978     {
0979         return extra_fp_operations::add(this->storage(), v, order);
0980     }
0981 
0982     BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0983     {
0984         return extra_fp_operations::sub(this->storage(), v, order);
0985     }
0986 
0987     BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0988     {
0989         return extra_fp_operations::negate(this->storage(), order);
0990     }
0991 
0992     BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0993     {
0994         extra_fp_operations::opaque_add(this->storage(), v, order);
0995     }
0996 
0997     BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0998     {
0999         extra_fp_operations::opaque_sub(this->storage(), v, order);
1000     }
1001 
1002     BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1003     {
1004         extra_fp_operations::opaque_negate(this->storage(), order);
1005     }
1006 
1007     // Operators
1008     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
1009     {
1010         return add(v);
1011     }
1012 
1013     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
1014     {
1015         return sub(v);
1016     }
1017 
1018     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1019     {
1020         BOOST_ASSERT(order != memory_order_release);
1021         BOOST_ASSERT(order != memory_order_acq_rel);
1022 
1023         return atomics::detail::bitwise_fp_cast< value_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(old_val), order));
1024     }
1025 
1026     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
1027     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
1028 
1029 private:
1030     BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
1031     {
1032         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1033     }
1034 
1035     BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
1036     {
1037         storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
1038         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1039         expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1040         return res;
1041     }
1042 
1043     BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
1044     {
1045         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1046     }
1047 
1048     BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
1049     {
1050         storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
1051         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
1052         expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
1053         return res;
1054     }
1055 };
1056 
1057 #endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
1058 
1059 
1060 //! Implementation for pointers to object types
1061 template< typename T, bool Interprocess >
1062 class base_atomic< T*, void*, Interprocess > :
1063     public base_atomic_common< T*, false, Interprocess >
1064 {
1065 private:
1066     typedef base_atomic_common< T*, false, Interprocess > base_type;
1067 
1068 public:
1069     typedef typename base_type::value_type value_type;
1070     typedef std::ptrdiff_t difference_type;
1071 
1072 protected:
1073     typedef typename base_type::core_operations core_operations;
1074     typedef typename base_type::wait_operations wait_operations;
1075     typedef atomics::detail::extra_operations< core_operations > extra_operations;
1076     typedef typename base_type::storage_type storage_type;
1077     typedef value_type value_arg_type;
1078 
1079 private:
1080 #if !defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) || !defined(BOOST_ATOMIC_NO_CLEAR_PADDING)
1081     typedef atomics::detail::true_type cxchg_use_bitwise_cast;
1082 #else
1083     typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= core_operations::storage_alignment > cxchg_use_bitwise_cast;
1084 #endif
1085 
1086     // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
1087     // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
1088     typedef atomics::detail::uintptr_t uintptr_storage_type;
1089 
1090 public:
1091     BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
1092     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_ATOMIC_CTOR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT :
1093         base_type(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
1094     {
1095     }
1096 
1097     // Standard methods
1098     BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1099     {
1100         BOOST_ASSERT(order != memory_order_consume);
1101         BOOST_ASSERT(order != memory_order_acquire);
1102         BOOST_ASSERT(order != memory_order_acq_rel);
1103 
1104         core_operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
1105     }
1106 
1107     BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1108     {
1109         BOOST_ASSERT(order != memory_order_release);
1110         BOOST_ASSERT(order != memory_order_acq_rel);
1111 
1112         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::load(this->storage(), order)));
1113     }
1114 
1115     BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1116     {
1117         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1118     }
1119 
1120     BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1121     {
1122         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1123     }
1124 
1125     BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1126     {
1127         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(core_operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
1128     }
1129 
1130     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1131     {
1132         BOOST_ASSERT(failure_order != memory_order_release);
1133         BOOST_ASSERT(failure_order != memory_order_acq_rel);
1134         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1135 
1136         return compare_exchange_strong_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
1137     }
1138 
1139     BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1140     {
1141         return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
1142     }
1143 
1144     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
1145     {
1146         BOOST_ASSERT(failure_order != memory_order_release);
1147         BOOST_ASSERT(failure_order != memory_order_acq_rel);
1148         BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
1149 
1150         return compare_exchange_weak_impl(expected, desired, success_order, failure_order, cxchg_use_bitwise_cast());
1151     }
1152 
1153     BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1154     {
1155         return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
1156     }
1157 
1158     // Boost.Atomic extensions
1159     BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1160     {
1161         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1162     }
1163 
1164     BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1165     {
1166         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
1167     }
1168 
1169     BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1170     {
1171         extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1172     }
1173 
1174     BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1175     {
1176         extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1177     }
1178 
1179     BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1180     {
1181         return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1182     }
1183 
1184     BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1185     {
1186         return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
1187     }
1188 
1189     // Operators
1190     BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
1191     {
1192         return fetch_add(1);
1193     }
1194 
1195     BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
1196     {
1197         return add(1);
1198     }
1199 
1200     BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
1201     {
1202         return fetch_sub(1);
1203     }
1204 
1205     BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
1206     {
1207         return sub(1);
1208     }
1209 
1210     BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
1211     {
1212         return add(v);
1213     }
1214 
1215     BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
1216     {
1217         return sub(v);
1218     }
1219 
1220     BOOST_FORCEINLINE value_type wait(value_arg_type old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1221     {
1222         BOOST_ASSERT(order != memory_order_release);
1223         BOOST_ASSERT(order != memory_order_acq_rel);
1224 
1225         return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(wait_operations::wait(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(old_val), order)));
1226     }
1227 
1228     BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
1229     BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
1230 
1231 private:
1232     BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
1233     {
1234         return core_operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1235     }
1236 
1237     BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
1238     {
1239         storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1240         const bool res = core_operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1241         expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1242         return res;
1243     }
1244 
1245     BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
1246     {
1247         return core_operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1248     }
1249 
1250     BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
1251     {
1252         storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
1253         const bool res = core_operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
1254         expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
1255         return res;
1256     }
1257 };
1258 
1259 } // namespace detail
1260 } // namespace atomics
1261 } // namespace boost
1262 
1263 #include <boost/atomic/detail/footer.hpp>
1264 
1265 #endif // BOOST_ATOMIC_DETAIL_ATOMIC_IMPl_HPP_INCLUDED_