Embedded Template Library 1.0
Loading...
Searching...
No Matches
flat_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) 2015 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_FLAT_MAP_INCLUDED
32#define ETL_FLAT_MAP_INCLUDED
33
34#include "platform.h"
35#include "initializer_list.h"
36#include "nth_type.h"
37#include "placement_new.h"
38#include "pool.h"
39#include "reference_flat_map.h"
40#include "type_traits.h"
41#include "utility.h"
42
44
45//*****************************************************************************
53//*****************************************************************************
54
55namespace etl
56{
57 //***************************************************************************
62 //***************************************************************************
63 template <typename TKey, typename TMapped, typename TKeyCompare = etl::less<TKey> >
64 class iflat_map : private etl::ireference_flat_map<TKey, TMapped, TKeyCompare>
65 {
66 private:
67
69 typedef typename refmap_t::lookup_t lookup_t;
70 typedef etl::ipool storage_t;
71
72 public:
73
74 typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
75 typedef TKey key_type;
76 typedef TMapped mapped_type;
77 typedef TKeyCompare key_compare;
78 typedef value_type& reference;
79 typedef const value_type& const_reference;
80#if ETL_USING_CPP11
81 typedef value_type&& rvalue_reference;
82#endif
83 typedef value_type* pointer;
84 typedef const value_type* const_pointer;
85 typedef size_t size_type;
86
87 typedef const key_type& const_key_reference;
88#if ETL_USING_CPP11
89 typedef key_type&& rvalue_key_reference;
90#endif
91 typedef mapped_type& mapped_reference;
92 typedef const mapped_type& const_mapped_reference;
93
94 typedef typename refmap_t::iterator iterator;
95 typedef typename refmap_t::const_iterator const_iterator;
96
97 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
98 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
99 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
100
101 private:
102
103 public:
104
105 //*********************************************************************
108 //*********************************************************************
109 iterator begin()
110 {
111 return refmap_t::begin();
112 }
113
114 //*********************************************************************
117 //*********************************************************************
118 const_iterator begin() const
119 {
120 return refmap_t::begin();
121 }
122
123 //*********************************************************************
126 //*********************************************************************
127 iterator end()
128 {
129 return refmap_t::end();
130 }
131
132 //*********************************************************************
135 //*********************************************************************
136 const_iterator end() const
137 {
138 return refmap_t::end();
139 }
140
141 //*********************************************************************
144 //*********************************************************************
145 const_iterator cbegin() const
146 {
147 return refmap_t::cbegin();
148 }
149
150 //*********************************************************************
153 //*********************************************************************
154 const_iterator cend() const
155 {
156 return refmap_t::cend();
157 }
158
159 //*********************************************************************
162 //*********************************************************************
163 reverse_iterator rbegin()
164 {
165 return refmap_t::rbegin();
166 }
167
168 //*********************************************************************
172 //*********************************************************************
173 const_reverse_iterator rbegin() const
174 {
175 return refmap_t::rbegin();
176 }
177
178 //*********************************************************************
181 //*********************************************************************
182 reverse_iterator rend()
183 {
184 return refmap_t::rend();
185 }
186
187 //*********************************************************************
190 //*********************************************************************
191 const_reverse_iterator rend() const
192 {
193 return refmap_t::rend();
194 }
195
196 //*********************************************************************
200 //*********************************************************************
201 const_reverse_iterator crbegin() const
202 {
203 return refmap_t::crbegin();
204 }
205
206 //*********************************************************************
209 //*********************************************************************
210 const_reverse_iterator crend() const
211 {
212 return refmap_t::crend();
213 }
214
215#if ETL_USING_CPP11
216 //*********************************************************************
220 //*********************************************************************
221 mapped_reference operator[](rvalue_key_reference key)
222 {
223 iterator i_element = lower_bound(key);
224
225 // Doesn't already exist?
226 if ((i_element == end()) || compare(key, i_element->first))
227 {
228 insert_default_value(i_element, etl::move(key));
229 }
230
231 return i_element->second;
232 }
233#endif
234
235 //*********************************************************************
239 //*********************************************************************
240 mapped_reference operator[](const_key_reference key)
241 {
242 iterator i_element = lower_bound(key);
243
244 // Doesn't already exist?
245 if ((i_element == end()) || compare(key, i_element->first))
246 {
247 insert_default_value(i_element, key);
248 }
249
250 return i_element->second;
251 }
252
253 //*********************************************************************
259 //*********************************************************************
260 mapped_reference at(const_key_reference key)
261 {
262 return refmap_t::at(key);
263 }
264
265#if ETL_USING_CPP11
266 //*********************************************************************
267 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
268 mapped_reference at(const K& key)
269 {
270 return refmap_t::at(key);
271 }
272#endif
273
274 //*********************************************************************
280 //*********************************************************************
281 const_mapped_reference at(const_key_reference key) const
282 {
283 return refmap_t::at(key);
284 }
285
286#if ETL_USING_CPP11
287 //*********************************************************************
288 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
289 const_mapped_reference at(const K& key) const
290 {
291 return refmap_t::at(key);
292 }
293#endif
294
295 //*********************************************************************
303 //*********************************************************************
304 template <typename TIterator>
305 void assign(TIterator first, TIterator last)
306 {
307#if ETL_IS_DEBUG_BUILD
308 difference_type d = etl::distance(first, last);
309 ETL_ASSERT(d <= difference_type(capacity()), ETL_ERROR(flat_map_full));
310#endif
311
312 clear();
313
314 while (first != last)
315 {
316 insert(*first);
317 ++first;
318 }
319 }
320
321 //*********************************************************************
326 //*********************************************************************
327 ETL_OR_STD::pair<iterator, bool> insert(const_reference value)
328 {
329 iterator i_element = lower_bound(value.first);
330
331 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
332
333 // Doesn't already exist?
334 if ((i_element == end()) || compare(value.first, i_element->first))
335 {
336 result = insert_value(i_element, value);
337 }
338
339 return result;
340 }
341
342#if ETL_USING_CPP11
343 //*********************************************************************
348 //*********************************************************************
349 ETL_OR_STD::pair<iterator, bool> insert(rvalue_reference value)
350 {
351 iterator i_element = lower_bound(value.first);
352
353 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
354
355 // Doesn't already exist?
356 if ((i_element == end()) || compare(value.first, i_element->first))
357 {
358 // result = insert_value(i_element, etl::move(value.first),
359 // etl::move(value.second));
360 result = insert_value(i_element, etl::move(value));
361 }
362
363 return result;
364 }
365#endif
366
367 //*********************************************************************
373 //*********************************************************************
374 iterator insert(const_iterator /*position*/, const_reference value)
375 {
376 return insert(value).first;
377 }
378
379#if ETL_USING_CPP11
380 //*********************************************************************
386 //*********************************************************************
387 iterator insert(const_iterator /*position*/, rvalue_reference value)
388 {
389 return insert(etl::move(value)).first;
390 }
391#endif
392
393 //*********************************************************************
400 //*********************************************************************
401 template <class TIterator>
402 void insert(TIterator first, TIterator last)
403 {
404 while (first != last)
405 {
406 insert(*first);
407 ++first;
408 }
409 }
410
411 //*************************************************************************
413 //*************************************************************************
414 ETL_OR_STD::pair<iterator, bool> emplace(const value_type& value)
415 {
416 return emplace(value.first, value.second);
417 }
418
419#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
420 //*************************************************************************
422 //*************************************************************************
423 template <typename... Args>
424 ETL_OR_STD::pair<iterator, bool> emplace(const_key_reference key, Args&&... args)
425 {
426 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
427
428 // Create it.
429 value_type* pvalue = storage.allocate<value_type>();
430 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
431 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(etl::forward<Args>(args)...);
432
433 iterator i_element = lower_bound(key);
434
435 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
436
437 // Doesn't already exist?
438 if ((i_element == end()) || compare(key, i_element->first))
439 {
440 ETL_INCREMENT_DEBUG_COUNT;
441 result = refmap_t::insert_at(i_element, *pvalue);
442 }
443 else
444 {
445 pvalue->~value_type();
446 storage.release(pvalue);
447 }
448
449 return result;
450 }
451
452#else
453
454 //*************************************************************************
456 //*************************************************************************
457 template <typename T1>
458 ETL_OR_STD::pair<iterator, bool> emplace(const_key_reference key, const T1& value1)
459 {
460 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
461
462 // Create it.
463 value_type* pvalue = storage.allocate<value_type>();
464 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
465 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1);
466
467 iterator i_element = lower_bound(key);
468
469 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
470
471 // Doesn't already exist?
472 if ((i_element == end()) || compare(key, i_element->first))
473 {
474 ETL_INCREMENT_DEBUG_COUNT;
475 result = refmap_t::insert_at(i_element, *pvalue);
476 }
477 else
478 {
479 pvalue->~value_type();
480 storage.release(pvalue);
481 }
482
483 return result;
484 }
485
486 //*************************************************************************
488 //*************************************************************************
489 template <typename T1, typename T2>
490 ETL_OR_STD::pair<iterator, bool> emplace(const_key_reference key, const T1& value1, const T2& value2)
491 {
492 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
493
494 // Create it.
495 value_type* pvalue = storage.allocate<value_type>();
496 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
497 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2);
498
499 iterator i_element = lower_bound(key);
500
501 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
502
503 // Doesn't already exist?
504 if ((i_element == end()) || compare(key, i_element->first))
505 {
506 ETL_INCREMENT_DEBUG_COUNT;
507 result = refmap_t::insert_at(i_element, *pvalue);
508 }
509 else
510 {
511 pvalue->~value_type();
512 storage.release(pvalue);
513 }
514
515 return result;
516 }
517
518 //*************************************************************************
520 //*************************************************************************
521 template <typename T1, typename T2, typename T3>
522 ETL_OR_STD::pair<iterator, bool> emplace(const_key_reference key, const T1& value1, const T2& value2, const T3& value3)
523 {
524 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
525
526 // Create it.
527 value_type* pvalue = storage.allocate<value_type>();
528 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
529 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3);
530
531 iterator i_element = lower_bound(key);
532
533 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
534
535 // Doesn't already exist?
536 if ((i_element == end()) || compare(key, i_element->first))
537 {
538 ETL_INCREMENT_DEBUG_COUNT;
539 result = refmap_t::insert_at(i_element, *pvalue);
540 }
541 else
542 {
543 pvalue->~value_type();
544 storage.release(pvalue);
545 }
546
547 return result;
548 }
549
550 //*************************************************************************
552 //*************************************************************************
553 template <typename T1, typename T2, typename T3, typename T4>
554 ETL_OR_STD::pair<iterator, bool> emplace(const_key_reference key, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
555 {
556 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
557
558 // Create it.
559 value_type* pvalue = storage.allocate<value_type>();
560 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
561 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3, value4);
562
563 iterator i_element = lower_bound(key);
564
565 ETL_OR_STD::pair<iterator, bool> result(i_element, false);
566
567 // Doesn't already exist?
568 if ((i_element == end()) || compare(key, i_element->first))
569 {
570 ETL_INCREMENT_DEBUG_COUNT;
571 result = refmap_t::insert_at(i_element, *pvalue);
572 }
573 else
574 {
575 pvalue->~value_type();
576 storage.release(pvalue);
577 }
578
579 return result;
580 }
581
582#endif
583
584#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
585 //*************************************************************************
588 //*************************************************************************
589 template <typename... Args>
590 ETL_OR_STD::pair<iterator, bool> try_emplace(const_key_reference key, Args&&... args)
591 {
592 iterator i_element = lower_bound(key);
593
594 // Already exists?
595 if ((i_element != end()) && !compare(key, i_element->first))
596 {
597 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
598 }
599
600 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
601
602 // Create it.
603 value_type* pvalue = storage.allocate<value_type>();
604 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
605 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(etl::forward<Args>(args)...);
606 ETL_INCREMENT_DEBUG_COUNT;
607
608 return refmap_t::insert_at(i_element, *pvalue);
609 }
610
611 //*************************************************************************
614 //*************************************************************************
615 template <typename... Args>
616 ETL_OR_STD::pair<iterator, bool> try_emplace(rvalue_key_reference key, Args&&... args)
617 {
618 iterator i_element = lower_bound(key);
619
620 // Already exists?
621 if ((i_element != end()) && !compare(key, i_element->first))
622 {
623 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
624 }
625
626 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
627
628 // Create it.
629 value_type* pvalue = storage.allocate<value_type>();
630 ::new ((void*)etl::addressof(pvalue->first)) key_type(etl::move(key));
631 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(etl::forward<Args>(args)...);
632 ETL_INCREMENT_DEBUG_COUNT;
633
634 return refmap_t::insert_at(i_element, *pvalue);
635 }
636
637#else
638
639 //*************************************************************************
641 //*************************************************************************
642 template <typename T1>
643 ETL_OR_STD::pair<iterator, bool> try_emplace(const_key_reference key, const T1& value1)
644 {
645 iterator i_element = lower_bound(key);
646
647 // Already exists?
648 if ((i_element != end()) && !compare(key, i_element->first))
649 {
650 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
651 }
652
653 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
654
655 // Create it.
656 value_type* pvalue = storage.allocate<value_type>();
657 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
658 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1);
659 ETL_INCREMENT_DEBUG_COUNT;
660
661 return refmap_t::insert_at(i_element, *pvalue);
662 }
663
664 //*************************************************************************
666 //*************************************************************************
667 template <typename T1, typename T2>
668 ETL_OR_STD::pair<iterator, bool> try_emplace(const_key_reference key, const T1& value1, const T2& value2)
669 {
670 iterator i_element = lower_bound(key);
671
672 // Already exists?
673 if ((i_element != end()) && !compare(key, i_element->first))
674 {
675 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
676 }
677
678 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
679
680 // Create it.
681 value_type* pvalue = storage.allocate<value_type>();
682 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
683 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2);
684 ETL_INCREMENT_DEBUG_COUNT;
685
686 return refmap_t::insert_at(i_element, *pvalue);
687 }
688
689 //*************************************************************************
691 //*************************************************************************
692 template <typename T1, typename T2, typename T3>
693 ETL_OR_STD::pair<iterator, bool> try_emplace(const_key_reference key, const T1& value1, const T2& value2, const T3& value3)
694 {
695 iterator i_element = lower_bound(key);
696
697 // Already exists?
698 if ((i_element != end()) && !compare(key, i_element->first))
699 {
700 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
701 }
702
703 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
704
705 // Create it.
706 value_type* pvalue = storage.allocate<value_type>();
707 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
708 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3);
709 ETL_INCREMENT_DEBUG_COUNT;
710
711 return refmap_t::insert_at(i_element, *pvalue);
712 }
713
714 //*************************************************************************
716 //*************************************************************************
717 template <typename T1, typename T2, typename T3, typename T4>
718 ETL_OR_STD::pair<iterator, bool> try_emplace(const_key_reference key, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
719 {
720 iterator i_element = lower_bound(key);
721
722 // Already exists?
723 if ((i_element != end()) && !compare(key, i_element->first))
724 {
725 return ETL_OR_STD::pair<iterator, bool>(i_element, false);
726 }
727
728 ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
729
730 // Create it.
731 value_type* pvalue = storage.allocate<value_type>();
732 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
733 ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3, value4);
734 ETL_INCREMENT_DEBUG_COUNT;
735
736 return refmap_t::insert_at(i_element, *pvalue);
737 }
738
739#endif
740
741 //*********************************************************************
745 //*********************************************************************
746 size_t erase(const_key_reference key)
747 {
748 iterator i_element = find(key);
749
750 if (i_element == end())
751 {
752 return 0;
753 }
754 else
755 {
756 i_element->~value_type();
757 storage.release(etl::addressof(*i_element));
758 refmap_t::erase(i_element);
759 ETL_DECREMENT_DEBUG_COUNT;
760 return 1;
761 }
762 }
763
764#if ETL_USING_CPP11
765 //*********************************************************************
766 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
767 size_t erase(K&& key)
768 {
769 iterator i_element = find(etl::forward<K>(key));
770
771 if (i_element == end())
772 {
773 return 0;
774 }
775 else
776 {
777 i_element->~value_type();
778 storage.release(etl::addressof(*i_element));
779 refmap_t::erase(i_element);
780 ETL_DECREMENT_DEBUG_COUNT;
781 return 1;
782 }
783 }
784#endif
785
786 //*********************************************************************
789 //*********************************************************************
790 iterator erase(iterator i_element)
791 {
792 i_element->~value_type();
793 storage.release(etl::addressof(*i_element));
794 ETL_DECREMENT_DEBUG_COUNT;
795 return refmap_t::erase(i_element);
796 }
797
798 //*********************************************************************
801 //*********************************************************************
802 iterator erase(const_iterator i_element)
803 {
804 i_element->~value_type();
805 storage.release(etl::addressof(*i_element));
806 ETL_DECREMENT_DEBUG_COUNT;
807 return refmap_t::erase(i_element);
808 }
809
810 //*********************************************************************
816 //*********************************************************************
817 iterator erase(const_iterator first, const_iterator last)
818 {
819 const_iterator itr = first;
820
821 while (itr != last)
822 {
823 itr->~value_type();
824 storage.release(etl::addressof(*itr));
825 ++itr;
826 ETL_DECREMENT_DEBUG_COUNT;
827 }
828
829 return refmap_t::erase(first, last);
830 }
831
832 //*************************************************************************
834 //*************************************************************************
835 void clear()
836 {
837 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<value_type>::value)
838 {
839 storage.release_all();
840 }
841 else
842 {
843 iterator itr = begin();
844
845 while (itr != end())
846 {
847 itr->~value_type();
848 storage.release(etl::addressof(*itr));
849 ++itr;
850 }
851 }
852
853 ETL_RESET_DEBUG_COUNT;
855 }
856
857 //*********************************************************************
861 //*********************************************************************
862 iterator find(const_key_reference key)
863 {
864 return refmap_t::find(key);
865 }
866
867#if ETL_USING_CPP11
868 //*********************************************************************
869 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
870 iterator find(const K& key)
871 {
872 return refmap_t::find(key);
873 }
874#endif
875
876 //*********************************************************************
880 //*********************************************************************
881 const_iterator find(const_key_reference key) const
882 {
883 return refmap_t::find(key);
884 }
885
886#if ETL_USING_CPP11
887 //*********************************************************************
888 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
889 const_iterator find(const K& key) const
890 {
891 return refmap_t::find(key);
892 }
893#endif
894
895 //*********************************************************************
899 //*********************************************************************
900 size_t count(const_key_reference key) const
901 {
902 return refmap_t::count(key);
903 }
904
905#if ETL_USING_CPP11
906 //*********************************************************************
907 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
908 size_t count(const K& key) const
909 {
910 return refmap_t::count(key);
911 }
912#endif
913
914 //*********************************************************************
918 //*********************************************************************
919 iterator lower_bound(const_key_reference key)
920 {
921 return refmap_t::lower_bound(key);
922 }
923
924#if ETL_USING_CPP11
925 //*********************************************************************
926 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
927 iterator lower_bound(const K& key)
928 {
929 return refmap_t::lower_bound(key);
930 }
931#endif
932
933 //*********************************************************************
937 //*********************************************************************
938 const_iterator lower_bound(const_key_reference key) const
939 {
940 return refmap_t::lower_bound(key);
941 }
942
943#if ETL_USING_CPP11
944 //*********************************************************************
945 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
946 const_iterator lower_bound(const K& key) const
947 {
948 return refmap_t::lower_bound(key);
949 }
950#endif
951
952 //*********************************************************************
956 //*********************************************************************
957 iterator upper_bound(const_key_reference key)
958 {
959 return refmap_t::upper_bound(key);
960 }
961
962#if ETL_USING_CPP11
963 //*********************************************************************
964 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
965 iterator upper_bound(const K& key)
966 {
967 return refmap_t::upper_bound(key);
968 }
969#endif
970
971 //*********************************************************************
975 //*********************************************************************
976 const_iterator upper_bound(const_key_reference key) const
977 {
978 return refmap_t::upper_bound(key);
979 }
980
981#if ETL_USING_CPP11
982 //*********************************************************************
983 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
984 const_iterator upper_bound(const K& key) const
985 {
986 return refmap_t::upper_bound(key);
987 }
988#endif
989
990 //*********************************************************************
994 //*********************************************************************
995 ETL_OR_STD::pair<iterator, iterator> equal_range(const_key_reference key)
996 {
997 return refmap_t::equal_range(key);
998 }
999
1000#if ETL_USING_CPP11
1001 //*********************************************************************
1002 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
1003 ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
1004 {
1005 return refmap_t::equal_range(key);
1006 }
1007#endif
1008
1009 //*********************************************************************
1013 //*********************************************************************
1014 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const_key_reference key) const
1015 {
1016 return refmap_t::equal_range(key);
1017 }
1018
1019#if ETL_USING_CPP11
1020 //*********************************************************************
1021 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
1022 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
1023 {
1024 return refmap_t::equal_range(key);
1025 }
1026#endif
1027
1028 //*************************************************************************
1030 //*************************************************************************
1031 bool contains(const_key_reference key) const
1032 {
1033 return find(key) != end();
1034 }
1035
1036#if ETL_USING_CPP11
1037 //*************************************************************************
1038 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
1039 bool contains(const K& k) const
1040 {
1041 return find(k) != end();
1042 }
1043#endif
1044
1045 //*************************************************************************
1047 //*************************************************************************
1049 {
1050 if (&rhs != this)
1051 {
1052 assign(rhs.cbegin(), rhs.cend());
1053 }
1054
1055 return *this;
1056 }
1057
1058#if ETL_USING_CPP11
1059 //*************************************************************************
1061 //*************************************************************************
1063 {
1064 move_container(etl::move(rhs));
1065
1066 return *this;
1067 }
1068#endif
1069
1070 //*************************************************************************
1073 //*************************************************************************
1074 size_type size() const
1075 {
1076 return refmap_t::size();
1077 }
1078
1079 //*************************************************************************
1082 //*************************************************************************
1083 bool empty() const
1084 {
1085 return refmap_t::empty();
1086 }
1087
1088 //*************************************************************************
1091 //*************************************************************************
1092 bool full() const
1093 {
1094 return refmap_t::full();
1095 }
1096
1097 //*************************************************************************
1100 //*************************************************************************
1101 size_type capacity() const
1102 {
1103 return refmap_t::capacity();
1104 }
1105
1106 //*************************************************************************
1109 //*************************************************************************
1110 size_type max_size() const
1111 {
1112 return refmap_t::max_size();
1113 }
1114
1115 //*************************************************************************
1118 //*************************************************************************
1119 size_t available() const
1120 {
1121 return refmap_t::available();
1122 }
1123
1124 protected:
1125
1126 //*********************************************************************
1128 //*********************************************************************
1129 iflat_map(lookup_t& lookup_, storage_t& storage_)
1130 : refmap_t(lookup_)
1131 , storage(storage_)
1132 {
1133 }
1134
1135#if ETL_USING_CPP11
1136 //*************************************************************************
1139 //*************************************************************************
1140 void move_container(iflat_map&& rhs)
1141 {
1142 if (&rhs != this)
1143 {
1144 this->clear();
1145
1146 etl::iflat_map<TKey, TMapped, TKeyCompare>::iterator first = rhs.begin();
1147 etl::iflat_map<TKey, TMapped, TKeyCompare>::iterator last = rhs.end();
1148
1149 // Move all of the elements.
1150 while (first != last)
1151 {
1152 typename etl::iflat_map<TKey, TMapped, TKeyCompare>::iterator temp = first;
1153 ++temp;
1154
1155 this->insert(etl::move(*first));
1156 first = temp;
1157 }
1158 }
1159 }
1160#endif
1161
1162 private:
1163
1164 // Disable copy construction.
1165 iflat_map(const iflat_map&);
1166
1167 storage_t& storage;
1168
1169 TKeyCompare compare;
1170
1172 ETL_DECLARE_DEBUG_COUNT;
1173
1174#if ETL_USING_CPP11
1175 //*************************************************************************
1176 template <typename TValueType>
1177 ETL_OR_STD::pair<iterator, bool> insert_value(iterator i_element, TValueType&& value)
1178 {
1179 ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full));
1180
1181 value_type* pvalue = storage.allocate<value_type>();
1182 ::new (pvalue) value_type(etl::forward<TValueType>(value));
1183 ETL_INCREMENT_DEBUG_COUNT;
1184 return refmap_t::insert_at(i_element, *pvalue);
1185 }
1186#else
1187 //*************************************************************************
1188 ETL_OR_STD::pair<iterator, bool> insert_value(iterator i_element, const_reference value)
1189 {
1190 ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full));
1191
1192 value_type* pvalue = storage.allocate<value_type>();
1193 ::new (pvalue) value_type(value_type(value));
1194 ETL_INCREMENT_DEBUG_COUNT;
1195 return refmap_t::insert_at(i_element, *pvalue);
1196 }
1197#endif
1198
1199#if ETL_USING_CPP11
1200 //*************************************************************************
1201 ETL_OR_STD::pair<iterator, bool> insert_default_value(iterator i_element, rvalue_key_reference key)
1202 {
1203 ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full));
1204
1205 value_type* pvalue = storage.allocate<value_type>();
1206 ::new ((void*)etl::addressof(pvalue->first)) key_type(etl::move(key));
1207 ::new ((void*)etl::addressof(pvalue->second)) mapped_type();
1208 ETL_INCREMENT_DEBUG_COUNT;
1209
1210 return refmap_t::insert_at(i_element, *pvalue);
1211 }
1212#endif
1213
1214 //*************************************************************************
1215 ETL_OR_STD::pair<iterator, bool> insert_default_value(iterator i_element, const_key_reference key)
1216 {
1217 ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full));
1218
1219 value_type* pvalue = storage.allocate<value_type>();
1220 ::new ((void*)etl::addressof(pvalue->first)) key_type(key);
1221 ::new ((void*)etl::addressof(pvalue->second)) mapped_type();
1222 ETL_INCREMENT_DEBUG_COUNT;
1223
1224 return refmap_t::insert_at(i_element, *pvalue);
1225 }
1226
1227 //*************************************************************************
1229 //*************************************************************************
1230#if defined(ETL_POLYMORPHIC_FLAT_MAP) || defined(ETL_POLYMORPHIC_CONTAINERS)
1231
1232 public:
1233
1234 virtual ~iflat_map() {}
1235#else
1236
1237 protected:
1238
1240#endif
1241 };
1242
1243 //***************************************************************************
1249 //***************************************************************************
1250 template <typename TKey, typename TMapped, typename TKeyCompare>
1252 {
1253 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1254 }
1255
1256 //***************************************************************************
1262 //***************************************************************************
1263 template <typename TKey, typename TMapped, typename TKeyCompare>
1265 {
1266 return !(lhs == rhs);
1267 }
1268
1269 //***************************************************************************
1276 //***************************************************************************
1277 template <typename TKey, typename TValue, const size_t MAX_SIZE_, typename TCompare = etl::less<TKey> >
1278 class flat_map : public etl::iflat_map<TKey, TValue, TCompare>
1279 {
1280 public:
1281
1282 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
1283
1284 //*************************************************************************
1286 //*************************************************************************
1288 : etl::iflat_map<TKey, TValue, TCompare>(lookup, storage)
1289 {
1290 }
1291
1292 //*************************************************************************
1294 //*************************************************************************
1295 flat_map(const flat_map& other)
1296 : etl::iflat_map<TKey, TValue, TCompare>(lookup, storage)
1297 {
1298 this->assign(other.cbegin(), other.cend());
1299 }
1300
1301#if ETL_USING_CPP11
1302 //*************************************************************************
1304 //*************************************************************************
1305 flat_map(flat_map&& other)
1306 : etl::iflat_map<TKey, TValue, TCompare>(lookup, storage)
1307 {
1308 if (&other != this)
1309 {
1310 this->move_container(etl::move(other));
1311 }
1312 }
1313#endif
1314
1315 //*************************************************************************
1320 //*************************************************************************
1321 template <typename TIterator>
1322 flat_map(TIterator first, TIterator last)
1323 : etl::iflat_map<TKey, TValue, TCompare>(lookup, storage)
1324 {
1325 this->assign(first, last);
1326 }
1327
1328#if ETL_HAS_INITIALIZER_LIST
1329 //*************************************************************************
1331 //*************************************************************************
1332 flat_map(std::initializer_list< typename etl::iflat_map<TKey, TValue, TCompare>::value_type> init)
1333 : etl::iflat_map<TKey, TValue, TCompare>(lookup, storage)
1334 {
1335 this->assign(init.begin(), init.end());
1336 }
1337#endif
1338
1339 //*************************************************************************
1341 //*************************************************************************
1343 {
1344 this->clear();
1345 }
1346
1347 //*************************************************************************
1349 //*************************************************************************
1351 {
1352 if (&rhs != this)
1353 {
1354 this->assign(rhs.cbegin(), rhs.cend());
1355 }
1356
1357 return *this;
1358 }
1359
1360#if ETL_USING_CPP11
1361 //*************************************************************************
1363 //*************************************************************************
1364 flat_map& operator=(flat_map&& rhs)
1365 {
1366 if (&rhs != this)
1367 {
1368 this->move_container(etl::move(rhs));
1369 }
1370
1371 return *this;
1372 }
1373#endif
1374
1375 private:
1376
1377 typedef typename etl::iflat_map<TKey, TValue, TCompare>::value_type node_t;
1378
1380 etl::pool<node_t, MAX_SIZE> storage;
1381
1383 etl::vector<node_t*, MAX_SIZE> lookup;
1384 };
1385
1386 template <typename TKey, typename TValue, const size_t MAX_SIZE_, typename TCompare>
1387 ETL_CONSTANT size_t flat_map<TKey, TValue, MAX_SIZE_, TCompare>::MAX_SIZE;
1388
1389 //*************************************************************************
1391 //*************************************************************************
1392#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1393 template <typename... TPairs>
1394 flat_map(TPairs...)
1395 -> flat_map<typename etl::nth_type_t<0, TPairs...>::first_type, typename etl::nth_type_t<0, TPairs...>::second_type, sizeof...(TPairs)>;
1396#endif
1397
1398 //*************************************************************************
1400 //*************************************************************************
1401#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
1402 template <typename TKey, typename TMapped, typename TKeyCompare = etl::less<TKey>, typename... TPairs>
1403 constexpr auto make_flat_map(TPairs&&... pairs) -> etl::flat_map<TKey, TMapped, sizeof...(TPairs), TKeyCompare>
1404 {
1405 return {etl::forward<TPairs>(pairs)...};
1406 }
1407#endif
1408} // namespace etl
1409
1410#endif
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_OR_STD::pair< iterator, bool > emplace(const_key_reference key, const T1 &value1, const T2 &value2)
Emplaces a value to the map.
Definition flat_map.h:490
const_iterator lower_bound(const_key_reference key) const
Definition flat_map.h:938
size_t count(const_key_reference key) const
Definition flat_map.h:900
size_type max_size() const
Definition flat_map.h:1110
reverse_iterator rbegin()
Definition flat_map.h:163
iterator begin()
Definition flat_map.h:109
ETL_OR_STD::pair< iterator, iterator > equal_range(const_key_reference key)
Definition flat_map.h:995
~flat_map()
Destructor.
Definition flat_map.h:1342
void clear()
Clears the flat_map.
Definition flat_map.h:835
iflat_map(lookup_t &lookup_, storage_t &storage_)
Constructor.
Definition flat_map.h:1129
size_t available() const
Definition flat_map.h:1119
iterator find(const_key_reference key)
Definition flat_map.h:862
const_reverse_iterator rbegin() const
Definition flat_map.h:173
const_iterator upper_bound(const_key_reference key) const
Definition flat_map.h:976
mapped_reference at(const_key_reference key)
Definition flat_map.h:260
iterator erase(const_iterator i_element)
\ param i_element Iterator to the element.
Definition flat_map.h:802
~iflat_map()
Destructor.
Definition flat_map.h:1239
iterator upper_bound(const_key_reference key)
Definition flat_map.h:957
ETL_OR_STD::pair< iterator, bool > emplace(const value_type &value)
Emplaces a value to the map.
Definition flat_map.h:414
const_iterator cend() const
Definition flat_map.h:154
const_reverse_iterator crbegin() const
Definition flat_map.h:201
const_mapped_reference at(const_key_reference key) const
Definition flat_map.h:281
flat_map & operator=(const flat_map &rhs)
Assignment operator.
Definition flat_map.h:1350
reverse_iterator rend()
Definition flat_map.h:182
size_type capacity() const
Definition flat_map.h:1101
flat_map()
Constructor.
Definition flat_map.h:1287
iterator erase(iterator i_element)
Definition flat_map.h:790
ETL_OR_STD::pair< iterator, bool > insert(const_reference value)
Definition flat_map.h:327
ETL_OR_STD::pair< iterator, bool > emplace(const_key_reference key, const T1 &value1)
Emplaces a value to the map.
Definition flat_map.h:458
const_iterator cbegin() const
Definition flat_map.h:145
size_t erase(const_key_reference key)
Definition flat_map.h:746
bool contains(const_key_reference key) const
Check if the map contains the key.
Definition flat_map.h:1031
iflat_map & operator=(const iflat_map &rhs)
Assignment operator.
Definition flat_map.h:1048
ETL_OR_STD::pair< iterator, bool > emplace(const_key_reference key, const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Emplaces a value to the map.
Definition flat_map.h:554
const_iterator begin() const
Definition flat_map.h:118
const_iterator end() const
Definition flat_map.h:136
bool full() const
Definition flat_map.h:1092
const_reverse_iterator rend() const
Definition flat_map.h:191
ETL_OR_STD::pair< iterator, bool > try_emplace(const_key_reference key, const T1 &value1, const T2 &value2)
Inserts an element into the flat_map if the key does not exist.
Definition flat_map.h:668
ETL_OR_STD::pair< iterator, bool > try_emplace(const_key_reference key, const T1 &value1)
Inserts an element into the flat_map if the key does not exist.
Definition flat_map.h:643
iterator end()
Definition flat_map.h:127
bool empty() const
Definition flat_map.h:1083
flat_map(const flat_map &other)
Copy constructor.
Definition flat_map.h:1295
ETL_OR_STD::pair< iterator, bool > try_emplace(const_key_reference key, const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Inserts an element into the flat_map if the key does not exist.
Definition flat_map.h:718
iterator erase(const_iterator first, const_iterator last)
Definition flat_map.h:817
const_iterator find(const_key_reference key) const
Definition flat_map.h:881
void insert(TIterator first, TIterator last)
Definition flat_map.h:402
ETL_OR_STD::pair< iterator, bool > try_emplace(const_key_reference key, const T1 &value1, const T2 &value2, const T3 &value3)
Inserts an element into the flat_map if the key does not exist.
Definition flat_map.h:693
void assign(TIterator first, TIterator last)
Definition flat_map.h:305
iterator insert(const_iterator, const_reference value)
Definition flat_map.h:374
const_reverse_iterator crend() const
Definition flat_map.h:210
flat_map(TIterator first, TIterator last)
Definition flat_map.h:1322
ETL_OR_STD::pair< iterator, bool > emplace(const_key_reference key, const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the map.
Definition flat_map.h:522
iterator lower_bound(const_key_reference key)
Definition flat_map.h:919
size_type size() const
Definition flat_map.h:1074
mapped_reference operator[](const_key_reference key)
Definition flat_map.h:240
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(const_key_reference key) const
Definition flat_map.h:1014
Definition flat_map.h:1279
Definition flat_map.h:65
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
T * allocate()
Definition ipool.h:334
void release(const void *const p_object)
Definition ipool.h:461
Definition ipool.h:110
mapped_type & at(key_parameter_t key)
Definition reference_flat_map.h:474
iterator begin()
Definition reference_flat_map.h:356
void clear()
Definition reference_flat_map.h:680
ETL_OR_STD::pair< iterator, bool > insert_at(iterator i_element, value_type &value)
Definition reference_flat_map.h:1006
const_reverse_iterator crbegin() const
Definition reference_flat_map.h:452
reverse_iterator rend()
Definition reference_flat_map.h:431
size_t count(key_parameter_t key) const
Definition reference_flat_map.h:784
iterator end()
Definition reference_flat_map.h:374
const_iterator cbegin() const
Definition reference_flat_map.h:392
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition reference_flat_map.h:879
size_t available() const
Definition reference_flat_map.h:986
const_reverse_iterator crend() const
Definition reference_flat_map.h:462
size_type max_size() const
Definition reference_flat_map.h:977
bool empty() const
Definition reference_flat_map.h:950
iterator lower_bound(key_parameter_t key)
Definition reference_flat_map.h:803
reverse_iterator rbegin()
Definition reference_flat_map.h:411
iterator upper_bound(key_parameter_t key)
Definition reference_flat_map.h:841
size_type size() const
Definition reference_flat_map.h:941
iterator find(key_parameter_t key)
Definition reference_flat_map.h:690
const_iterator cend() const
Definition reference_flat_map.h:401
size_t erase(key_parameter_t key)
Definition reference_flat_map.h:613
bool full() const
Definition reference_flat_map.h:959
size_type capacity() const
Definition reference_flat_map.h:968
Definition reference_flat_map.h:79
Definition reference_flat_map.h:110
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_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
TContainer::iterator end(TContainer &container)
Definition iterator.h:1166
Definition compare.h:51
iterator
Definition iterator.h:482
pair holds two objects of arbitrary type
Definition utility.h:176