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
12namespace hi::inline v1 {
13
16template<typename T>
17T fetch_max(std::atomic<T> &lhs, T rhs, std::memory_order order) noexcept
18{
19 auto expected = lhs.load(order);
20 while (expected < rhs) {
21 if (lhs.compare_exchange_weak(expected, rhs, order)) {
22 return expected;
23 }
24 }
25 return expected;
26}
27
30template<typename T>
31T fetch_min(std::atomic<T> &lhs, T rhs, std::memory_order order) noexcept
32{
33 auto expected = lhs.load(order);
34 while (rhs < expected) {
35 if (lhs.compare_exchange_weak(expected, rhs, order)) {
36 return expected;
37 }
38 }
39 return expected;
40}
41
42template<typename T>
44public:
45 using element_type = T;
46 using pointer = element_type *;
47 using reference = element_type &;
48
49 ~atomic_unique_ptr() noexcept
50 {
51 delete _pointer.load(std::memory_order_relaxed);
52 }
53
54 constexpr atomic_unique_ptr() noexcept = default;
55 atomic_unique_ptr(atomic_unique_ptr const &) = delete;
56 atomic_unique_ptr &operator=(atomic_unique_ptr const &) = delete;
57
58 atomic_unique_ptr(atomic_unique_ptr &&other) noexcept : _pointer(other._pointer.exchange(nullptr)) {}
59
60 atomic_unique_ptr &operator=(atomic_unique_ptr &&other) noexcept
61 {
62 hi_return_on_self_assignment(other);
63
64 delete _pointer.exchange(other._pointer.exchange(nullptr));
65 return *this;
66 }
67
68 constexpr atomic_unique_ptr(std::nullptr_t) noexcept : _pointer(nullptr) {}
69
70 atomic_unique_ptr &operator=(std::nullptr_t) noexcept
71 {
72 delete _pointer.exchange(nullptr);
73 return *this;
74 }
75
76 constexpr atomic_unique_ptr(pointer other) noexcept : _pointer(other) {}
77
78 atomic_unique_ptr &operator=(pointer other) noexcept
79 {
80 delete _pointer.exchange(other);
81 return *this;
82 }
83
86 [[nodiscard]] pointer get(std::memory_order order = std::memory_order::seq_cst) const noexcept
87 {
88 return _pointer.load(order);
89 }
90
102 template<typename... Args>
103 [[nodiscard]] reference get_or_make(Args &&...args) noexcept
104 {
105 auto expected = _pointer.load(std::memory_order::acquire);
106 if (expected != nullptr) {
107 return *expected;
108 }
109
110 auto desired = new element_type(std::forward<Args>(args)...);
111 if (not _pointer.compare_exchange_strong(expected, desired, std::memory_order::release, std::memory_order::acquire)) {
112 // Lost construction race.
113 delete desired;
114 return *expected;
115 } else {
116 return *desired;
117 }
118 }
119
120private:
121 std::atomic<pointer> _pointer;
122};
123
124} // namespace hi::inline v1
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
Definition atomic.hpp:43
reference get_or_make(Args &&...args) noexcept
Get or make an object.
Definition atomic.hpp:103
pointer get(std::memory_order order=std::memory_order::seq_cst) const noexcept
Get the raw pointer.
Definition atomic.hpp:86
Definition concepts.hpp:35
Definition concepts.hpp:38