Embedded Template Library  1.0
reference_flat_multiset.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_MULTISET_INCLUDED
32 #define ETL_REFERENCE_FLAT_MULTISET_INCLUDED
33 
34 #include <stddef.h>
35 
36 #include "platform.h"
37 
38 #include "algorithm.h"
39 #include "iterator.h"
40 #include "functional.h"
41 #include "utility.h"
42 
43 #include "type_traits.h"
44 #include "vector.h"
45 #include "pool.h"
46 #include "error_handler.h"
47 #include "exception.h"
48 
49 #undef ETL_FILE
50 #define ETL_FILE "33"
51 
52 namespace etl
53 {
54  //***************************************************************************
57  //***************************************************************************
59  {
60  public:
61 
62  flat_multiset_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
63  : exception(reason_, file_name_, line_number_)
64  {
65  }
66  };
67 
68  //***************************************************************************
71  //***************************************************************************
73  {
74  public:
75 
76  flat_multiset_full(string_type file_name_, numeric_type line_number_)
77  : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:full", ETL_FILE"A"), file_name_, line_number_)
78  {
79  }
80  };
81 
82  //***************************************************************************
85  //***************************************************************************
87  {
88  public:
89 
90  flat_multiset_iterator(string_type file_name_, numeric_type line_number_)
91  : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:iterator", ETL_FILE"C"), file_name_, line_number_)
92  {
93  }
94  };
95 
96  //***************************************************************************
100  //***************************************************************************
101  template <typename T, typename TKeyCompare = etl::less<T> >
103  {
104  public:
105 
106  typedef T key_type;
107  typedef T value_type;
108  typedef TKeyCompare key_compare;
109  typedef value_type& reference;
110  typedef const value_type& const_reference;
111  typedef value_type* pointer;
112  typedef const value_type* const_pointer;
113  typedef size_t size_type;
114 
115  protected:
116 
118 
119  public:
120 
121  //*************************************************************************
122  class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
123  {
124  public:
125 
126  friend class ireference_flat_multiset;
127 
128  iterator()
129  {
130  }
131 
132  iterator(typename lookup_t::iterator ilookup_)
133  : ilookup(ilookup_)
134  {
135  }
136 
137  iterator(const iterator& other)
138  : ilookup(other.ilookup)
139  {
140  }
141 
142  iterator& operator =(const iterator& other)
143  {
144  ilookup = other.ilookup;
145  return *this;
146  }
147 
148  iterator& operator ++()
149  {
150  ++ilookup;
151  return *this;
152  }
153 
154  iterator operator ++(int)
155  {
156  iterator temp(*this);
157  ++ilookup;
158  return temp;
159  }
160 
161  iterator& operator --()
162  {
163  --ilookup;
164  return *this;
165  }
166 
167  iterator operator --(int)
168  {
169  iterator temp(*this);
170  --ilookup;
171  return temp;
172  }
173 
174  reference operator *()
175  {
176  return *(*ilookup);
177  }
178 
179  const_reference operator *() const
180  {
181  return *(*ilookup);
182  }
183 
184  pointer operator &()
185  {
186  return etl::addressof(*(*ilookup));
187  }
188 
189  const_pointer operator &() const
190  {
191  return &(*(*ilookup));
192  }
193 
194  pointer operator ->()
195  {
196  return etl::addressof(*(*ilookup));
197  }
198 
199  const_pointer operator ->() const
200  {
201  return etl::addressof(*(*ilookup));
202  }
203 
204  friend bool operator == (const iterator& lhs, const iterator& rhs)
205  {
206  return lhs.ilookup == rhs.ilookup;
207  }
208 
209  friend bool operator != (const iterator& lhs, const iterator& rhs)
210  {
211  return !(lhs == rhs);
212  }
213 
214  private:
215 
216  typename lookup_t::iterator ilookup;
217  };
218 
219  //*************************************************************************
220  class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
221  {
222  public:
223 
224  friend class ireference_flat_multiset;
225 
227  {
228  }
229 
230  const_iterator(typename lookup_t::const_iterator ilookup_)
231  : ilookup(ilookup_)
232  {
233  }
234 
236  : ilookup(other.ilookup)
237  {
238  }
239 
240  const_iterator(const const_iterator& other)
241  : ilookup(other.ilookup)
242  {
243  }
244 
245  const_iterator& operator =(const iterator& other)
246  {
247  ilookup = other.ilookup;
248  return *this;
249  }
250 
251  const_iterator& operator =(const const_iterator& other)
252  {
253  ilookup = other.ilookup;
254  return *this;
255  }
256 
257  const_iterator& operator ++()
258  {
259  ++ilookup;
260  return *this;
261  }
262 
263  const_iterator operator ++(int)
264  {
265  const_iterator temp(*this);
266  ++ilookup;
267  return temp;
268  }
269 
270  const_iterator& operator --()
271  {
272  --ilookup;
273  return *this;
274  }
275 
276  const_iterator operator --(int)
277  {
278  const_iterator temp(*this);
279  --ilookup;
280  return temp;
281  }
282 
283  const_reference operator *() const
284  {
285  return *(*ilookup);
286  }
287 
288  const_pointer operator &() const
289  {
290  return etl::addressof(*(*ilookup));
291  }
292 
293  const_pointer operator ->() const
294  {
295  return etl::addressof(*(*ilookup));
296  }
297 
298  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
299  {
300  return lhs.ilookup == rhs.ilookup;
301  }
302 
303  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
304  {
305  return !(lhs == rhs);
306  }
307 
308  private:
309 
310  typename lookup_t::const_iterator ilookup;
311  };
312 
313  protected:
314 
315  typedef typename etl::parameter_type<T>::type parameter_t;
316 
317  public:
318 
319  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
320  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
321  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
322 
323  //*********************************************************************
326  //*********************************************************************
328  {
329  return iterator(lookup.begin());
330  }
331 
332  //*********************************************************************
335  //*********************************************************************
337  {
338  return const_iterator(lookup.begin());
339  }
340 
341  //*********************************************************************
344  //*********************************************************************
346  {
347  return iterator(lookup.end());
348  }
349 
350  //*********************************************************************
353  //*********************************************************************
355  {
356  return const_iterator(lookup.end());
357  }
358 
359  //*********************************************************************
362  //*********************************************************************
364  {
365  return const_iterator(lookup.cbegin());
366  }
367 
368  //*********************************************************************
371  //*********************************************************************
373  {
374  return const_iterator(lookup.cend());
375  }
376 
377  //*********************************************************************
380  //*********************************************************************
381  reverse_iterator rbegin()
382  {
383  return reverse_iterator(lookup.rbegin());
384  }
385 
386  //*********************************************************************
389  //*********************************************************************
390  const_reverse_iterator rbegin() const
391  {
392  return const_reverse_iterator(lookup.rbegin());
393  }
394 
395  //*********************************************************************
398  //*********************************************************************
399  reverse_iterator rend()
400  {
401  return reverse_iterator(lookup.rend());
402  }
403 
404  //*********************************************************************
407  //*********************************************************************
408  const_reverse_iterator rend() const
409  {
410  return const_reverse_iterator(lookup.rend());
411  }
412 
413  //*********************************************************************
416  //*********************************************************************
417  const_reverse_iterator crbegin() const
418  {
419  return const_reverse_iterator(lookup.crbegin());
420  }
421 
422  //*********************************************************************
425  //*********************************************************************
426  const_reverse_iterator crend() const
427  {
428  return const_reverse_iterator(lookup.crend());
429  }
430 
431  //*********************************************************************
437  //*********************************************************************
438  template <typename TIterator>
439  void assign(TIterator first, TIterator last)
440  {
441 #if defined(ETL_DEBUG)
442  difference_type d = etl::distance(first, last);
443  ETL_ASSERT(d <= difference_type(capacity()), ETL_ERROR(flat_multiset_full));
444 #endif
445 
446  clear();
447 
448  while (first != last)
449  {
450  insert(*first++);
451  }
452  }
453 
454  //*********************************************************************
458  //*********************************************************************
459  ETL_OR_STD::pair<iterator, bool> insert(value_type& value)
460  {
461  ETL_OR_STD::pair<iterator, bool> result(end(), false);
462 
463  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
464 
465  iterator i_element = etl::lower_bound(begin(), end(), value, compare);
466 
467  if (i_element == end())
468  {
469  // At the end. Doesn't exist.
470  lookup.push_back(&value);
471  result.first = --end();
472  result.second = true;
473  }
474  else
475  {
476  // Not at the end.
477  lookup.insert(i_element.ilookup, &value);
478  result.first = i_element;
479  result.second = true;
480  }
481 
482  return result;
483  }
484 
485  //*********************************************************************
490  //*********************************************************************
491  iterator insert(iterator position, value_type& value)
492  {
493  return insert(value).first;
494  }
495 
496  //*********************************************************************
502  //*********************************************************************
503  template <class TIterator>
504  void insert(TIterator first, TIterator last)
505  {
506  while (first != last)
507  {
508  insert(*first++);
509  }
510  }
511 
512  //*********************************************************************
516  //*********************************************************************
517  size_t erase(parameter_t key)
518  {
519  ETL_OR_STD::pair<iterator, iterator> range = equal_range(key);
520 
521  if (range.first == end())
522  {
523  return 0;
524  }
525  else
526  {
527  size_t d = etl::distance(range.first, range.second);
528  erase(range.first, range.second);
529  return d;
530  }
531  }
532 
533  //*********************************************************************
536  //*********************************************************************
537  void erase(iterator i_element)
538  {
539  lookup.erase(i_element.ilookup);
540  }
541 
542  //*********************************************************************
548  //*********************************************************************
549  void erase(iterator first, iterator last)
550  {
551  lookup.erase(first.ilookup, last.ilookup);
552  }
553 
554  //*************************************************************************
556  //*************************************************************************
557  void clear()
558  {
559  lookup.clear();
560  }
561 
562  //*********************************************************************
566  //*********************************************************************
567  iterator find(parameter_t key)
568  {
569  iterator itr = etl::lower_bound(begin(), end(), key, compare);
570 
571  if (itr != end())
572  {
573  if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
574  {
575  return itr;
576  }
577  else
578  {
579  return end();
580  }
581  }
582 
583  return end();
584  }
585 
586  //*********************************************************************
590  //*********************************************************************
591  const_iterator find(parameter_t key) const
592  {
593  const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
594 
595  if (itr != end())
596  {
597  if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
598  {
599  return itr;
600  }
601  else
602  {
603  return end();
604  }
605  }
606 
607  return end();
608  }
609 
610  //*********************************************************************
614  //*********************************************************************
615  size_t count(parameter_t key) const
616  {
617  ETL_OR_STD::pair<const_iterator, const_iterator> range = equal_range(key);
618 
619  return etl::distance(range.first, range.second);
620  }
621 
622  //*********************************************************************
626  //*********************************************************************
627  iterator lower_bound(parameter_t key)
628  {
629  return etl::lower_bound(begin(), end(), key, compare);
630  }
631 
632  //*********************************************************************
636  //*********************************************************************
637  const_iterator lower_bound(parameter_t key) const
638  {
639  return etl::lower_bound(cbegin(), cend(), key, compare);
640  }
641 
642  //*********************************************************************
646  //*********************************************************************
647  iterator upper_bound(parameter_t key)
648  {
649  return etl::upper_bound(begin(), end(), key, compare);
650  }
651 
652  //*********************************************************************
656  //*********************************************************************
657  const_iterator upper_bound(parameter_t key) const
658  {
659  return etl::upper_bound(cbegin(), cend(), key, compare);
660  }
661 
662  //*********************************************************************
666  //*********************************************************************
667  ETL_OR_STD::pair<iterator, iterator> equal_range(parameter_t key)
668  {
669  return etl::equal_range(begin(), end(), key, compare);
670  }
671 
672  //*********************************************************************
676  //*********************************************************************
677  ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
678  {
679  return etl::equal_range(begin(), end(), key, compare);
680  }
681 
682  //*************************************************************************
685  //*************************************************************************
686  size_type size() const
687  {
688  return lookup.size();
689  }
690 
691  //*************************************************************************
694  //*************************************************************************
695  bool empty() const
696  {
697  return lookup.empty();
698  }
699 
700  //*************************************************************************
703  //*************************************************************************
704  bool full() const
705  {
706  return lookup.full();
707  }
708 
709  //*************************************************************************
712  //*************************************************************************
713  size_type capacity() const
714  {
715  return lookup.capacity();
716  }
717 
718  //*************************************************************************
721  //*************************************************************************
722  size_type max_size() const
723  {
724  return lookup.max_size();
725  }
726 
727  //*************************************************************************
730  //*************************************************************************
731  size_t available() const
732  {
733  return lookup.available();
734  }
735 
736  protected:
737 
738  //*********************************************************************
740  //*********************************************************************
742  : lookup(lookup_)
743  {
744  }
745 
746  //*********************************************************************
750  //*********************************************************************
751  ETL_OR_STD::pair<iterator, bool> insert_at(iterator i_element, reference value)
752  {
753  ETL_OR_STD::pair<iterator, bool> result(end(), false);
754 
755  if (i_element == end())
756  {
757  // At the end.
758  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
759 
760  lookup.push_back(&value);
761  result.first = --end();
762  result.second = true;
763  }
764  else
765  {
766  // Not at the end.
767  result.first = i_element;
768 
769  // A new one.
770  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
771  lookup.insert(i_element.ilookup, &value);
772  result.second = true;
773  }
774 
775  return result;
776  }
777 
778  private:
779 
780  // Disable copy construction.
783 
784  lookup_t& lookup;
785 
786  TKeyCompare compare;
787 
788  //*************************************************************************
790  //*************************************************************************
791 #if defined(ETL_POLYMORPHIC_REFERENCE_FLAT_MULTISET) || defined(ETL_POLYMORPHIC_CONTAINERS)
792  public:
793  virtual ~ireference_flat_multiset()
794  {
795  }
796 #else
797  protected:
799  {
800  }
801 #endif
802  };
803 
804  //***************************************************************************
807  //***************************************************************************
808  template <typename TKey, const size_t MAX_SIZE_, typename TKeyCompare = etl::less<TKey> >
809  class reference_flat_multiset : public ireference_flat_multiset<TKey, TKeyCompare>
810  {
811  public:
812 
813  static const size_t MAX_SIZE = MAX_SIZE_;
814 
815  //*************************************************************************
817  //*************************************************************************
819  : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
820  {
821  }
822 
823  //*************************************************************************
825  //*************************************************************************
827  : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
828  {
830  }
831 
832  //*************************************************************************
837  //*************************************************************************
838  template <typename TIterator>
839  reference_flat_multiset(TIterator first, TIterator last)
840  : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
841  {
843  }
844 
845  //*************************************************************************
847  //*************************************************************************
849  {
851  }
852 
853  private:
854 
855  typedef TKey value_type;
856 
857  // The vector that stores pointers to the nodes.
859  };
860 
861  //***************************************************************************
867  //***************************************************************************
868  template <typename T, typename TKeyCompare>
870  {
871  return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
872  }
873 
874  //***************************************************************************
880  //***************************************************************************
881  template <typename T, typename TKeyCompare>
883  {
884  return !(lhs == rhs);
885  }
886 }
887 
888 #undef ETL_FILE
889 #endif
Definition: reference_flat_multiset.h:59
Definition: reference_flat_multiset.h:73
Definition: reference_flat_multiset.h:87
Definition: reference_flat_multiset.h:221
Definition: reference_flat_multiset.h:123
Definition: reference_flat_multiset.h:103
iterator upper_bound(parameter_t key)
Definition: reference_flat_multiset.h:647
size_t count(parameter_t key) const
Definition: reference_flat_multiset.h:615
const_iterator begin() const
Definition: reference_flat_multiset.h:336
iterator begin()
Definition: reference_flat_multiset.h:327
const_iterator find(parameter_t key) const
Definition: reference_flat_multiset.h:591
~ireference_flat_multiset()
Destructor.
Definition: reference_flat_multiset.h:798
const_iterator upper_bound(parameter_t key) const
Definition: reference_flat_multiset.h:657
ireference_flat_multiset(lookup_t &lookup_)
Constructor.
Definition: reference_flat_multiset.h:741
reverse_iterator rbegin()
Definition: reference_flat_multiset.h:381
void erase(iterator first, iterator last)
Definition: reference_flat_multiset.h:549
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(parameter_t key) const
Definition: reference_flat_multiset.h:677
size_t erase(parameter_t key)
Definition: reference_flat_multiset.h:517
bool empty() const
Definition: reference_flat_multiset.h:695
ETL_OR_STD::pair< iterator, bool > insert_at(iterator i_element, reference value)
Definition: reference_flat_multiset.h:751
const_iterator end() const
Definition: reference_flat_multiset.h:354
reverse_iterator rend()
Definition: reference_flat_multiset.h:399
size_t available() const
Definition: reference_flat_multiset.h:731
void insert(TIterator first, TIterator last)
Definition: reference_flat_multiset.h:504
iterator find(parameter_t key)
Definition: reference_flat_multiset.h:567
size_type size() const
Definition: reference_flat_multiset.h:686
const_iterator lower_bound(parameter_t key) const
Definition: reference_flat_multiset.h:637
ETL_OR_STD::pair< iterator, iterator > equal_range(parameter_t key)
Definition: reference_flat_multiset.h:667
bool full() const
Definition: reference_flat_multiset.h:704
void clear()
Clears the reference_flat_multiset.
Definition: reference_flat_multiset.h:557
iterator end()
Definition: reference_flat_multiset.h:345
const_reverse_iterator rbegin() const
Definition: reference_flat_multiset.h:390
void erase(iterator i_element)
Definition: reference_flat_multiset.h:537
iterator lower_bound(parameter_t key)
Definition: reference_flat_multiset.h:627
iterator insert(iterator position, value_type &value)
Definition: reference_flat_multiset.h:491
ETL_OR_STD::pair< iterator, bool > insert(value_type &value)
Definition: reference_flat_multiset.h:459
size_type capacity() const
Definition: reference_flat_multiset.h:713
const_reverse_iterator crbegin() const
Definition: reference_flat_multiset.h:417
const_reverse_iterator crend() const
Definition: reference_flat_multiset.h:426
const_iterator cend() const
Definition: reference_flat_multiset.h:372
const_reverse_iterator rend() const
Definition: reference_flat_multiset.h:408
size_type max_size() const
Definition: reference_flat_multiset.h:722
void assign(TIterator first, TIterator last)
Definition: reference_flat_multiset.h:439
const_iterator cbegin() const
Definition: reference_flat_multiset.h:363
Definition: reference_flat_multiset.h:810
reference_flat_multiset(const reference_flat_multiset &other)
Copy constructor.
Definition: reference_flat_multiset.h:826
~reference_flat_multiset()
Destructor.
Definition: reference_flat_multiset.h:848
reference_flat_multiset()
Constructor.
Definition: reference_flat_multiset.h:818
reference_flat_multiset(TIterator first, TIterator last)
Definition: reference_flat_multiset.h:839
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::ireference_flat_multiset< T, TKeyCompare > &lhs, const etl::ireference_flat_multiset< T, TKeyCompare > &rhs)
Definition: reference_flat_multiset.h:882
bool operator==(const etl::ireference_flat_multiset< T, TKeyCompare > &lhs, const etl::ireference_flat_multiset< T, TKeyCompare > &rhs)
Definition: reference_flat_multiset.h:869
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
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