header_utils
Loading...
Searching...
No Matches
containers.h
1
4
5#pragma once
6
7#include <vector>
8#include <map>
9#include "ranges.h"
10
11namespace ghassanpl
12{
15
18
20 template <typename T, typename U>
21 constexpr auto push_back_unique(std::vector<T>& vector, U&& value)
22 {
23 const auto it = std::ranges::find(vector, value);
24 if (it == vector.end())
25 {
26 vector.push_back(std::forward<U>(value));
27 return std::prev(vector.end());
28 }
29 return it;
30 }
31
33 template <typename T, typename U>
34 constexpr std::optional<T> erase_single(std::vector<T>& vector, U&& value)
35 {
36 const auto it = std::ranges::find(vector, value);
37 if (it == std::ranges::end(vector))
38 return {};
39 auto&& result = std::move(*it);
40 vector.erase(it);
41 return result;
42 }
43
45 template <typename K, typename V, typename COMP, typename U>
46 constexpr std::optional<V> erase_single(std::map<K, V, COMP>& map, U&& key)
47 {
48 const auto it = map.find(key);
49 if (it == map.end())
50 return {};
51 auto&& result = std::move(it->second);
52 map.erase(it);
53 return result;
54 }
55
57 template <typename T, typename PRED>
58 constexpr std::optional<T> erase_single_if(std::vector<T>& vector, PRED&& pred)
59 {
60 const auto it = std::ranges::find_if(vector, pred);
61 if (it == std::ranges::end(vector))
62 return {};
63 auto&& result = std::move(*it);
64 vector.erase(it);
65 return result;
66 }
67
69 template <typename T, typename U>
70 constexpr std::optional<T> erase_single_swap(std::vector<T>& vector, U&& value)
71 {
72 const auto it = std::ranges::find(vector, value);
73 if (it == std::ranges::end(vector))
74 return {};
75
76 auto&& result = std::exchange(*it, vector.back());
77 vector.pop_back();
78 return result;
79 }
80
82 template <typename T, typename PRED>
83 constexpr std::optional<T> erase_single_swap_if(std::vector<T>& vector, PRED&& pred)
84 {
85 const auto it = std::ranges::find_if(vector, pred);
86 if (it == std::ranges::end(vector))
87 return {};
88
89 auto&& result = std::exchange(*it, vector.back());
90 vector.pop_back();
91 return result;
92 }
93
95 template <typename T>
96 constexpr std::optional<T> erase_at_swap(std::vector<T>& vector, size_t index)
97 {
98 if (!valid_index(vector, index))
99 return {};
100
101 auto&& result = std::exchange(vector[index], vector.back());
102 vector.pop_back();
103 return result;
104 }
105
107 template <typename KEY, typename MAP>
108 auto map_find(MAP& map, KEY&& key)
109 {
110 auto it = map.find(std::forward<KEY>(key));
111 return (it != map.end()) ? &it->second : nullptr;
112 }
113
115 template <typename DEF, typename KEY, typename MAP>
116 auto map_at_or_default(MAP&& map, KEY&& key, DEF&& def)
117 {
118 auto it = map.find(std::forward<KEY>(key));
119 if (it != map.end())
120 return forward_like<MAP>(it->second);
121 return decltype(it->second){ std::forward<DEF>(def) };
122 }
123
125 template <typename KEY, typename MAP>
126 decltype(auto) map_at(MAP&& map, KEY&& key)
127 {
128 auto it = map.find(std::forward<KEY>(key));
129 if (it != map.end())
130 return forward_like<MAP>(it->second);
131 throw std::out_of_range("invalid map key");
132 }
133
134 namespace detail
135 {
136 template <typename MAP>
137 inline auto map_key_type(MAP const& val)
138 {
139 auto& [k, v] = *std::begin(val);
140 return decltype(k){};
141 }
142 }
143
145 template <typename MAP, typename VAL>
146 auto map_find_value(MAP& map, VAL const* value)
147 {
148 for (auto& [k, v] : map)
149 {
150 if (&v == value)
151 return &k;
152 }
153 using map_key_type = decltype(detail::map_key_type(map));
154 return (map_key_type const*)nullptr;
155 }
156
159 template <typename K, typename V, typename C, typename VAL>
160 auto at_ptr(std::map<K, V, C> const& map, VAL&& value) { return map_find(map, std::forward<VAL>(value)); }
161
164 template <typename K, typename V, typename C, typename VAL>
165 auto at_ptr(std::map<K, V, C>& map, VAL&& value) { return map_find(map, std::forward<VAL>(value)); }
166
168 /*
169 void move_element(container cont, int from_index, int to_index)
170 {
171 assumingvalidindex(fromindex)
172 assumingvalidindex(toindex)
173
174 if (from_index == to_index)
175 return;
176
177 if (std::abs(from_index - to_index) == 1)
178 {
179 std::swap(mFiles[from_index], mFiles[to_index]);
180 return;
181 }
182
183 if (from_index < to_index)
184 std::rotate(mFiles.begin() + from_index, mFiles.begin() + from_index + 1, mFiles.begin() + to_index + 1);
185 else
186 std::rotate(mFiles.begin() + to_index, mFiles.begin() + from_index, mFiles.begin() + from_index + 1);
187 }
188
189 void move_element_by(container cont, int from_index, int by)
190 {
191 move_element(cont, from_index, clamp(from_index+by, 0, size(cont)));
192 }
193 void move_element_to_front();
194 void move_element_to_back();
195 */
196
198}
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
auto map_at_or_default(MAP &&map, KEY &&key, DEF &&def)
Finds the value associated with key in the map and retuns it, or def if none found.
Definition containers.h:116
auto at_ptr(std::map< K, V, C > const &map, VAL &&value)
Same as map_find()
Definition containers.h:160
constexpr std::optional< T > erase_single_if(std::vector< T > &vector, PRED &&pred)
Finds a value in the vector by predicate, and erases it.
Definition containers.h:58
constexpr std::optional< T > erase_single_swap_if(std::vector< T > &vector, PRED &&pred)
Finds and erases a value in vector by predicate, not preserving item order (swapping last item to era...
Definition containers.h:83
auto map_find_value(MAP &map, VAL const *value)
Finds the first value of a map element, and returns a pointer to its key, or nullptr if none found.
Definition containers.h:146
constexpr std::optional< T > erase_single(std::vector< T > &vector, U &&value)
Finds a value in the vector, and erases it, but returns the value.
Definition containers.h:34
decltype(auto) map_at(MAP &&map, KEY &&key)
Basically map.at() but works with heterogenous key types.
Definition containers.h:126
auto map_find(MAP &map, KEY &&key)
Finds the value associated with key in the map and retuns a pointer to it, or nullptr if none found.
Definition containers.h:108
constexpr auto push_back_unique(std::vector< T > &vector, U &&value)
Definition containers.h:21
constexpr std::optional< T > erase_single_swap(std::vector< T > &vector, U &&value)
Finds and erases a value in vector, not preserving item order (swapping last item to erased)
Definition containers.h:70
constexpr std::optional< T > erase_at_swap(std::vector< T > &vector, size_t index)
Erases the element at index in vector, not preserving item order (swapping last item to erased)
Definition containers.h:96
constexpr bool valid_index(random_access_range auto &range, std::integral auto index)
Returns whether or not a given integer is a valid index to a random access range
Definition ranges.h:37
The below code is based on Sun's libm library code, which is licensed under the following license:
Primary namespace for everything in this library.
Definition align+rec2.h:10