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>
63template <
typename Key,
typename Value,
size_t kArraySize>
67 using mapped_type = Value;
71 using size_type = size_t;
72 using difference_type = ptrdiff_t;
73 using container_type =
typename std::array<value_type, kArraySize>;
74 using iterator =
typename container_type::iterator;
75 using const_iterator =
typename container_type::const_iterator;
82 using value_type = FlatMap::mapped_type;
83 using difference_type = std::ptrdiff_t;
84 using pointer = value_type*;
85 using reference = value_type&;
86 using iterator_category = std::bidirectional_iterator_tag;
94 constexpr reference operator*()
const {
95 reference value = current_->second;
99 constexpr pointer operator->()
const {
return &operator*(); }
124 return current_ == other.current_;
128 return !(*
this == other);
134 constexpr mapped_iterator(FlatMap::iterator current) : current_(current) {}
136 FlatMap::iterator current_;
139 constexpr FlatMap(
const std::array<value_type, kArraySize>& items)
141 ConstexprSort(items_.begin(), kArraySize);
144 constexpr FlatMap(std::array<value_type, kArraySize>&& items)
145 : items_(std::move(items)) {
146 ConstexprSort(items_.begin(), kArraySize);
151 template <
typename... Items,
152 typename = std::enable_if_t<
153 std::conjunction_v<std::is_same<Items, value_type>...>>>
154 constexpr FlatMap(
const Items&... items) : FlatMap(std::array{items...}) {}
156 FlatMap(FlatMap&) =
delete;
157 FlatMap& operator=(FlatMap&) =
delete;
160 constexpr size_type size()
const {
return kArraySize; }
161 constexpr size_type empty()
const {
return size() == 0; }
162 constexpr size_type max_size()
const {
return kArraySize; }
172 constexpr mapped_type&
at(
const key_type& key) {
173 PW_ASSERT(end() != begin());
174 iterator it = std::lower_bound(
175 items_.begin(), items_.end(), key, IsItemKeyLessThanGivenKey);
176 const key_type& found_key = it->first;
177 PW_ASSERT(it != items_.end() && found_key == key);
178 mapped_type& found_value = it->second;
189 constexpr const mapped_type&
at(
const key_type& key)
const {
190 PW_ASSERT(end() != begin());
191 const_iterator it = std::lower_bound(
192 items_.cbegin(), items_.cend(), key, IsItemKeyLessThanGivenKey);
193 const key_type& found_key = it->first;
194 PW_ASSERT(it != items_.cend() && found_key == key);
195 const mapped_type& found_value = it->second;
199 constexpr bool contains(
const key_type& key)
const {
200 return find(key) != end();
203 constexpr const_iterator find(
const key_type& key)
const {
204 if (end() == begin()) {
208 const_iterator it = lower_bound(key);
209 if (it == end() || it->first != key) {
215 constexpr const_iterator lower_bound(
const key_type& key)
const {
216 return std::lower_bound(begin(), end(), key, IsItemKeyLessThanGivenKey);
219 constexpr const_iterator upper_bound(
const key_type& key)
const {
220 return std::upper_bound(
221 begin(), end(), key, [](key_type lkey,
const value_type& item) {
222 return item.first > lkey;
226 constexpr std::pair<const_iterator, const_iterator> equal_range(
227 const key_type& key)
const {
228 if (end() == begin()) {
229 return std::make_pair(end(), end());
232 return std::make_pair(lower_bound(key), upper_bound(key));
236 constexpr const_iterator begin()
const {
return cbegin(); }
237 constexpr const_iterator cbegin()
const {
return items_.cbegin(); }
238 constexpr const_iterator end()
const {
return cend(); }
239 constexpr const_iterator cend()
const {
return items_.cend(); }
265 static constexpr void ConstexprSort(iterator data, size_type size) {
270 for (iterator it = data + 1,
271 end = data +
static_cast<difference_type
>(size);
274 if (it->first < it[-1].first) {
276 value_type temp = std::move(*it);
277 iterator it2 = it - 1;
279 *(it2 + 1) = std::move(*it2);
280 if (it2 == data || !(temp.first < it2[-1].first)) {
285 *it2 = std::move(temp);
290 static constexpr bool IsItemKeyLessThanGivenKey(
const value_type& item,
292 const key_type& item_key = item.first;
293 return item_key < key;
296 std::array<value_type, kArraySize> items_;
299template <
typename K,
typename V,
typename... Items>
300FlatMap(
const Pair<K, V>& item1,
const Items&... items)
301 -> FlatMap<K, V, 1 +
sizeof...(items)>;
Definition: flat_map.h:80
Definition: flat_map.h:64
constexpr mapped_type & at(const key_type &key)
Definition: flat_map.h:172
constexpr mapped_iterator mapped_begin()
Definition: flat_map.h:247
constexpr mapped_iterator mapped_end()
Definition: flat_map.h:257
constexpr const mapped_type & at(const key_type &key) const
Definition: flat_map.h:189
Definition: flat_map.h:31