File indexing completed on 2025-01-18 09:38:11
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_ATOMIC_NUMBER_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_ATOMIC_NUMBER_HPP
0009
0010 #include <atomic>
0011 #include <boost/histogram/detail/priority.hpp>
0012 #include <type_traits>
0013
0014 namespace boost {
0015 namespace histogram {
0016 namespace detail {
0017
0018
0019 template <class T>
0020 struct atomic_number : std::atomic<T> {
0021 static_assert(std::is_arithmetic<T>(), "");
0022
0023 using base_t = std::atomic<T>;
0024 using std::atomic<T>::atomic;
0025
0026 atomic_number() noexcept = default;
0027 atomic_number(const atomic_number& o) noexcept : std::atomic<T>{o.load()} {}
0028 atomic_number& operator=(const atomic_number& o) noexcept {
0029 this->store(o.load());
0030 return *this;
0031 }
0032
0033
0034 atomic_number& operator++() noexcept {
0035 increment_impl(static_cast<base_t&>(*this), priority<1>{});
0036 return *this;
0037 }
0038
0039
0040 atomic_number& operator+=(const T& x) noexcept {
0041 add_impl(static_cast<base_t&>(*this), x, priority<1>{});
0042 return *this;
0043 }
0044
0045
0046 atomic_number& operator*=(const T& x) noexcept {
0047 this->store(this->load() * x);
0048 return *this;
0049 }
0050
0051
0052 atomic_number& operator/=(const T& x) noexcept {
0053 this->store(this->load() / x);
0054 return *this;
0055 }
0056
0057 private:
0058
0059 template <class U = T>
0060 auto increment_impl(std::atomic<U>& a, priority<1>) noexcept -> decltype(++a) {
0061 return ++a;
0062 }
0063
0064
0065 template <class U = T>
0066 void increment_impl(std::atomic<U>&, priority<0>) noexcept {
0067 this->operator+=(static_cast<U>(1));
0068 }
0069
0070
0071 template <class U = T>
0072 static auto add_impl(std::atomic<U>& a, const U& x, priority<1>) noexcept
0073 -> decltype(a += x) {
0074 return a += x;
0075 }
0076
0077
0078 template <class U = T>
0079 static void add_impl(std::atomic<U>& a, const U& x, priority<0>) noexcept {
0080 U expected = a.load();
0081
0082
0083
0084 while (!a.compare_exchange_weak(expected, expected + x))
0085 ;
0086 }
0087 };
0088 }
0089 }
0090 }
0091
0092 #endif