HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
atomic.hpp
1// Copyright Take Vos 2019-2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "architecture.hpp"
8#include <atomic>
9#include <thread>
10#include <chrono>
11
12hi_warning_push();
13// C26403: Reset or explicitly delete and owner<T> pointer '...' (r.3).: ...
14// The static analyser is very confused about the get_or_make() function.
15hi_warning_ignore_msvc(26403);
16
17namespace hi::inline v1 {
18
21template<typename T>
22T fetch_max(std::atomic<T> &lhs, T rhs, std::memory_order order) noexcept
23{
24 auto expected = lhs.load(order);
25 while (expected < rhs) {
26 if (lhs.compare_exchange_weak(expected, rhs, order)) {
27 return expected;
28 }
29 }
30 return expected;
31}
32
35template<typename T>
36T fetch_min(std::atomic<T> &lhs, T rhs, std::memory_order order) noexcept
37{
38 auto expected = lhs.load(order);
39 while (rhs < expected) {
40 if (lhs.compare_exchange_weak(expected, rhs, order)) {
41 return expected;
42 }
43 }
44 return expected;
45}
46
47template<typename T>
49public:
50 using element_type = T;
51 using pointer = element_type *;
52 using reference = element_type &;
53
54 ~atomic_unique_ptr() noexcept
55 {
56 delete _pointer.load(std::memory_order_relaxed);
57 }
58
59 constexpr atomic_unique_ptr() noexcept = default;
60 atomic_unique_ptr(atomic_unique_ptr const &) = delete;
61 atomic_unique_ptr &operator=(atomic_unique_ptr const &) = delete;
62
63 atomic_unique_ptr(atomic_unique_ptr &&other) noexcept : _pointer(other._pointer.exchange(nullptr)) {}
64
65 atomic_unique_ptr &operator=(atomic_unique_ptr &&other) noexcept
66 {
67 hi_return_on_self_assignment(other);
68
69 delete _pointer.exchange(other._pointer.exchange(nullptr));
70 return *this;
71 }
72
73 constexpr atomic_unique_ptr(std::nullptr_t) noexcept : _pointer(nullptr) {}
74
75 atomic_unique_ptr &operator=(std::nullptr_t) noexcept
76 {
77 delete _pointer.exchange(nullptr);
78 return *this;
79 }
80
81 constexpr atomic_unique_ptr(pointer other) noexcept : _pointer(other) {}
82
83 atomic_unique_ptr &operator=(pointer other) noexcept
84 {
85 delete _pointer.exchange(other);
86 return *this;
87 }
88
91 [[nodiscard]] pointer get(std::memory_order order = std::memory_order::seq_cst) const noexcept
92 {
93 return _pointer.load(order);
94 }
95
107 template<typename... Args>
108 [[nodiscard]] reference get_or_make(Args &&...args) noexcept
109 {
110 auto expected = _pointer.load(std::memory_order::acquire);
111 if (expected != nullptr) {
112 return *expected;
113 }
114
115 auto desired = new element_type(std::forward<Args>(args)...);
116 if (not _pointer.compare_exchange_strong(expected, desired, std::memory_order::release, std::memory_order::acquire)) {
117 // Lost construction race.
118 delete desired;
119 return *expected;
120 } else {
121 return *desired;
122 }
123 }
124
125private:
126 std::atomic<pointer> _pointer;
127};
128
129} // namespace hi::inline v1
130
131hi_warning_pop();
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
Definition atomic.hpp:48
reference get_or_make(Args &&...args) noexcept
Get or make an object.
Definition atomic.hpp:108
pointer get(std::memory_order order=std::memory_order::seq_cst) const noexcept
Get the raw pointer.
Definition atomic.hpp:91
Definition concepts.hpp:36
Definition concepts.hpp:39