Embedded Template Library 1.0
Loading...
Searching...
No Matches
const_map.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2025 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_CONST_MAP_INCLUDED
32#define ETL_CONST_MAP_INCLUDED
33
34#include "platform.h"
35
36#include "algorithm.h"
37#include "functional.h"
38#include "nth_type.h"
39#include "span.h"
40#include "type_traits.h"
41
43
44#if ETL_USING_CPP11
45
48
49namespace etl
50{
51 template <typename TKey, typename TMapped, typename TKeyCompare>
52 class iconst_map
53 {
54 public:
55
56 using key_type = TKey;
57 using value_type = ETL_OR_STD::pair<const TKey, TMapped>;
58 using mapped_type = TMapped;
59 using key_compare = TKeyCompare;
60 using const_reference = const value_type&;
61 using const_pointer = const value_type*;
62 using const_iterator = const value_type*;
63 using size_type = size_t;
64
65 //*********************************************************************
67 //*********************************************************************
68 class value_compare
69 {
70 public:
71
72 // Compare two value types.
73 ETL_CONSTEXPR14 bool operator()(const value_type& element1, const value_type& element2) const ETL_NOEXCEPT
74 {
75 return kcompare(element1.first, element2.first);
76 }
77
78 // Compare value type and key.
79 ETL_CONSTEXPR14 bool operator()(const value_type& element, const key_type& key) const ETL_NOEXCEPT
80 {
81 return kcompare(element.first, key);
82 }
83
84 // Compare value types and key.
85 // Enabled for transparent comparators.
86 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
87 ETL_CONSTEXPR14 bool operator()(const value_type& element, const K& key) const ETL_NOEXCEPT
88 {
89 return kcompare(element.first, key);
90 }
91
92 // Compare key and value type.
93 ETL_CONSTEXPR14 bool operator()(const key_type& key, const value_type& element) const ETL_NOEXCEPT
94 {
95 return kcompare(key, element.first);
96 }
97
98 // Compare key and value type.
99 // Enabled for transparent comparators.
100 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
101 ETL_CONSTEXPR14 bool operator()(const K& key, const value_type& element) const ETL_NOEXCEPT
102 {
103 return kcompare(key, element.first);
104 }
105
106 key_compare kcompare;
107 };
108
109 //*************************************************************************
113 //*************************************************************************
114 ETL_CONSTEXPR14 bool is_valid() const ETL_NOEXCEPT
115 {
116 return etl::is_unique_sorted(begin(), end(), vcompare);
117 }
118
119 //*************************************************************************
121 //*************************************************************************
122 ETL_CONSTEXPR14 const_iterator begin() const ETL_NOEXCEPT
123 {
124 return element_list;
125 }
126
127 //*************************************************************************
129 //*************************************************************************
130 ETL_CONSTEXPR14 const_iterator cbegin() const ETL_NOEXCEPT
131 {
132 return element_list;
133 }
134
135 //*************************************************************************
137 //*************************************************************************
138 ETL_CONSTEXPR14 const_iterator end() const ETL_NOEXCEPT
139 {
140 return element_list_end;
141 }
142
143 //*************************************************************************
145 //*************************************************************************
146 ETL_CONSTEXPR14 const_iterator cend() const ETL_NOEXCEPT
147 {
148 return element_list_end;
149 }
150
151 //*************************************************************************
153 //*************************************************************************
154 ETL_CONSTEXPR14 const_pointer data() const ETL_NOEXCEPT
155 {
156 return element_list;
157 }
158
159 //*************************************************************************
165 //*************************************************************************
166 ETL_CONSTEXPR14 const mapped_type& operator[](const key_type& key) const ETL_NOEXCEPT
167 {
168 const_iterator itr = find(key);
169
170 return itr->second;
171 }
172
173 //*************************************************************************
180 //*************************************************************************
181 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
182 ETL_CONSTEXPR14 const mapped_type& operator[](const K& key) const ETL_NOEXCEPT
183 {
184 const_iterator itr = find(key);
185
186 return itr->second;
187 }
188
189 //*************************************************************************
195 //*************************************************************************
196 ETL_CONSTEXPR14 const mapped_type& at(const key_type& key) const ETL_NOEXCEPT
197 {
198 const_iterator itr = find(key);
199
200 return itr->second;
201 }
202
203 //*************************************************************************
210 //*************************************************************************
211 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
212 ETL_CONSTEXPR14 const mapped_type& at(const K& key) const ETL_NOEXCEPT
213 {
214 const_iterator itr = find(key);
215
216 return itr->second;
217 }
218
219 //*************************************************************************
224 //*************************************************************************
225 ETL_CONSTEXPR14 const_iterator find(const key_type& key) const ETL_NOEXCEPT
226 {
227 const_iterator itr = lower_bound(key);
228
229 if ((itr != end()) && (keys_are_equal(itr->first, key)))
230 {
231 return itr;
232 }
233
234 return end();
235 }
236
237 //*************************************************************************
243 //*************************************************************************
244 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
245 ETL_CONSTEXPR14 const_iterator find(const K& key) const ETL_NOEXCEPT
246 {
247 const_iterator itr = lower_bound(key);
248
249 if ((itr != end()) && (keys_are_equal(itr->first, key)))
250 {
251 return itr;
252 }
253
254 return end();
255 }
256
257 //*************************************************************************
261 //*************************************************************************
262 ETL_CONSTEXPR14 bool contains(const key_type& key) const ETL_NOEXCEPT
263 {
264 return find(key) != end();
265 }
266
267 //*************************************************************************
272 //*************************************************************************
273 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
274 ETL_CONSTEXPR14 bool contains(const K& key) const ETL_NOEXCEPT
275 {
276 return find(key) != end();
277 }
278
279 //*************************************************************************
283 //*************************************************************************
284 ETL_CONSTEXPR14 size_type count(const key_type& key) const ETL_NOEXCEPT
285 {
286 return contains(key) ? 1 : 0;
287 }
288
289 //*************************************************************************
294 //*************************************************************************
295 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
296 ETL_CONSTEXPR14 size_type count(const K& key) const ETL_NOEXCEPT
297 {
298 return contains(key) ? 1 : 0;
299 }
300
301 //*************************************************************************
308 //*************************************************************************
309 ETL_CONSTEXPR14 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const key_type& key) const ETL_NOEXCEPT
310 {
311 return etl::equal_range(begin(), end(), key, vcompare);
312 }
313
314 //*************************************************************************
322 //*************************************************************************
323 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
324 ETL_CONSTEXPR14 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const ETL_NOEXCEPT
325 {
326 return etl::equal_range(begin(), end(), key, vcompare);
327 }
328
329 //*************************************************************************
336 //*************************************************************************
337 ETL_CONSTEXPR14 const_iterator lower_bound(const key_type& key) const ETL_NOEXCEPT
338 {
339 return etl::lower_bound(begin(), end(), key, vcompare);
340 }
341
342 //*************************************************************************
349 //*************************************************************************
350 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
351 ETL_CONSTEXPR14 const_iterator lower_bound(const K& key) const ETL_NOEXCEPT
352 {
353 return etl::lower_bound(begin(), end(), key, vcompare);
354 }
355
356 //*************************************************************************
363 //*************************************************************************
364 ETL_CONSTEXPR14 const_iterator upper_bound(const key_type& key) const ETL_NOEXCEPT
365 {
366 return etl::upper_bound(begin(), end(), key, vcompare);
367 }
368
369 //*************************************************************************
376 //*************************************************************************
377 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
378 ETL_CONSTEXPR14 const_iterator upper_bound(const K& key) const ETL_NOEXCEPT
379 {
380 return etl::upper_bound(begin(), end(), key, vcompare);
381 }
382
383 //*************************************************************************
386 //*************************************************************************
387 ETL_CONSTEXPR14 size_type empty() const ETL_NOEXCEPT
388 {
389 return size() == 0U;
390 }
391
392 //*************************************************************************
395 //*************************************************************************
396 ETL_CONSTEXPR14 size_type full() const ETL_NOEXCEPT
397 {
398 return (max_elements != 0) && (size() == max_elements);
399 }
400
401 //*************************************************************************
404 //*************************************************************************
405 ETL_CONSTEXPR14 size_type size() const ETL_NOEXCEPT
406 {
407 return size_type(element_list_end - element_list);
408 }
409
410 //*************************************************************************
413 //*************************************************************************
414 ETL_CONSTEXPR14 size_type max_size() const ETL_NOEXCEPT
415 {
416 return max_elements;
417 }
418
419 //*************************************************************************
423 //*************************************************************************
424 ETL_CONSTEXPR14 size_type capacity() const ETL_NOEXCEPT
425 {
426 return max_elements;
427 }
428
429 //*************************************************************************
432 //*************************************************************************
433 ETL_CONSTEXPR14 key_compare key_comp() const ETL_NOEXCEPT
434 {
435 return vcompare.kcompare;
436 }
437
438 //*************************************************************************
441 //*************************************************************************
442 ETL_CONSTEXPR14 value_compare value_comp() const ETL_NOEXCEPT
443 {
444 return vcompare;
445 }
446
447 protected:
448
449 //*************************************************************************
451 //*************************************************************************
452 template <typename... TElements>
453 ETL_CONSTEXPR14 explicit iconst_map(const value_type* element_list_, size_type size_, size_type max_elements_) ETL_NOEXCEPT
454 : element_list(element_list_)
455 , element_list_end{element_list_ + size_}
456 , max_elements(max_elements_)
457 {
458 }
459
460 private:
461
462 //*********************************************************************
464 //*********************************************************************
465 ETL_CONSTEXPR14 bool keys_are_equal(const key_type& key1, const key_type& key2) const ETL_NOEXCEPT
466 {
467 return !key_compare()(key1, key2) && !key_compare()(key2, key1);
468 }
469
470 //*********************************************************************
473 //*********************************************************************
474 template <typename K1, typename K2, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
475 ETL_CONSTEXPR14 bool keys_are_equal(const K1& key1, const K2& key2) const ETL_NOEXCEPT
476 {
477 return !key_compare()(key1, key2) && !key_compare()(key2, key1);
478 }
479
480 value_compare vcompare;
481
482 const value_type* element_list;
483 const value_type* element_list_end;
484 size_type max_elements;
485 };
486
487 //*********************************************************************
489 //*********************************************************************
490 template <typename TKey, typename TMapped, size_t Size, typename TKeyCompare = etl::less<TKey>>
491 class const_map : public iconst_map<TKey, TMapped, TKeyCompare>
492 {
493 public:
494
495 using base_t = iconst_map<TKey, TMapped, TKeyCompare>;
496
497 using key_type = typename base_t::key_type;
498 using value_type = typename base_t::value_type;
499 using mapped_type = typename base_t::mapped_type;
500 using key_compare = typename base_t::key_compare;
501 using const_reference = typename base_t::const_reference;
502 using const_pointer = typename base_t::const_pointer;
503 using const_iterator = typename base_t::const_iterator;
504 using size_type = typename base_t::size_type;
505
506 static_assert((etl::is_default_constructible<key_type>::value), "key_type must be default constructible");
507 static_assert((etl::is_default_constructible<mapped_type>::value), "mapped_type must be default constructible");
508
509 //*************************************************************************
514 //*************************************************************************
515 template <typename... TElements>
516 ETL_CONSTEXPR14 explicit const_map(TElements&&... elements) ETL_NOEXCEPT
517 : iconst_map<TKey, TMapped, TKeyCompare>(element_list, sizeof...(elements), Size)
518 , element_list{etl::forward<TElements>(elements)...}
519 {
520 static_assert((etl::are_all_same<value_type, etl::decay_t<TElements>...>::value), "All elements must be value_type");
521 static_assert(sizeof...(elements) <= Size, "Number of elements exceeds capacity");
522 }
523
524 private:
525
526 value_type element_list[Size];
527 };
528
529 //*************************************************************************
531 //*************************************************************************
532 #if ETL_USING_CPP17
533 template <typename... TElements>
534 const_map(TElements...)
535 -> const_map<typename etl::nth_type_t<0, TElements...>::first_type, typename etl::nth_type_t<0, TElements...>::second_type, sizeof...(TElements)>;
536 #endif
537
538 //*********************************************************************
540 //*********************************************************************
541 template <typename TKey, typename TMapped, typename TKeyCompare = etl::less<TKey>>
542 class const_map_ext : public iconst_map<TKey, TMapped, TKeyCompare>
543 {
544 public:
545
546 using base_t = iconst_map<TKey, TMapped, TKeyCompare>;
547
548 using key_type = typename base_t::key_type;
549 using value_type = typename base_t::value_type;
550 using mapped_type = typename base_t::mapped_type;
551 using key_compare = typename base_t::key_compare;
552 using const_reference = typename base_t::const_reference;
553 using const_pointer = typename base_t::const_pointer;
554 using const_iterator = typename base_t::const_iterator;
555 using size_type = typename base_t::size_type;
556
557 static_assert((etl::is_default_constructible<key_type>::value), "key_type must be default constructible");
558 static_assert((etl::is_default_constructible<mapped_type>::value), "mapped_type must be default constructible");
559
560 //*************************************************************************
562 //*************************************************************************
563 ETL_CONSTEXPR14 const_map_ext() ETL_NOEXCEPT
564 : iconst_map<TKey, TMapped, TKeyCompare>(nullptr, 0, 0)
565 {
566 }
567
568 //*************************************************************************
570 //*************************************************************************
571 template <size_type Size>
572 ETL_CONSTEXPR14 explicit const_map_ext(const etl::span<const value_type, Size>& sp) ETL_NOEXCEPT
573 : iconst_map<TKey, TMapped, TKeyCompare>(sp.data(), Size, Size)
574 {
575 }
576
577 //*************************************************************************
579 //*************************************************************************
580 template <size_type Size>
581 ETL_CONSTEXPR14 explicit const_map_ext(const value_type (&begin_)[Size]) ETL_NOEXCEPT
582 : iconst_map<TKey, TMapped, TKeyCompare>(begin_, Size, Size)
583 {
584 }
585 };
586
587 //*************************************************************************
589 //*************************************************************************
590 #if ETL_USING_CPP17
591 template <typename TElements, size_t Size>
592 const_map_ext(const etl::span<TElements, Size>&) -> const_map_ext<typename TElements::first_type, typename TElements::second_type>;
593
594 template <typename TElements, size_t Size>
595 const_map_ext(const TElements (&)[Size]) -> const_map_ext<typename TElements::first_type, typename TElements::second_type>;
596 #endif
597
598 //*************************************************************************
600 //*************************************************************************
601 template <typename TKey, typename TMapped, typename TKeyCompare>
602 ETL_CONSTEXPR14 bool operator==(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
603 ETL_NOEXCEPT
604 {
605 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
606 }
607
608 //*************************************************************************
610 //*************************************************************************
611 template <typename TKey, typename TMapped, typename TKeyCompare>
612 ETL_CONSTEXPR14 bool operator!=(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
613 ETL_NOEXCEPT
614 {
615 return !(lhs == rhs);
616 }
617
618 //*************************************************************************
620 //*************************************************************************
621 template <typename TKey, typename TMapped, typename TKeyCompare>
622 ETL_CONSTEXPR14 bool operator<(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
623 ETL_NOEXCEPT
624 {
625 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), lhs.value_comp());
626 }
627
628 //*************************************************************************
630 //*************************************************************************
631 template <typename TKey, typename TMapped, typename TKeyCompare>
632 ETL_CONSTEXPR14 bool operator>(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
633 ETL_NOEXCEPT
634 {
635 return (rhs < lhs);
636 }
637
638 //*************************************************************************
640 //*************************************************************************
641 template <typename TKey, typename TMapped, typename TKeyCompare>
642 ETL_CONSTEXPR14 bool operator<=(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
643 ETL_NOEXCEPT
644 {
645 return !(rhs < lhs);
646 }
647
648 //*************************************************************************
650 //*************************************************************************
651 template <typename TKey, typename TMapped, typename TKeyCompare>
652 ETL_CONSTEXPR14 bool operator>=(const etl::iconst_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iconst_map<TKey, TMapped, TKeyCompare>& rhs)
653 ETL_NOEXCEPT
654 {
655 return !(lhs < rhs);
656 }
657} // namespace etl
658
659#endif
660#endif
ETL_NODISCARD ETL_CONSTEXPR14 bool is_unique_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1727
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1078
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1470
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1130
TContainer::const_iterator cbegin(const TContainer &container)
Definition iterator.h:1156
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1144
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1434
TContainer::iterator end(TContainer &container)
Definition iterator.h:1166
TContainer::const_iterator cend(const TContainer &container)
Definition iterator.h:1186
TContainer::iterator begin(TContainer &container)
Definition iterator.h:1136
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1103
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1117