HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
small_map.hpp
1// Copyright Take Vos 2019-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.hpp"
8#include <array>
9#include <utility>
10#include <optional>
11#include <type_traits>
12
13namespace hi::inline v1 {
14
15template<typename K, typename V, int N>
16class small_map {
17public:
18 using key_type = K;
19 using value_type = V;
20 struct item_type {
21 K key;
22 V value;
23 };
24 static constexpr int capacity = N;
26
27private:
28 typename array_type::iterator _end;
29 array_type items = {};
30
31public:
32 small_map()
33 {
34 _end = items.begin();
35 }
36
37 small_map(small_map const &other)
38 {
39 hi_axiom(this != &other);
40 _end = items.begin();
41 for (hilet &other_item : other) {
42 auto &this_item = *(_end++);
43 this_item = other_item;
44 }
45 }
46
47 small_map(small_map &&other)
48 {
49 hi_axiom(this != &other);
50 using std::swap;
51
52 _end = items.begin();
53 for (auto &other_item : other) {
54 auto &this_item = *(_end++);
55 swap(this_item, other_item);
56 }
57 // All items in other are valid, no reason to set other._end.
58 }
59
60 small_map &operator=(small_map const &other)
61 {
62 hi_return_on_self_assignment(other);
63 _end = items.begin();
64 for (hilet &other_item : other) {
65 auto &this_item = *(_end++);
66 this_item = other_item;
67 }
68 return *this;
69 }
70
71 small_map &operator=(small_map &&other)
72 {
73 hi_return_on_self_assignment(other);
74 _end = items.begin();
75 for (hilet &other_item : other) {
76 auto &this_item = *(_end++);
77 this_item = std::move(other_item);
78 }
79 other._end = other.begin();
80 return *this;
81 }
82
83 std::size_t size() const
84 {
85 return _end - items.begin();
86 }
87
88 decltype(auto) begin() const
89 {
90 return items.begin();
91 }
92 decltype(auto) begin()
93 {
94 return items.begin();
95 }
96 decltype(auto) end() const
97 {
98 return _end;
99 }
100 decltype(auto) end()
101 {
102 return _end;
103 }
104
105 std::optional<V> get(K const &key) const noexcept
106 {
107 for (auto i = begin(); i != end(); ++i) {
108 if (i->key == key) {
109 return i->value;
110 }
111 }
112 return {};
113 }
114
115 V get(K const &key, V const &default_value) const noexcept
116 {
117 if (hilet &value = get(key)) {
118 return *value;
119 } else {
120 return default_value;
121 }
122 }
123
124 template<typename KK, typename VV>
125 bool set(KK &&key, VV &&value) noexcept
126 {
127 auto i = begin();
128 for (; i != end(); ++i) {
129 if (i->key == key) {
130 i->value = std::forward<VV>(value);
131 return true;
132 }
133 }
134 if (i != items.end()) {
135 _end = i + 1;
136 i->key = std::forward<KK>(key);
137 i->value = std::forward<VV>(value);
138 return true;
139 }
140
141 return false;
142 }
143
144 V increment(K const &key) noexcept
145 {
146 static_assert(std::is_arithmetic_v<V>, "Only increment on a artihmatic value");
147 auto i = begin();
148 for (; i != end(); ++i) {
149 if (i->key == key) {
150 return ++(i->value);
151 }
152 }
153 if (i != items.end()) {
154 _end = i + 1;
155 i->key = key;
156 return i->value = V{1};
157 }
158
159 return 0;
160 }
161};
162
163} // namespace hi::inline v1
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
Definition small_map.hpp:16
Definition small_map.hpp:20
T begin(T... args)
T end(T... args)
T move(T... args)
T swap(T... args)