Embedded Template Library  1.0
reference_flat_multimap.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2017 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_REFERENCE_FLAT_MULTIMAP_BASE_INCLUDED
32 #define ETL_REFERENCE_FLAT_MULTIMAP_BASE_INCLUDED
33 
34 #include <stddef.h>
35 
36 #include "platform.h"
37 #include "exception.h"
38 #include "error_handler.h"
39 #include "debug_count.h"
40 #include "vector.h"
41 #include "iterator.h"
42 
43 #undef ETL_FILE
44 #define ETL_FILE "31"
45 
46 namespace etl
47 {
48  //***************************************************************************
51  //***************************************************************************
53  {
54  public:
55 
56  flat_multimap_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
57  : exception(reason_, file_name_, line_number_)
58  {
59  }
60  };
61 
62  //***************************************************************************
65  //***************************************************************************
67  {
68  public:
69 
70  flat_multimap_full(string_type file_name_, numeric_type line_number_)
71  : flat_multimap_exception(ETL_ERROR_TEXT("flat_multimap:full", ETL_FILE"A"), file_name_, line_number_)
72  {
73  }
74  };
75 
76  //***************************************************************************
80  //***************************************************************************
81  template <typename TKey, typename TMapped, typename TKeyCompare = etl::less<TKey> >
83  {
84  public:
85 
86  typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
87 
88  protected:
89 
91 
92  public:
93 
94  typedef TKey key_type;
95  typedef TMapped mapped_type;
96  typedef TKeyCompare key_compare;
97  typedef value_type& reference;
98  typedef const value_type& const_reference;
99  typedef value_type* pointer;
100  typedef const value_type* const_pointer;
101  typedef size_t size_type;
102 
103  //*************************************************************************
104  class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
105  {
106  public:
107 
108  friend class ireference_flat_multimap;
109  friend class const_iterator;
110 
111  iterator()
112  {
113  }
114 
115  iterator(typename lookup_t::iterator ilookup_)
116  : ilookup(ilookup_)
117  {
118  }
119 
120  iterator(const iterator& other)
121  : ilookup(other.ilookup)
122  {
123  }
124 
125  iterator& operator =(const iterator& other)
126  {
127  ilookup = other.ilookup;
128  return *this;
129  }
130 
131  iterator& operator ++()
132  {
133  ++ilookup;
134  return *this;
135  }
136 
137  iterator operator ++(int)
138  {
139  iterator temp(*this);
140  ++ilookup;
141  return temp;
142  }
143 
144  iterator& operator --()
145  {
146  --ilookup;
147  return *this;
148  }
149 
150  iterator operator --(int)
151  {
152  iterator temp(*this);
153  --ilookup;
154  return temp;
155  }
156 
157  reference operator *()
158  {
159  return *(*ilookup);
160  }
161 
162  const_reference operator *() const
163  {
164  return *(*ilookup);
165  }
166 
167  pointer operator &()
168  {
169  return etl::addressof(*(*ilookup));
170  }
171 
172  const_pointer operator &() const
173  {
174  return &(*(*ilookup));
175  }
176 
177  pointer operator ->()
178  {
179  return etl::addressof(*(*ilookup));
180  }
181 
182  const_pointer operator ->() const
183  {
184  return etl::addressof(*(*ilookup));
185  }
186 
187  friend bool operator == (const iterator& lhs, const iterator& rhs)
188  {
189  return lhs.ilookup == rhs.ilookup;
190  }
191 
192  friend bool operator != (const iterator& lhs, const iterator& rhs)
193  {
194  return !(lhs == rhs);
195  }
196 
197  private:
198 
199  typename lookup_t::iterator ilookup;
200  };
201 
202  //*************************************************************************
203  class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
204  {
205  public:
206 
207  friend class ireference_flat_multimap;
208 
210  {
211  }
212 
213  const_iterator(typename lookup_t::const_iterator ilookup_)
214  : ilookup(ilookup_)
215  {
216  }
217 
219  : ilookup(other.ilookup)
220  {
221  }
222 
223  const_iterator(const const_iterator& other)
224  : ilookup(other.ilookup)
225  {
226  }
227 
228  const_iterator& operator =(const iterator& other)
229  {
230  ilookup = other.ilookup;
231  return *this;
232  }
233 
234  const_iterator& operator =(const const_iterator& other)
235  {
236  ilookup = other.ilookup;
237  return *this;
238  }
239 
240  const_iterator& operator ++()
241  {
242  ++ilookup;
243  return *this;
244  }
245 
246  const_iterator operator ++(int)
247  {
248  const_iterator temp(*this);
249  ++ilookup;
250  return temp;
251  }
252 
253  const_iterator& operator --()
254  {
255  --ilookup;
256  return *this;
257  }
258 
259  const_iterator operator --(int)
260  {
261  const_iterator temp(*this);
262  --ilookup;
263  return temp;
264  }
265 
266  const_reference operator *() const
267  {
268  return *(*ilookup);
269  }
270 
271  const_pointer operator &() const
272  {
273  return etl::addressof(*(*ilookup));
274  }
275 
276  const_pointer operator ->() const
277  {
278  return etl::addressof(*(*ilookup));
279  }
280 
281  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
282  {
283  return lhs.ilookup == rhs.ilookup;
284  }
285 
286  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
287  {
288  return !(lhs == rhs);
289  }
290 
291  private:
292 
293  typename lookup_t::const_iterator ilookup;
294  };
295 
296  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
297  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
298  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
299 
300  protected:
301 
302  typedef typename etl::parameter_type<TKey>::type key_parameter_t;
303 
304  private:
305 
306  //*********************************************************************
308  //*********************************************************************
309  class Compare
310  {
311  public:
312 
313  bool operator ()(const value_type& element, key_type key) const
314  {
315  return comp(element.first, key);
316  }
317 
318  bool operator ()(key_type key, const value_type& element) const
319  {
320  return comp(key, element.first);
321  }
322 
323  key_compare comp;
324  };
325 
326  public:
327 
328  //*********************************************************************
331  //*********************************************************************
333  {
334  return iterator(lookup.begin());
335  }
336 
337  //*********************************************************************
340  //*********************************************************************
342  {
343  return const_iterator(lookup.begin());
344  }
345 
346  //*********************************************************************
349  //*********************************************************************
351  {
352  return iterator(lookup.end());
353  }
354 
355  //*********************************************************************
358  //*********************************************************************
360  {
361  return const_iterator(lookup.end());
362  }
363 
364  //*********************************************************************
367  //*********************************************************************
369  {
370  return const_iterator(lookup.cbegin());
371  }
372 
373  //*********************************************************************
376  //*********************************************************************
378  {
379  return const_iterator(lookup.cend());
380  }
381 
382  //*********************************************************************
385  //*********************************************************************
386  reverse_iterator rbegin()
387  {
388  return reverse_iterator(lookup.rbegin());
389  }
390 
391  //*********************************************************************
394  //*********************************************************************
395  const_reverse_iterator rbegin() const
396  {
397  return const_reverse_iterator(lookup.rbegin());
398  }
399 
400  //*********************************************************************
403  //*********************************************************************
404  reverse_iterator rend()
405  {
406  return reverse_iterator(lookup.rend());
407  }
408 
409  //*********************************************************************
412  //*********************************************************************
413  const_reverse_iterator rend() const
414  {
415  return const_reverse_iterator(lookup.rend());
416  }
417 
418  //*********************************************************************
421  //*********************************************************************
422  const_reverse_iterator crbegin() const
423  {
424  return const_reverse_iterator(lookup.crbegin());
425  }
426 
427  //*********************************************************************
430  //*********************************************************************
431  const_reverse_iterator crend() const
432  {
433  return const_reverse_iterator(lookup.crend());
434  }
435 
436  //*********************************************************************
442  //*********************************************************************
443  template <typename TIterator>
444  void assign(TIterator first, TIterator last)
445  {
446 #if defined(ETL_DEBUG)
447  difference_type d = etl::distance(first, last);
448  ETL_ASSERT(d <= difference_type(capacity()), ETL_ERROR(flat_multimap_full));
449 #endif
450 
451  clear();
452 
453  while (first != last)
454  {
455  insert(*first++);
456  }
457  }
458 
459  //*********************************************************************
463  //*********************************************************************
464  ETL_OR_STD::pair<iterator, bool> insert(value_type& value)
465  {
466  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multimap_full));
467 
468  ETL_OR_STD::pair<iterator, bool> result(end(), false);
469 
470  iterator i_element = lower_bound(value.first);
471 
472  return insert_at(i_element, value);
473  }
474 
475  //*********************************************************************
480  //*********************************************************************
481  iterator insert(iterator position, const value_type& value)
482  {
483  return insert(value).first;
484  }
485 
486  //*********************************************************************
492  //*********************************************************************
493  template <class TIterator>
494  void insert(TIterator first, TIterator last)
495  {
496  while (first != last)
497  {
498  insert(*first++);
499  }
500  }
501 
502  //*********************************************************************
506  //*********************************************************************
507  size_t erase(key_parameter_t key)
508  {
509  ETL_OR_STD::pair<iterator, iterator> range = equal_range(key);
510 
511  if (range.first == end())
512  {
513  return 0;
514  }
515  else
516  {
517  size_t d = etl::distance(range.first, range.second);
518  erase(range.first, range.second);
519  return d;
520  }
521  }
522 
523  //*********************************************************************
526  //*********************************************************************
527  void erase(iterator i_element)
528  {
529  lookup.erase(i_element.ilookup);
530  }
531 
532  //*********************************************************************
538  //*********************************************************************
539  void erase(iterator first, iterator last)
540  {
541  lookup.erase(first.ilookup, last.ilookup);
542  }
543 
544  //*************************************************************************
546  //*************************************************************************
547  void clear()
548  {
549  lookup.clear();
550  }
551 
552  //*********************************************************************
556  //*********************************************************************
557  iterator find(key_parameter_t key)
558  {
559  iterator itr = lower_bound(key);
560 
561  if (itr != end())
562  {
563  if (!key_compare()(itr->first, key) && !key_compare()(key, itr->first))
564  {
565  return itr;
566  }
567  else
568  {
569  return end();
570  }
571  }
572 
573  return end();
574  }
575 
576  //*********************************************************************
580  //*********************************************************************
581  const_iterator find(key_parameter_t key) const
582  {
583  const_iterator itr = lower_bound(key);
584 
585  if (itr != end())
586  {
587  if (!key_compare()(itr->first, key) && !key_compare()(key, itr->first))
588  {
589  return itr;
590  }
591  else
592  {
593  return end();
594  }
595  }
596 
597  return end();
598  }
599 
600  //*********************************************************************
604  //*********************************************************************
605  size_t count(key_parameter_t key) const
606  {
607  ETL_OR_STD::pair<const_iterator, const_iterator> range = equal_range(key);
608 
609  return etl::distance(range.first, range.second);
610  }
611 
612  //*********************************************************************
616  //*********************************************************************
617  iterator lower_bound(key_parameter_t key)
618  {
619  return etl::lower_bound(begin(), end(), key, compare);
620  }
621 
622  //*********************************************************************
626  //*********************************************************************
627  const_iterator lower_bound(key_parameter_t key) const
628  {
629  return etl::lower_bound(cbegin(), cend(), key, compare);
630  }
631 
632  //*********************************************************************
636  //*********************************************************************
637  iterator upper_bound(key_parameter_t key)
638  {
639  return etl::upper_bound(begin(), end(), key, compare);
640  }
641 
642  //*********************************************************************
646  //*********************************************************************
647  const_iterator upper_bound(key_parameter_t key) const
648  {
649  return etl::upper_bound(begin(), end(), key, compare);
650  }
651 
652  //*********************************************************************
656  //*********************************************************************
657  ETL_OR_STD::pair<iterator, iterator> equal_range(key_parameter_t key)
658  {
659  iterator i_lower = etl::lower_bound(begin(), end(), key, compare);
660 
661  return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, end(), key, compare));
662  }
663 
664  //*********************************************************************
668  //*********************************************************************
669  ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(key_parameter_t key) const
670  {
671  const_iterator i_lower = etl::lower_bound(cbegin(), cend(), key, compare);
672 
673  return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, cend(), key, compare));
674  }
675 
676  //*************************************************************************
679  //*************************************************************************
680  size_type size() const
681  {
682  return lookup.size();
683  }
684 
685  //*************************************************************************
688  //*************************************************************************
689  bool empty() const
690  {
691  return lookup.empty();
692  }
693 
694  //*************************************************************************
697  //*************************************************************************
698  bool full() const
699  {
700  return lookup.full();
701  }
702 
703  //*************************************************************************
706  //*************************************************************************
707  size_type capacity() const
708  {
709  return lookup.capacity();
710  }
711 
712  //*************************************************************************
715  //*************************************************************************
716  size_type max_size() const
717  {
718  return lookup.max_size();
719  }
720 
721  //*************************************************************************
724  //*************************************************************************
725  size_t available() const
726  {
727  return lookup.available();
728  }
729 
730  protected:
731 
732  //*********************************************************************
734  //*********************************************************************
736  : lookup(lookup_)
737  {
738  }
739 
740  //*********************************************************************
744  //*********************************************************************
745  ETL_OR_STD::pair<iterator, bool> insert_at(iterator i_element, value_type& value)
746  {
747  ETL_OR_STD::pair<iterator, bool> result(end(), false);
748 
749  if (i_element == end())
750  {
751  // At the end.
752  lookup.push_back(&value);
753  result.first = --end();
754  result.second = true;
755  }
756  else
757  {
758  // Not at the end.
759  lookup.insert(i_element.ilookup, &value);
760  result.first = i_element;
761  result.second = true;
762  }
763 
764  return result;
765  }
766 
767  private:
768 
769  // Disable copy construction and assignment.
772 
773  lookup_t& lookup;
774 
775  Compare compare;
776 
777  //*************************************************************************
779  //*************************************************************************
780 #if defined(ETL_POLYMORPHIC_REFERENCE_FLAT_MULTIMAP) || defined(ETL_POLYMORPHIC_CONTAINERS)
781  public:
782  virtual ~ireference_flat_multimap()
783  {
784  }
785 #else
786  protected:
788  {
789  }
790 #endif
791  };
792 
793  //***************************************************************************
799  //***************************************************************************
800  template <typename TKey, typename TMapped, typename TKeyCompare>
802  {
803  return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
804  }
805 
806  //***************************************************************************
812  //***************************************************************************
813  template <typename TKey, typename TMapped, typename TKeyCompare>
815  {
816  return !(lhs == rhs);
817  }
818 
819  //***************************************************************************
826  //***************************************************************************
827  template <typename TKey, typename TValue, const size_t MAX_SIZE_, typename TCompare = etl::less<TKey> >
828  class reference_flat_multimap : public ireference_flat_multimap<TKey, TValue, TCompare>
829  {
830  public:
831 
832  static const size_t MAX_SIZE = MAX_SIZE_;
833 
834  //*************************************************************************
836  //*************************************************************************
838  : ireference_flat_multimap<TKey, TValue, TCompare>(lookup)
839  {
840  }
841 
842  //*************************************************************************
844  //*************************************************************************
846  : ireference_flat_multimap<TKey, TValue, TCompare>(lookup)
847  {
849  }
850 
851  //*************************************************************************
856  //*************************************************************************
857  template <typename TIterator>
858  reference_flat_multimap(TIterator first, TIterator last)
859  : ireference_flat_multimap<TKey, TValue, TCompare>(lookup)
860  {
862  }
863 
864  //*************************************************************************
866  //*************************************************************************
868  {
870  }
871 
872  private:
873 
874  typedef typename ireference_flat_multimap<TKey, TValue, TCompare>::value_type node_t;
875 
876  // The vector that stores pointers to the nodes.
878  };
879 }
880 
881 #undef ETL_FILE
882 
883 #endif
Definition: reference_flat_multimap.h:53
Definition: reference_flat_multimap.h:67
Definition: reference_flat_multimap.h:204
Definition: reference_flat_multimap.h:105
Definition: reference_flat_multimap.h:83
const_reverse_iterator crbegin() const
Definition: reference_flat_multimap.h:422
size_t count(key_parameter_t key) const
Definition: reference_flat_multimap.h:605
iterator lower_bound(key_parameter_t key)
Definition: reference_flat_multimap.h:617
const_iterator find(key_parameter_t key) const
Definition: reference_flat_multimap.h:581
reverse_iterator rbegin()
Definition: reference_flat_multimap.h:386
const_reverse_iterator crend() const
Definition: reference_flat_multimap.h:431
iterator upper_bound(key_parameter_t key)
Definition: reference_flat_multimap.h:637
bool empty() const
Definition: reference_flat_multimap.h:689
const_reverse_iterator rbegin() const
Definition: reference_flat_multimap.h:395
const_iterator cbegin() const
Definition: reference_flat_multimap.h:368
size_type size() const
Definition: reference_flat_multimap.h:680
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition: reference_flat_multimap.h:657
size_t available() const
Definition: reference_flat_multimap.h:725
ETL_OR_STD::pair< iterator, bool > insert(value_type &value)
Definition: reference_flat_multimap.h:464
bool full() const
Definition: reference_flat_multimap.h:698
size_t erase(key_parameter_t key)
Definition: reference_flat_multimap.h:507
~ireference_flat_multimap()
Destructor.
Definition: reference_flat_multimap.h:787
const_iterator end() const
Definition: reference_flat_multimap.h:359
void erase(iterator i_element)
Definition: reference_flat_multimap.h:527
ETL_OR_STD::pair< iterator, bool > insert_at(iterator i_element, value_type &value)
Definition: reference_flat_multimap.h:745
const_iterator upper_bound(key_parameter_t key) const
Definition: reference_flat_multimap.h:647
const_reverse_iterator rend() const
Definition: reference_flat_multimap.h:413
iterator begin()
Definition: reference_flat_multimap.h:332
iterator insert(iterator position, const value_type &value)
Definition: reference_flat_multimap.h:481
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(key_parameter_t key) const
Definition: reference_flat_multimap.h:669
iterator end()
Definition: reference_flat_multimap.h:350
iterator find(key_parameter_t key)
Definition: reference_flat_multimap.h:557
const_iterator cend() const
Definition: reference_flat_multimap.h:377
size_type max_size() const
Definition: reference_flat_multimap.h:716
void clear()
Clears the reference_flat_multimap.
Definition: reference_flat_multimap.h:547
void insert(TIterator first, TIterator last)
Definition: reference_flat_multimap.h:494
ireference_flat_multimap(lookup_t &lookup_)
Constructor.
Definition: reference_flat_multimap.h:735
void assign(TIterator first, TIterator last)
Definition: reference_flat_multimap.h:444
size_type capacity() const
Definition: reference_flat_multimap.h:707
reverse_iterator rend()
Definition: reference_flat_multimap.h:404
const_iterator lower_bound(key_parameter_t key) const
Definition: reference_flat_multimap.h:627
void erase(iterator first, iterator last)
Definition: reference_flat_multimap.h:539
const_iterator begin() const
Definition: reference_flat_multimap.h:341
Definition: reference_flat_multimap.h:829
~reference_flat_multimap()
Destructor.
Definition: reference_flat_multimap.h:867
reference_flat_multimap()
Constructor.
Definition: reference_flat_multimap.h:837
reference_flat_multimap(const reference_flat_multimap &other)
Copy constructor.
Definition: reference_flat_multimap.h:845
reference_flat_multimap(TIterator first, TIterator last)
Definition: reference_flat_multimap.h:858
bitset< MAXN > operator&(const bitset< MAXN > &lhs, const bitset< MAXN > &rhs)
Definition: bitset.h:1157
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
T * addressof(T &t)
Definition: memory.h:61
iterator begin()
Definition: vector.h:108
size_type max_size() const
Definition: vector_base.h:143
void push_back(const_reference value)
Definition: vector.h:408
const_reverse_iterator crbegin() const
Definition: vector.h:198
reverse_iterator rend()
Definition: vector.h:180
size_type capacity() const
Definition: vector_base.h:134
iterator insert(iterator position, const_reference value)
Definition: vector.h:531
const_iterator cend() const
Definition: vector.h:153
void clear()
Clears the vector.
Definition: vector.h:398
iterator end()
Definition: vector.h:126
const_reverse_iterator crend() const
Definition: vector.h:207
const_iterator cbegin() const
Definition: vector.h:144
bool full() const
Definition: vector.h:914
size_type size() const
Definition: vector.h:896
iterator erase(iterator i_element)
Definition: vector.h:820
bool empty() const
Definition: vector.h:905
size_t available() const
Definition: vector.h:923
reverse_iterator rbegin()
Definition: vector.h:162
Definition: vector.h:80
Definition: absolute.h:37
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
bool operator==(const etl::ireference_flat_multimap< TKey, TMapped, TKeyCompare > &lhs, const etl::ireference_flat_multimap< TKey, TMapped, TKeyCompare > &rhs)
Definition: reference_flat_multimap.h:801
bool operator!=(const etl::ireference_flat_multimap< TKey, TMapped, TKeyCompare > &lhs, const etl::ireference_flat_multimap< TKey, TMapped, TKeyCompare > &rhs)
Definition: reference_flat_multimap.h:814
Definition: compare.h:52
iterator
Definition: iterator.h:422
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, const T & >::type type
By default fundamental and pointer types are passed by value.
Definition: parameter_type.h:48