HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
stable_set.hpp
1// Copyright Take Vos 2022.
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 "unfair_mutex.hpp"
8#include <mutex>
9#include <memory>
10#include <atomic>
11#include <map>
12#include <unordered_map>
13#include <functional>
14
15namespace hi::inline v1 {
16
27template<typename Key>
29public:
30 using value_type = Key;
31 using size_type = size_t;
32 using map_type = std::conditional_t<
36 using key_type = Key;
37 using difference_type = ptrdiff_t;
38 using reference = value_type const&;
39 using const_reference = value_type const&;
40 using pointer = value_type const *;
41 using const_pointer = value_type const *;
42
43 ~stable_set() = default;
44 constexpr stable_set() noexcept = default;
45 stable_set(stable_set const&) = delete;
46 stable_set(stable_set&&) = delete;
47 stable_set& operator=(stable_set const&) = delete;
48 stable_set& operator=(stable_set&&) = delete;
49
50 [[nodiscard]] size_t size() const noexcept
51 {
52 hilet lock = std::scoped_lock(_mutex);
53 return _vector.size();
54 }
55
56 [[nodiscard]] bool empty() const noexcept
57 {
58 return size() == 0;
59 }
60
61 operator bool() const noexcept
62 {
63 return not empty();
64 }
65
72 [[nodiscard]] const_reference operator[](size_t index) const noexcept
73 {
74 hilet lock = std::scoped_lock(_mutex);
75 hi_assert_bounds(index, _vector);
76 return *_vector[index];
77 }
78
88 template<typename Arg>
89 [[nodiscard]] size_t insert(Arg&& arg) noexcept requires(std::is_same_v<std::decay_t<Arg>, value_type>)
90 {
91 hilet lock = std::scoped_lock(_mutex);
92
93 hilet[it, is_inserted] = _map.emplace(std::forward<Arg>(arg), _vector.size());
94 if (is_inserted) {
95 _vector.push_back(std::addressof(it->first));
96 }
97 return it->second;
98 }
99
109 template<typename... Args>
110 [[nodiscard]] size_t emplace(Args&&...args) noexcept
111 {
112 hilet lock = std::scoped_lock(_mutex);
113
114 hilet[it, is_inserted] = _map.emplace(value_type{std::forward<Args>(args)...}, _vector.size());
115 if (is_inserted) {
116 _vector.push_back(std::addressof(it->first));
117 }
118 return it->second;
119 }
120
121private:
122 // clang-format sucks.
123 using vector_type = std::vector<const_pointer>;
124
125 vector_type _vector;
126 map_type _map;
127 mutable unfair_mutex _mutex;
128};
129} // namespace hi::inline v1
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
This is a set of object with stable indices.
Definition stable_set.hpp:28
size_t insert(Arg &&arg) noexcept
Insert an object into the stable-set.
Definition stable_set.hpp:89
size_t emplace(Args &&...args) noexcept
Emplace an object into the stable-set.
Definition stable_set.hpp:110
const_reference operator[](size_t index) const noexcept
Get a const reference to an object located at an index in the set.
Definition stable_set.hpp:72
Definition concepts.hpp:36
Definition concepts.hpp:39
T addressof(T... args)