23#include "pw_assert/assert.h"
25namespace pw::containers {
30template <
typename First,
typename Second>
35 bool operator==(
const Pair& p)
const {
36 return first == p.first && second == p.second;
39 bool operator!=(
const Pair& p)
const {
return !(*
this == p); }
42template <
typename T1,
typename T2>
54template <
typename Key,
typename Value,
size_t kArraySize>
58 using mapped_type = Value;
62 using size_type = size_t;
63 using difference_type = ptrdiff_t;
64 using container_type =
typename std::array<value_type, kArraySize>;
65 using iterator =
typename container_type::iterator;
66 using const_iterator =
typename container_type::const_iterator;
73 using value_type = FlatMap::mapped_type;
74 using difference_type = std::ptrdiff_t;
75 using pointer = value_type*;
76 using reference = value_type&;
77 using iterator_category = std::bidirectional_iterator_tag;
85 constexpr reference operator*()
const {
86 reference value = current_->second;
90 constexpr pointer operator->()
const {
return &operator*(); }
115 return current_ == other.current_;
119 return !(*
this == other);
125 constexpr mapped_iterator(FlatMap::iterator current) : current_(current) {}
127 FlatMap::iterator current_;
130 constexpr FlatMap(
const std::array<value_type, kArraySize>& items)
132 ConstexprSort(items_.begin(), kArraySize);
135 constexpr FlatMap(std::array<value_type, kArraySize>&& items)
136 : items_(std::move(items)) {
137 ConstexprSort(items_.begin(), kArraySize);
142 template <
typename... Items,
143 typename = std::enable_if_t<
144 std::conjunction_v<std::is_same<Items, value_type>...>>>
145 constexpr FlatMap(
const Items&... items) : FlatMap(std::array{items...}) {}
147 FlatMap(FlatMap&) =
delete;
148 FlatMap& operator=(FlatMap&) =
delete;
151 constexpr size_type size()
const {
return kArraySize; }
152 constexpr size_type empty()
const {
return size() == 0; }
153 constexpr size_type max_size()
const {
return kArraySize; }
163 constexpr mapped_type&
at(
const key_type& key) {
164 PW_ASSERT(end() != begin());
165 iterator it = std::lower_bound(
166 items_.begin(), items_.end(), key, IsItemKeyLessThanGivenKey);
167 const key_type& found_key = it->first;
168 PW_ASSERT(it != items_.end() && found_key == key);
169 mapped_type& found_value = it->second;
180 constexpr const mapped_type&
at(
const key_type& key)
const {
181 PW_ASSERT(end() != begin());
182 const_iterator it = std::lower_bound(
183 items_.cbegin(), items_.cend(), key, IsItemKeyLessThanGivenKey);
184 const key_type& found_key = it->first;
185 PW_ASSERT(it != items_.cend() && found_key == key);
186 const mapped_type& found_value = it->second;
190 constexpr bool contains(
const key_type& key)
const {
191 return find(key) != end();
194 constexpr const_iterator find(
const key_type& key)
const {
195 if (end() == begin()) {
199 const_iterator it = lower_bound(key);
200 if (it == end() || it->first != key) {
206 constexpr const_iterator lower_bound(
const key_type& key)
const {
207 return std::lower_bound(begin(), end(), key, IsItemKeyLessThanGivenKey);
210 constexpr const_iterator upper_bound(
const key_type& key)
const {
211 return std::upper_bound(
212 begin(), end(), key, [](key_type lkey,
const value_type& item) {
213 return item.first > lkey;
217 constexpr std::pair<const_iterator, const_iterator> equal_range(
218 const key_type& key)
const {
219 if (end() == begin()) {
220 return std::make_pair(end(), end());
223 return std::make_pair(lower_bound(key), upper_bound(key));
227 constexpr const_iterator begin()
const {
return cbegin(); }
228 constexpr const_iterator cbegin()
const {
return items_.cbegin(); }
229 constexpr const_iterator end()
const {
return cend(); }
230 constexpr const_iterator cend()
const {
return items_.cend(); }
256 static constexpr void ConstexprSort(iterator data, size_type size) {
261 for (iterator it = data + 1,
262 end = data +
static_cast<difference_type
>(size);
265 if (it->first < it[-1].first) {
267 value_type temp = std::move(*it);
268 iterator it2 = it - 1;
270 *(it2 + 1) = std::move(*it2);
271 if (it2 == data || !(temp.first < it2[-1].first)) {
276 *it2 = std::move(temp);
281 static constexpr bool IsItemKeyLessThanGivenKey(
const value_type& item,
283 const key_type& item_key = item.first;
284 return item_key < key;
287 std::array<value_type, kArraySize> items_;
290template <
typename K,
typename V,
typename... Items>
291FlatMap(
const Pair<K, V>& item1,
const Items&... items)
292 -> FlatMap<K, V, 1 +
sizeof...(items)>;
Definition: flat_map.h:71
Definition: flat_map.h:55
constexpr mapped_type & at(const key_type &key)
Definition: flat_map.h:163
constexpr mapped_iterator mapped_begin()
Definition: flat_map.h:238
constexpr mapped_iterator mapped_end()
Definition: flat_map.h:248
constexpr const mapped_type & at(const key_type &key) const
Definition: flat_map.h:180
Definition: flat_map.h:31