atomic_floating.h 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #pragma once
  2. #include <type_traits>
  3. #include <atomic>
  4. namespace prometheus {
  5. template <typename FloatingType>
  6. inline std::atomic<FloatingType>& atomic_add_for_floating_types(std::atomic<FloatingType>& value,
  7. const FloatingType& add) {
  8. FloatingType desired;
  9. FloatingType expected = value.load(std::memory_order_relaxed);
  10. do {
  11. desired = expected + add;
  12. } while (!value.compare_exchange_weak(expected, desired));
  13. return value;
  14. }
  15. template <typename FloatingType, class = typename std::enable_if<std::is_floating_point<FloatingType>::value, int>::type>
  16. inline std::atomic<FloatingType>& operator++(std::atomic<FloatingType>& value) {
  17. return atomic_add_for_floating_types(value, 1.0);
  18. }
  19. template <typename FloatingType, class = typename std::enable_if<std::is_floating_point<FloatingType>::value, int>::type>
  20. inline std::atomic<FloatingType>& operator+=(std::atomic<FloatingType>& value, const FloatingType& val) {
  21. return atomic_add_for_floating_types(value, val);
  22. }
  23. template <typename FloatingType, class = typename std::enable_if<std::is_floating_point<FloatingType>::value, int>::type>
  24. inline std::atomic<FloatingType>& operator--(std::atomic<FloatingType>& value) {
  25. return atomic_add_for_floating_types(value, -1.0);
  26. }
  27. template <typename FloatingType, class = typename std::enable_if<std::is_floating_point<FloatingType>::value, int>::type>
  28. inline std::atomic<FloatingType>& operator-=(std::atomic<FloatingType>& value, const FloatingType& val) {
  29. return atomic_add_for_floating_types(value, -val);
  30. }
  31. }