HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
small_map.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/required.hpp"
7#include <array>
8#include <utility>
9#include <optional>
10#include <type_traits>
11
12namespace tt {
13
14template<typename K, typename V, int N>
15class small_map {
16public:
17 using key_type = K;
18 using value_type = V;
19 struct item_type {
20 K key;
21 V value;
22 };
23 static constexpr int capacity = N;
25
26private:
27 typename array_type::iterator _end;
28 array_type items = {};
29
30public:
31 small_map() {
32 _end = items.begin();
33 }
34
35 small_map(small_map const &other) {
36 tt_assume(this != &other);
37 _end = items.begin();
38 for (ttlet &other_item: other) {
39 auto &this_item = *(_end++);
40 this_item = other_item;
41 }
42 }
43
44 small_map(small_map &&other) {
45 tt_assume(this != &other);
46 using std::swap;
47
48 _end = items.begin();
49 for (auto &other_item: other) {
50 auto &this_item = *(_end++);
51 swap(this_item, other_item);
52 }
53 // All items in other are valid, no reason to set other._end.
54 }
55
56 small_map &operator=(small_map const &other) {
57 if (this != &other) {
58 _end = items.begin();
59 for (ttlet &other_item: other) {
60 auto &this_item = *(_end++);
61 this_item = other_item;
62 }
63 }
64 return *this;
65 }
66
67 small_map &operator=(small_map &&other) {
68 if (this != &other) {
69 _end = items.begin();
70 for (ttlet &other_item: other) {
71 auto &this_item = *(_end++);
72 this_item = std::move(other_item);
73 }
74 other._end = other.begin();
75 }
76 return *this;
77 }
78
79 size_t size() const {
80 return _end - items.begin();
81 }
82
83 decltype(auto) begin() const { return items.begin(); }
84 decltype(auto) begin() { return items.begin(); }
85 decltype(auto) end() const { return _end; }
86 decltype(auto) end() { return _end; }
87
88
89
90 std::optional<V> get(K const &key) const noexcept {
91 for (auto i = begin(); i != end(); ++i) {
92 if (i->key == key) {
93 return i->value;
94 }
95 }
96 return {};
97 }
98
99 V get(K const &key, V const &default_value) const noexcept {
100 if (ttlet &value = get(key)) {
101 return *value;
102 } else {
103 return default_value;
104 }
105 }
106
107 template<typename KK, typename VV>
108 bool set(KK &&key, VV &&value) noexcept {
109 auto i = begin();
110 for (; i != end(); ++i) {
111 if (i->key == key) {
112 i->value = std::forward<VV>(value);
113 return true;
114 }
115 }
116 if (i != items.end()) {
117 _end = i + 1;
118 i->key = std::forward<KK>(key);
119 i->value = std::forward<VV>(value);
120 return true;
121 }
122
123 return false;
124 }
125
126 V increment(K const &key) noexcept {
127 static_assert(std::is_arithmetic_v<V>, "Only increment on a artihmatic value");
128 auto i = begin();
129 for (; i != end(); ++i) {
130 if (i->key == key) {
131 return ++(i->value);
132 }
133 }
134 if (i != items.end()) {
135 _end = i + 1;
136 i->key = key;
137 return i->value = V{1};
138 }
139
140 return 0;
141 }
142};
143
144}
145
146
Definition small_map.hpp:15
Definition small_map.hpp:19
T begin(T... args)
T end(T... args)
T move(T... args)
T swap(T... args)