Embedded Template Library  1.0
reference_flat_set.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_SET_INCLUDED
32 #define ETL_REFERENCE_FLAT_SET_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 "pool.h"
45 #include "error_handler.h"
46 #include "exception.h"
47 #include "vector.h"
48 #include "iterator.h"
49 
50 #undef ETL_FILE
51 #define ETL_FILE "32"
52 
53 namespace etl
54 {
55  //***************************************************************************
58  //***************************************************************************
60  {
61  public:
62 
63  flat_set_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
64  : exception(reason_, file_name_, line_number_)
65  {
66  }
67  };
68 
69  //***************************************************************************
72  //***************************************************************************
74  {
75  public:
76 
77  flat_set_full(string_type file_name_, numeric_type line_number_)
78  : flat_set_exception(ETL_ERROR_TEXT("flat_set:full", ETL_FILE"A"), file_name_, line_number_)
79  {
80  }
81  };
82 
83  //***************************************************************************
86  //***************************************************************************
88  {
89  public:
90 
91  flat_set_iterator(string_type file_name_, numeric_type line_number_)
92  : flat_set_exception(ETL_ERROR_TEXT("flat_set:iterator", ETL_FILE"C"), file_name_, line_number_)
93  {
94  }
95  };
96 
97  //***************************************************************************
101  //***************************************************************************
102  template <typename T, typename TKeyCompare = etl::less<T> >
104  {
105  public:
106 
107  typedef T key_type;
108  typedef T value_type;
109  typedef TKeyCompare key_compare;
110  typedef value_type& reference;
111  typedef const value_type& const_reference;
112  typedef value_type* pointer;
113  typedef const value_type* const_pointer;
114  typedef size_t size_type;
115 
116  protected:
117 
119 
120  public:
121 
122  //*************************************************************************
123  class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
124  {
125  public:
126 
127  friend class ireference_flat_set;
128  friend class const_iterator;
129 
130  iterator()
131  {
132  }
133 
134  iterator(typename lookup_t::iterator ilookup_)
135  : ilookup(ilookup_)
136  {
137  }
138 
139  iterator(const iterator& other)
140  : ilookup(other.ilookup)
141  {
142  }
143 
144  iterator& operator =(const iterator& other)
145  {
146  ilookup = other.ilookup;
147  return *this;
148  }
149 
150  iterator& operator ++()
151  {
152  ++ilookup;
153  return *this;
154  }
155 
156  iterator operator ++(int)
157  {
158  iterator temp(*this);
159  ++ilookup;
160  return temp;
161  }
162 
163  iterator& operator --()
164  {
165  --ilookup;
166  return *this;
167  }
168 
169  iterator operator --(int)
170  {
171  iterator temp(*this);
172  --ilookup;
173  return temp;
174  }
175 
176  reference operator *()
177  {
178  return *(*ilookup);
179  }
180 
181  const_reference operator *() const
182  {
183  return *(*ilookup);
184  }
185 
186  pointer operator &()
187  {
188  return etl::addressof(*(*ilookup));
189  }
190 
191  const_pointer operator &() const
192  {
193  return &(*(*ilookup));
194  }
195 
196  pointer operator ->()
197  {
198  return etl::addressof(*(*ilookup));
199  }
200 
201  const_pointer operator ->() const
202  {
203  return etl::addressof(*(*ilookup));
204  }
205 
206  friend bool operator == (const iterator& lhs, const iterator& rhs)
207  {
208  return lhs.ilookup == rhs.ilookup;
209  }
210 
211  friend bool operator != (const iterator& lhs, const iterator& rhs)
212  {
213  return !(lhs == rhs);
214  }
215 
216  private:
217 
218  typename lookup_t::iterator ilookup;
219  };
220 
221  //*************************************************************************
222  class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
223  {
224  public:
225 
226  friend class ireference_flat_set;
227 
229  {
230  }
231 
232  const_iterator(typename lookup_t::const_iterator ilookup_)
233  : ilookup(ilookup_)
234  {
235  }
236 
237  const_iterator(const typename ireference_flat_set::iterator& other)
238  : ilookup(other.ilookup)
239  {
240  }
241 
242  const_iterator(const const_iterator& other)
243  : ilookup(other.ilookup)
244  {
245  }
246 
247  const_iterator& operator =(const iterator& other)
248  {
249  ilookup = other.ilookup;
250  return *this;
251  }
252 
253  const_iterator& operator =(const const_iterator& other)
254  {
255  ilookup = other.ilookup;
256  return *this;
257  }
258 
259  const_iterator& operator ++()
260  {
261  ++ilookup;
262  return *this;
263  }
264 
265  const_iterator operator ++(int)
266  {
267  const_iterator temp(*this);
268  ++ilookup;
269  return temp;
270  }
271 
272  const_iterator& operator --()
273  {
274  --ilookup;
275  return *this;
276  }
277 
278  const_iterator operator --(int)
279  {
280  const_iterator temp(*this);
281  --ilookup;
282  return temp;
283  }
284 
285  const_reference operator *() const
286  {
287  return *(*ilookup);
288  }
289 
290  const_pointer operator &() const
291  {
292  return etl::addressof(*(*ilookup));
293  }
294 
295  const_pointer operator ->() const
296  {
297  return etl::addressof(*(*ilookup));
298  }
299 
300  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
301  {
302  return lhs.ilookup == rhs.ilookup;
303  }
304 
305  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
306  {
307  return !(lhs == rhs);
308  }
309 
310  private:
311 
312  typename lookup_t::const_iterator ilookup;
313  };
314 
315  protected:
316 
317  typedef typename etl::parameter_type<T>::type parameter_t;
318 
319  public:
320 
321  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
322  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
323  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
324 
325  //*********************************************************************
328  //*********************************************************************
330  {
331  return iterator(lookup.begin());
332  }
333 
334  //*********************************************************************
337  //*********************************************************************
339  {
340  return const_iterator(lookup.begin());
341  }
342 
343  //*********************************************************************
346  //*********************************************************************
348  {
349  return iterator(lookup.end());
350  }
351 
352  //*********************************************************************
355  //*********************************************************************
357  {
358  return const_iterator(lookup.end());
359  }
360 
361  //*********************************************************************
364  //*********************************************************************
366  {
367  return const_iterator(lookup.cbegin());
368  }
369 
370  //*********************************************************************
373  //*********************************************************************
375  {
376  return const_iterator(lookup.cend());
377  }
378 
379  //*********************************************************************
382  //*********************************************************************
383  reverse_iterator rbegin()
384  {
385  return reverse_iterator(lookup.rbegin());
386  }
387 
388  //*********************************************************************
391  //*********************************************************************
392  const_reverse_iterator rbegin() const
393  {
394  return const_reverse_iterator(lookup.rbegin());
395  }
396 
397  //*********************************************************************
400  //*********************************************************************
401  reverse_iterator rend()
402  {
403  return reverse_iterator(lookup.rend());
404  }
405 
406  //*********************************************************************
409  //*********************************************************************
410  const_reverse_iterator rend() const
411  {
412  return const_reverse_iterator(lookup.rend());
413  }
414 
415  //*********************************************************************
418  //*********************************************************************
419  const_reverse_iterator crbegin() const
420  {
421  return const_reverse_iterator(lookup.crbegin());
422  }
423 
424  //*********************************************************************
427  //*********************************************************************
428  const_reverse_iterator crend() const
429  {
430  return const_reverse_iterator(lookup.crend());
431  }
432 
433  //*********************************************************************
439  //*********************************************************************
440  template <typename TIterator>
441  void assign(TIterator first, TIterator last)
442  {
443 #if defined(ETL_DEBUG)
444  difference_type d = etl::distance(first, last);
445  ETL_ASSERT(d <= difference_type(capacity()), ETL_ERROR(flat_set_full));
446 #endif
447 
448  clear();
449 
450  while (first != last)
451  {
452  insert(*first++);
453  }
454  }
455 
456  //*********************************************************************
460  //*********************************************************************
461  ETL_OR_STD::pair<iterator, bool> insert(reference value)
462  {
463  iterator i_element = lower_bound(value);
464 
465  return insert_at(i_element, value);
466  }
467 
468  //*********************************************************************
473  //*********************************************************************
474  iterator insert(iterator position, reference value)
475  {
476  return insert(value).first;
477  }
478 
479  //*********************************************************************
485  //*********************************************************************
486  template <class TIterator>
487  void insert(TIterator first, TIterator last)
488  {
489  while (first != last)
490  {
491  insert(*first++);
492  }
493  }
494 
495  //*********************************************************************
499  //*********************************************************************
500  size_t erase(parameter_t key)
501  {
502  iterator i_element = find(key);
503 
504  if (i_element == end())
505  {
506  return 0;
507  }
508  else
509  {
510  lookup.erase(i_element.ilookup);
511  return 1;
512  }
513  }
514 
515  //*********************************************************************
518  //*********************************************************************
519  void erase(iterator i_element)
520  {
521  lookup.erase(i_element.ilookup);
522  }
523 
524  //*********************************************************************
530  //*********************************************************************
531  void erase(iterator first, iterator last)
532  {
533  lookup.erase(first.ilookup, last.ilookup);
534  }
535 
536  //*************************************************************************
538  //*************************************************************************
539  void clear()
540  {
541  lookup.clear();
542  }
543 
544  //*********************************************************************
548  //*********************************************************************
549  iterator find(parameter_t key)
550  {
551  iterator itr = etl::lower_bound(begin(), end(), key, compare);
552 
553  if (itr != end())
554  {
555  if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
556  {
557  return itr;
558  }
559  else
560  {
561  return end();
562  }
563  }
564 
565  return end();
566  }
567 
568  //*********************************************************************
572  //*********************************************************************
573  const_iterator find(parameter_t key) const
574  {
575  const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
576 
577  if (itr != end())
578  {
579  if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
580  {
581  return itr;
582  }
583  else
584  {
585  return end();
586  }
587  }
588 
589  return end();
590  }
591 
592  //*********************************************************************
596  //*********************************************************************
597  size_t count(parameter_t key) const
598  {
599  return (find(key) == end()) ? 0 : 1;
600  }
601 
602  //*********************************************************************
606  //*********************************************************************
607  iterator lower_bound(parameter_t key)
608  {
609  return etl::lower_bound(begin(), end(), key, compare);
610  }
611 
612  //*********************************************************************
616  //*********************************************************************
617  const_iterator lower_bound(parameter_t key) const
618  {
619  return etl::lower_bound(cbegin(), cend(), key, compare);
620  }
621 
622  //*********************************************************************
626  //*********************************************************************
627  iterator upper_bound(parameter_t key)
628  {
629  return etl::upper_bound(begin(), end(), key, compare);
630  }
631 
632  //*********************************************************************
636  //*********************************************************************
637  const_iterator upper_bound(parameter_t key) const
638  {
639  return etl::upper_bound(cbegin(), cend(), key, compare);
640  }
641 
642  //*********************************************************************
646  //*********************************************************************
647  ETL_OR_STD::pair<iterator, iterator> equal_range(parameter_t key)
648  {
649  return etl::equal_range(begin(), end(), key, compare);
650  }
651 
652  //*********************************************************************
656  //*********************************************************************
657  ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
658  {
659  return etl::upper_bound(cbegin(), cend(), key, compare);
660  }
661 
662  //*************************************************************************
665  //*************************************************************************
666  size_type size() const
667  {
668  return lookup.size();
669  }
670 
671  //*************************************************************************
674  //*************************************************************************
675  bool empty() const
676  {
677  return lookup.empty();
678  }
679 
680  //*************************************************************************
683  //*************************************************************************
684  bool full() const
685  {
686  return lookup.full();
687  }
688 
689  //*************************************************************************
692  //*************************************************************************
693  size_type capacity() const
694  {
695  return lookup.capacity();
696  }
697 
698  //*************************************************************************
701  //*************************************************************************
702  size_type max_size() const
703  {
704  return lookup.max_size();
705  }
706 
707  //*************************************************************************
710  //*************************************************************************
711  size_t available() const
712  {
713  return lookup.available();
714  }
715 
716  protected:
717 
718  //*********************************************************************
720  //*********************************************************************
722  : lookup(lookup_)
723  {
724  }
725 
726  //*********************************************************************
730  //*********************************************************************
731  ETL_OR_STD::pair<iterator, bool> insert_at(iterator i_element, reference value)
732  {
733  ETL_OR_STD::pair<iterator, bool> result(end(), false);
734 
735  if (i_element == end())
736  {
737  // At the end.
738  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full));
739 
740  lookup.push_back(&value);
741  result.first = --end();
742  result.second = true;
743  }
744  else
745  {
746  // Not at the end.
747  result.first = i_element;
748 
749  // Existing element?
750  if (compare(value, *i_element) || compare(*i_element, value))
751  {
752  // A new one.
753  ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full));
754  lookup.insert(i_element.ilookup, &value);
755  result.second = true;
756  }
757  }
758 
759  return result;
760  }
761 
762  private:
763 
764  // Disable copy construction.
766  ireference_flat_set& operator =(const ireference_flat_set&);
767 
768  lookup_t& lookup;
769 
770  TKeyCompare compare;
771 
772  //*************************************************************************
774  //*************************************************************************
775 #if defined(ETL_POLYMORPHIC_REFERENCE_FLAT_SET) || defined(ETL_POLYMORPHIC_CONTAINERS)
776  public:
777  virtual ~ireference_flat_set()
778  {
779  }
780 #else
781  protected:
783  {
784  }
785 #endif
786  };
787 
788  //***************************************************************************
791  //***************************************************************************
792  template <typename TKey, const size_t MAX_SIZE_, typename TKeyCompare = etl::less<TKey> >
793  class reference_flat_set : public ireference_flat_set<TKey, TKeyCompare>
794  {
795  public:
796 
797  static const size_t MAX_SIZE = MAX_SIZE_;
798 
799  //*************************************************************************
801  //*************************************************************************
803  : ireference_flat_set<TKey, TKeyCompare>(lookup)
804  {
805  }
806 
807  //*************************************************************************
809  //*************************************************************************
811  : ireference_flat_set<TKey, TKeyCompare>(lookup)
812  {
814  }
815 
816  //*************************************************************************
821  //*************************************************************************
822  template <typename TIterator>
823  reference_flat_set(TIterator first, TIterator last)
824  : ireference_flat_set<TKey, TKeyCompare>(lookup)
825  {
827  }
828 
829  //*************************************************************************
831  //*************************************************************************
833  {
835  }
836 
837  private:
838 
839  typedef TKey value_type;
840 
841  // The vector that stores pointers to the nodes.
843  };
844 
845  //***************************************************************************
851  //***************************************************************************
852  template <typename T, typename TKeyCompare>
854  {
855  return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
856  }
857 
858  //***************************************************************************
864  //***************************************************************************
865  template <typename T, typename TKeyCompare>
867  {
868  return !(lhs == rhs);
869  }
870 }
871 
872 #undef ETL_FILE
873 #endif
Definition: reference_flat_set.h:60
Definition: reference_flat_set.h:74
Definition: reference_flat_set.h:88
Definition: reference_flat_set.h:223
Definition: reference_flat_set.h:124
Definition: reference_flat_set.h:104
const_iterator lower_bound(parameter_t key) const
Definition: reference_flat_set.h:617
~ireference_flat_set()
Destructor.
Definition: reference_flat_set.h:782
size_type capacity() const
Definition: reference_flat_set.h:693
ETL_OR_STD::pair< iterator, bool > insert(reference value)
Definition: reference_flat_set.h:461
size_t available() const
Definition: reference_flat_set.h:711
const_iterator begin() const
Definition: reference_flat_set.h:338
iterator upper_bound(parameter_t key)
Definition: reference_flat_set.h:627
const_iterator find(parameter_t key) const
Definition: reference_flat_set.h:573
iterator insert(iterator position, reference value)
Definition: reference_flat_set.h:474
void assign(TIterator first, TIterator last)
Definition: reference_flat_set.h:441
ETL_OR_STD::pair< iterator, bool > insert_at(iterator i_element, reference value)
Definition: reference_flat_set.h:731
const_reverse_iterator rend() const
Definition: reference_flat_set.h:410
void erase(iterator i_element)
Definition: reference_flat_set.h:519
const_reverse_iterator crbegin() const
Definition: reference_flat_set.h:419
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(parameter_t key) const
Definition: reference_flat_set.h:657
const_iterator end() const
Definition: reference_flat_set.h:356
iterator begin()
Definition: reference_flat_set.h:329
size_t erase(parameter_t key)
Definition: reference_flat_set.h:500
iterator end()
Definition: reference_flat_set.h:347
const_iterator upper_bound(parameter_t key) const
Definition: reference_flat_set.h:637
const_iterator cend() const
Definition: reference_flat_set.h:374
const_iterator cbegin() const
Definition: reference_flat_set.h:365
iterator find(parameter_t key)
Definition: reference_flat_set.h:549
const_reverse_iterator rbegin() const
Definition: reference_flat_set.h:392
size_type max_size() const
Definition: reference_flat_set.h:702
const_reverse_iterator crend() const
Definition: reference_flat_set.h:428
bool empty() const
Definition: reference_flat_set.h:675
size_type size() const
Definition: reference_flat_set.h:666
reverse_iterator rbegin()
Definition: reference_flat_set.h:383
ETL_OR_STD::pair< iterator, iterator > equal_range(parameter_t key)
Definition: reference_flat_set.h:647
ireference_flat_set(lookup_t &lookup_)
Constructor.
Definition: reference_flat_set.h:721
size_t count(parameter_t key) const
Definition: reference_flat_set.h:597
void insert(TIterator first, TIterator last)
Definition: reference_flat_set.h:487
bool full() const
Definition: reference_flat_set.h:684
void clear()
Clears the reference_flat_set.
Definition: reference_flat_set.h:539
void erase(iterator first, iterator last)
Definition: reference_flat_set.h:531
iterator lower_bound(parameter_t key)
Definition: reference_flat_set.h:607
reverse_iterator rend()
Definition: reference_flat_set.h:401
Definition: reference_flat_set.h:794
reference_flat_set(TIterator first, TIterator last)
Definition: reference_flat_set.h:823
reference_flat_set(const reference_flat_set &other)
Copy constructor.
Definition: reference_flat_set.h:810
reference_flat_set()
Constructor.
Definition: reference_flat_set.h:802
~reference_flat_set()
Destructor.
Definition: reference_flat_set.h:832
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_set< T, TKeyCompare > &lhs, const etl::ireference_flat_set< T, TKeyCompare > &rhs)
Definition: reference_flat_set.h:853
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_set< T, TKeyCompare > &lhs, const etl::ireference_flat_set< T, TKeyCompare > &rhs)
Definition: reference_flat_set.h:866
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