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 "../utility/utility.hpp"
8#include "../concurrency/concurrency.hpp"
9#include "../macros.hpp"
10#include <mutex>
11#include <memory>
12#include <atomic>
13#include <map>
14#include <unordered_map>
15#include <functional>
16
17hi_export_module(hikogui.container.stable_set);
18
19hi_export namespace hi::inline v1 {
20
31template<typename Key>
33public:
34 using value_type = Key;
35 using size_type = size_t;
36 using map_type = std::conditional_t<
40 using key_type = Key;
41 using difference_type = ptrdiff_t;
42 using reference = value_type const&;
43 using const_reference = value_type const&;
44 using pointer = value_type const *;
45 using const_pointer = value_type const *;
46
47 ~stable_set() = default;
48 constexpr stable_set() noexcept = default;
49 stable_set(stable_set const&) = delete;
50 stable_set(stable_set&&) = delete;
51 stable_set& operator=(stable_set const&) = delete;
52 stable_set& operator=(stable_set&&) = delete;
53
54 [[nodiscard]] size_t size() const noexcept
55 {
56 auto const lock = std::scoped_lock(_mutex);
57 return _vector.size();
58 }
59
60 [[nodiscard]] bool empty() const noexcept
61 {
62 return size() == 0;
63 }
64
65 operator bool() const noexcept
66 {
67 return not empty();
68 }
69
76 [[nodiscard]] const_reference operator[](size_t index) const noexcept
77 {
78 auto const lock = std::scoped_lock(_mutex);
79 hi_assert_bounds(index, _vector);
80 return *_vector[index];
81 }
82
92 template<typename Arg>
93 [[nodiscard]] size_t insert(Arg&& arg) noexcept requires(std::is_same_v<std::decay_t<Arg>, value_type>)
94 {
95 auto const lock = std::scoped_lock(_mutex);
96
97 auto const[it, is_inserted] = _map.emplace(std::forward<Arg>(arg), _vector.size());
98 if (is_inserted) {
99 _vector.push_back(std::addressof(it->first));
100 }
101 return it->second;
102 }
103
113 template<typename... Args>
114 [[nodiscard]] size_t emplace(Args&&...args) noexcept
115 {
116 auto const lock = std::scoped_lock(_mutex);
117
118 auto const[it, is_inserted] = _map.emplace(value_type{std::forward<Args>(args)...}, _vector.size());
119 if (is_inserted) {
120 _vector.push_back(std::addressof(it->first));
121 }
122 return it->second;
123 }
124
125private:
126 // clang-format sucks.
127 using vector_type = std::vector<const_pointer>;
128
129 vector_type _vector;
130 map_type _map;
131 mutable unfair_mutex _mutex;
132};
133} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
This is a set of object with stable indices.
Definition stable_set.hpp:32
size_t insert(Arg &&arg) noexcept
Insert an object into the stable-set.
Definition stable_set.hpp:93
size_t emplace(Args &&...args) noexcept
Emplace an object into the stable-set.
Definition stable_set.hpp:114
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:76
T addressof(T... args)