Embedded Template Library 1.0
Loading...
Searching...
No Matches
unordered_set.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) 2016 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_UNORDERED_SET_INCLUDED
32#define ETL_UNORDERED_SET_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "debug_count.h"
37#include "error_handler.h"
38#include "exception.h"
39#include "functional.h"
40#include "hash.h"
41#include "initializer_list.h"
43#include "iterator.h"
44#include "nth_type.h"
45#include "nullptr.h"
46#include "parameter_type.h"
47#include "placement_new.h"
48#include "pool.h"
49#include "type_traits.h"
50#include "utility.h"
51#include "vector.h"
52
54
55#include <stddef.h>
56
57//*****************************************************************************
61//*****************************************************************************
62
63namespace etl
64{
65 //***************************************************************************
68 //***************************************************************************
69 class unordered_set_exception : public etl::exception
70 {
71 public:
72
73 unordered_set_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
74 : etl::exception(reason_, file_name_, line_number_)
75 {
76 }
77 };
78
79 //***************************************************************************
82 //***************************************************************************
83 class unordered_set_full : public etl::unordered_set_exception
84 {
85 public:
86
87 unordered_set_full(string_type file_name_, numeric_type line_number_)
88 : etl::unordered_set_exception(ETL_ERROR_TEXT("unordered_set:full", ETL_UNORDERED_SET_FILE_ID"A"), file_name_, line_number_)
89 {
90 }
91 };
92
93 //***************************************************************************
96 //***************************************************************************
97 class unordered_set_out_of_range : public etl::unordered_set_exception
98 {
99 public:
100
101 unordered_set_out_of_range(string_type file_name_, numeric_type line_number_)
102 : etl::unordered_set_exception(ETL_ERROR_TEXT("unordered_set:range", ETL_UNORDERED_SET_FILE_ID"B"), file_name_, line_number_)
103 {
104 }
105 };
106
107 //***************************************************************************
110 //***************************************************************************
111 class unordered_set_iterator : public etl::unordered_set_exception
112 {
113 public:
114
115 unordered_set_iterator(string_type file_name_, numeric_type line_number_)
116 : etl::unordered_set_exception(ETL_ERROR_TEXT("unordered_set:iterator", ETL_UNORDERED_SET_FILE_ID"C"), file_name_, line_number_)
117 {
118 }
119 };
120
121 //***************************************************************************
126 //***************************************************************************
127 template <typename TKey, typename THash = etl::hash<TKey>, typename TKeyEqual = etl::equal_to<TKey> >
129 {
130 public:
131
132 typedef TKey value_type;
133 typedef TKey key_type;
134 typedef THash hasher;
135 typedef TKeyEqual key_equal;
136 typedef value_type& reference;
137 typedef const value_type& const_reference;
138#if ETL_USING_CPP11
139 typedef value_type&& rvalue_reference;
140#endif
141 typedef value_type* pointer;
142 typedef const value_type* const_pointer;
143 typedef size_t size_type;
144
145 typedef const TKey& key_parameter_t;
146
147 typedef etl::forward_link<0> link_t;
148
149 //*********************************************************************
150 // The nodes that store the elements.
151 struct node_t : public link_t
152 {
153 node_t(const_reference key_)
154 : key(key_)
155 {
156 }
157
158 value_type key;
159 };
160
161 friend bool operator==(const node_t& lhs, const node_t& rhs)
162 {
163 return (lhs.key == rhs.key);
164 }
165
166 friend bool operator!=(const node_t& lhs, const node_t& rhs)
167 {
168 return !(lhs == rhs);
169 }
170
171 protected:
172
174 typedef etl::ipool pool_t;
175
176 public:
177
178 // Local iterators iterate over one bucket.
179 typedef typename bucket_t::iterator local_iterator;
180 typedef typename bucket_t::const_iterator const_local_iterator;
181
182 //*********************************************************************
183 class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, TKey>
184 {
185 public:
186
187 typedef typename etl::iterator<ETL_OR_STD::forward_iterator_tag, TKey>::value_type value_type;
188 typedef typename iunordered_set::key_type key_type;
189 typedef typename iunordered_set::hasher hasher;
190 typedef typename iunordered_set::key_equal key_equal;
191 typedef typename iunordered_set::reference reference;
192 typedef typename iunordered_set::const_reference const_reference;
193 typedef typename iunordered_set::pointer pointer;
194 typedef typename iunordered_set::const_pointer const_pointer;
195 typedef typename iunordered_set::size_type size_type;
196
197 friend class iunordered_set;
198 friend class const_iterator;
199
200 //*********************************
201 iterator() {}
202
203 //*********************************
204 iterator(const iterator& other)
205 : pbuckets_end(other.pbuckets_end)
206 , pbucket(other.pbucket)
207 , inode(other.inode)
208 {
209 }
210
211 //*********************************
212 iterator& operator++()
213 {
214 ++inode;
215
216 // The end of this node list?
217 if (inode == pbucket->end())
218 {
219 // Search for the next non-empty bucket.
220 ++pbucket;
221 while ((pbucket != pbuckets_end) && (pbucket->empty()))
222 {
223 ++pbucket;
224 }
225
226 // If not past the end, get the first node in the bucket.
227 if (pbucket != pbuckets_end)
228 {
229 inode = pbucket->begin();
230 }
231 }
232
233 return *this;
234 }
235
236 //*********************************
237 iterator operator++(int)
238 {
239 iterator temp(*this);
240 operator++();
241 return temp;
242 }
243
244 //*********************************
245 iterator& operator=(const iterator& other)
246 {
247 pbuckets_end = other.pbuckets_end;
248 pbucket = other.pbucket;
249 inode = other.inode;
250 return *this;
251 }
252
253 //*********************************
254 reference operator*() const
255 {
256 return inode->key;
257 }
258
259 //*********************************
260 pointer operator&() const
261 {
262 return &(inode->key);
263 }
264
265 //*********************************
266 pointer operator->() const
267 {
268 return &(inode->key);
269 }
270
271 //*********************************
272 friend bool operator==(const iterator& lhs, const iterator& rhs)
273 {
274 return lhs.compare(rhs);
275 }
276
277 //*********************************
278 friend bool operator!=(const iterator& lhs, const iterator& rhs)
279 {
280 return !(lhs == rhs);
281 }
282
283 private:
284
285 //*********************************
286 iterator(bucket_t* pbuckets_end_, bucket_t* pbucket_, local_iterator inode_)
287 : pbuckets_end(pbuckets_end_)
288 , pbucket(pbucket_)
289 , inode(inode_)
290 {
291 }
292
293 //*********************************
294 bool compare(const iterator& rhs) const
295 {
296 return rhs.inode == inode;
297 }
298
299 //*********************************
300 bucket_t& get_bucket()
301 {
302 return *pbucket;
303 }
304
305 //*********************************
306 bucket_t*& get_bucket_list_iterator()
307 {
308 return pbucket;
309 }
310
311 //*********************************
312 local_iterator get_local_iterator()
313 {
314 return inode;
315 }
316
317 bucket_t* pbuckets_end;
318 bucket_t* pbucket;
319 local_iterator inode;
320 };
321
322 //*********************************************************************
323 class const_iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, const TKey>
324 {
325 public:
326
327 typedef typename etl::iterator<ETL_OR_STD::forward_iterator_tag, const TKey>::value_type value_type;
328 typedef typename iunordered_set::key_type key_type;
329 typedef typename iunordered_set::hasher hasher;
330 typedef typename iunordered_set::key_equal key_equal;
331 typedef typename iunordered_set::reference reference;
332 typedef typename iunordered_set::const_reference const_reference;
333 typedef typename iunordered_set::pointer pointer;
334 typedef typename iunordered_set::const_pointer const_pointer;
335 typedef typename iunordered_set::size_type size_type;
336
337 friend class iunordered_set;
338 friend class iterator;
339
340 //*********************************
341 const_iterator() {}
342
343 //*********************************
344 const_iterator(const typename iunordered_set::iterator& other)
345 : pbuckets_end(other.pbuckets_end)
346 , pbucket(other.pbucket)
347 , inode(other.inode)
348 {
349 }
350
351 //*********************************
352 const_iterator(const const_iterator& other)
353 : pbuckets_end(other.pbuckets_end)
354 , pbucket(other.pbucket)
355 , inode(other.inode)
356 {
357 }
358
359 //*********************************
360 const_iterator& operator++()
361 {
362 ++inode;
363
364 // The end of this node list?
365 if (inode == pbucket->end())
366 {
367 // Search for the next non-empty bucket.
368
369 ++pbucket;
370 while ((pbucket != pbuckets_end) && (pbucket->empty()))
371 {
372 ++pbucket;
373 }
374
375 // If not past the end, get the first node in the bucket.
376 if (pbucket != pbuckets_end)
377 {
378 inode = pbucket->begin();
379 }
380 }
381
382 return *this;
383 }
384
385 //*********************************
386 const_iterator operator++(int)
387 {
388 const_iterator temp(*this);
389 operator++();
390 return temp;
391 }
392
393 //*********************************
394 const_iterator& operator=(const const_iterator& other)
395 {
396 pbuckets_end = other.pbuckets_end;
397 pbucket = other.pbucket;
398 inode = other.inode;
399 return *this;
400 }
401
402 //*********************************
403 const_reference operator*() const
404 {
405 return inode->key;
406 }
407
408 //*********************************
409 const_pointer operator&() const
410 {
411 return &(inode->key);
412 }
413
414 //*********************************
415 const_pointer operator->() const
416 {
417 return &(inode->key);
418 }
419
420 //*********************************
421 friend bool operator==(const const_iterator& lhs, const const_iterator& rhs)
422 {
423 return lhs.compare(rhs);
424 }
425
426 //*********************************
427 friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs)
428 {
429 return !(lhs == rhs);
430 }
431
432 private:
433
434 //*********************************
435 const_iterator(bucket_t* pbuckets_end_, bucket_t* pbucket_, local_iterator inode_)
436 : pbuckets_end(pbuckets_end_)
437 , pbucket(pbucket_)
438 , inode(inode_)
439 {
440 }
441
442 //*********************************
443 bool compare(const const_iterator& rhs) const
444 {
445 return rhs.inode == inode;
446 }
447
448 //*********************************
449 bucket_t& get_bucket()
450 {
451 return *pbucket;
452 }
453
454 //*********************************
455 bucket_t*& get_bucket_list_iterator()
456 {
457 return pbucket;
458 }
459
460 //*********************************
461 local_iterator get_local_iterator()
462 {
463 return inode;
464 }
465
466 bucket_t* pbuckets_end;
467 bucket_t* pbucket;
468 local_iterator inode;
469 };
470
471 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
472
473 //*********************************************************************
476 //*********************************************************************
477 iterator begin()
478 {
479 return iterator(pbuckets + number_of_buckets, first, first->begin());
480 }
481
482 //*********************************************************************
485 //*********************************************************************
486 const_iterator begin() const
487 {
488 return const_iterator(pbuckets + number_of_buckets, first, first->begin());
489 }
490
491 //*********************************************************************
494 //*********************************************************************
495 const_iterator cbegin() const
496 {
497 return const_iterator(pbuckets + number_of_buckets, first, first->begin());
498 }
499
500 //*********************************************************************
503 //*********************************************************************
504 local_iterator begin(size_t i)
505 {
506 return pbuckets[i].begin();
507 }
508
509 //*********************************************************************
512 //*********************************************************************
513 const_local_iterator begin(size_t i) const
514 {
515 return pbuckets[i].cbegin();
516 }
517
518 //*********************************************************************
521 //*********************************************************************
522 const_local_iterator cbegin(size_t i) const
523 {
524 return pbuckets[i].cbegin();
525 }
526
527 //*********************************************************************
530 //*********************************************************************
531 iterator end()
532 {
533 return iterator(pbuckets + number_of_buckets, last, last->end());
534 }
535
536 //*********************************************************************
539 //*********************************************************************
540 const_iterator end() const
541 {
542 return const_iterator(pbuckets + number_of_buckets, last, last->end());
543 }
544
545 //*********************************************************************
548 //*********************************************************************
549 const_iterator cend() const
550 {
551 return const_iterator(pbuckets + number_of_buckets, last, last->end());
552 }
553
554 //*********************************************************************
557 //*********************************************************************
558 local_iterator end(size_t i)
559 {
560 return pbuckets[i].end();
561 }
562
563 //*********************************************************************
566 //*********************************************************************
567 const_local_iterator end(size_t i) const
568 {
569 return pbuckets[i].cend();
570 }
571
572 //*********************************************************************
575 //*********************************************************************
576 const_local_iterator cend(size_t i) const
577 {
578 return pbuckets[i].cend();
579 }
580
581 //*********************************************************************
584 //*********************************************************************
585 size_type get_bucket_index(key_parameter_t key) const
586 {
587 return key_hash_function(key) % number_of_buckets;
588 }
589
590#if ETL_USING_CPP11
591 //*********************************************************************
594 //*********************************************************************
595 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
596 size_type get_bucket_index(const K& key) const
597 {
598 return key_hash_function(key) % number_of_buckets;
599 }
600#endif
601
602 //*********************************************************************
605 //*********************************************************************
606 size_type bucket_size(key_parameter_t key) const
607 {
608 size_t index = bucket(key);
609
610 return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
611 }
612
613#if ETL_USING_CPP11
614 //*********************************************************************
617 //*********************************************************************
618 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
619 size_type bucket_size(const K& key) const
620 {
621 size_t index = bucket(key);
622
623 return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
624 }
625#endif
626
627 //*********************************************************************
630 //*********************************************************************
631 size_type max_bucket_count() const
632 {
633 return number_of_buckets;
634 }
635
636 //*********************************************************************
639 //*********************************************************************
640 size_type bucket_count() const
641 {
642 return number_of_buckets;
643 }
644
645 //*********************************************************************
652 //*********************************************************************
653 template <typename TIterator>
654 void assign(TIterator first_, TIterator last_)
655 {
656#if ETL_IS_DEBUG_BUILD
657 difference_type d = etl::distance(first_, last_);
658 ETL_ASSERT(d >= 0, ETL_ERROR(unordered_set_iterator));
659 ETL_ASSERT(size_t(d) <= max_size(), ETL_ERROR(unordered_set_full));
660#endif
661
662 clear();
663
664 while (first_ != last_)
665 {
666 insert(*first_);
667 ++first_;
668 }
669 }
670
671 //*********************************************************************
676 //*********************************************************************
677 ETL_OR_STD::pair<iterator, bool> insert(const_reference key)
678 {
679 ETL_OR_STD::pair<iterator, bool> result(end(), false);
680
681 if (full())
682 {
683 iterator iter = find(key);
684 if (iter == end())
685 {
686 ETL_ASSERT_FAIL(ETL_ERROR(unordered_set_full));
687 }
688 else
689 {
690 result.first = iter;
691 result.second = false;
692 return result;
693 }
694 }
695
696 // Get the hash index.
697 size_t index = get_bucket_index(key);
698
699 // Get the bucket & bucket iterator.
700 bucket_t* pbucket = pbuckets + index;
701 bucket_t& bucket = *pbucket;
702
703 // The first one in the bucket?
704 if (bucket.empty())
705 {
706 // Get a new node.
707 node_t* node = allocate_data_node();
708 node->clear();
709 ::new (&node->key) value_type(key);
710 ETL_INCREMENT_DEBUG_COUNT;
711
712 // Just add the pointer to the bucket;
713 bucket.insert_after(bucket.before_begin(), *node);
714 adjust_first_last_markers_after_insert(&bucket);
715
716 result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
717 result.second = true;
718 }
719 else
720 {
721 // Step though the bucket looking for a place to insert.
722 local_iterator inode_previous = bucket.before_begin();
723 local_iterator inode = bucket.begin();
724
725 while (inode != bucket.end())
726 {
727 // Do we already have this key?
728 if (key_equal_function(inode->key, key))
729 {
730 break;
731 }
732
733 ++inode_previous;
734 ++inode;
735 }
736
737 // Not already there?
738 if (inode == bucket.end())
739 {
740 // Get a new node.
741 node_t* node = allocate_data_node();
742 node->clear();
743 ::new (&node->key) value_type(key);
744 ETL_INCREMENT_DEBUG_COUNT;
745
746 // Add the node to the end of the bucket;
747 bucket.insert_after(inode_previous, *node);
748 adjust_first_last_markers_after_insert(&bucket);
749 ++inode_previous;
750
751 result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
752 result.second = true;
753 }
754 }
755
756 return result;
757 }
758
759#if ETL_USING_CPP11
760 //*********************************************************************
765 //*********************************************************************
766 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
767 ETL_OR_STD::pair<iterator, bool> insert(const K& key)
768 {
769 ETL_OR_STD::pair<iterator, bool> result(end(), false);
770
771 if (full())
772 {
773 iterator iter = find(key);
774 if (iter == end())
775 {
776 ETL_ASSERT_FAIL(ETL_ERROR(unordered_set_full));
777 }
778 else
779 {
780 result.first = iter;
781 result.second = false;
782 return result;
783 }
784 }
785
786 // Get the hash index.
787 size_t index = get_bucket_index(key);
788
789 // Get the bucket & bucket iterator.
790 bucket_t* pbucket = pbuckets + index;
791 bucket_t& bucket = *pbucket;
792
793 // The first one in the bucket?
794 if (bucket.empty())
795 {
796 // Get a new node.
797 node_t* node = allocate_data_node();
798 node->clear();
799 ::new (&node->key) value_type(key);
800 ETL_INCREMENT_DEBUG_COUNT;
801
802 // Just add the pointer to the bucket;
803 bucket.insert_after(bucket.before_begin(), *node);
804 adjust_first_last_markers_after_insert(&bucket);
805
806 result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
807 result.second = true;
808 }
809 else
810 {
811 // Step though the bucket looking for a place to insert.
812 local_iterator inode_previous = bucket.before_begin();
813 local_iterator inode = bucket.begin();
814
815 while (inode != bucket.end())
816 {
817 // Do we already have this key?
818 if (key_equal_function(inode->key, key))
819 {
820 break;
821 }
822
823 ++inode_previous;
824 ++inode;
825 }
826
827 // Not already there?
828 if (inode == bucket.end())
829 {
830 // Get a new node.
831 node_t* node = allocate_data_node();
832 node->clear();
833 ::new (&node->key) value_type(key);
834 ETL_INCREMENT_DEBUG_COUNT;
835
836 // Add the node to the end of the bucket;
837 bucket.insert_after(inode_previous, *node);
838 adjust_first_last_markers_after_insert(&bucket);
839 ++inode_previous;
840
841 result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
842 result.second = true;
843 }
844 }
845
846 return result;
847 }
848#endif
849
850#if ETL_USING_CPP11
851 //*********************************************************************
856 //*********************************************************************
857 ETL_OR_STD::pair<iterator, bool> insert(rvalue_reference key)
858 {
859 ETL_OR_STD::pair<iterator, bool> result(end(), false);
860
861 if (full())
862 {
863 iterator iter = find(key);
864 if (iter == end())
865 {
866 ETL_ASSERT_FAIL(ETL_ERROR(unordered_set_full));
867 }
868 else
869 {
870 result.first = iter;
871 result.second = false;
872 return result;
873 }
874 }
875
876 // Get the hash index.
877 size_t index = get_bucket_index(key);
878
879 // Get the bucket & bucket iterator.
880 bucket_t* pbucket = pbuckets + index;
881 bucket_t& bucket = *pbucket;
882
883 // The first one in the bucket?
884 if (bucket.empty())
885 {
886 // Get a new node.
887 node_t* node = allocate_data_node();
888 node->clear();
889 ::new (&node->key) value_type(etl::move(key));
890 ETL_INCREMENT_DEBUG_COUNT;
891
892 // Just add the pointer to the bucket;
893 bucket.insert_after(bucket.before_begin(), *node);
894 adjust_first_last_markers_after_insert(&bucket);
895
896 result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
897 result.second = true;
898 }
899 else
900 {
901 // Step though the bucket looking for a place to insert.
902 local_iterator inode_previous = bucket.before_begin();
903 local_iterator inode = bucket.begin();
904
905 while (inode != bucket.end())
906 {
907 // Do we already have this key?
908 if (key_equal_function(inode->key, key))
909 {
910 break;
911 }
912
913 ++inode_previous;
914 ++inode;
915 }
916
917 // Not already there?
918 if (inode == bucket.end())
919 {
920 // Get a new node.
921 node_t* node = allocate_data_node();
922 node->clear();
923 ::new (&node->key) value_type(etl::move(key));
924 ETL_INCREMENT_DEBUG_COUNT;
925
926 // Add the node to the end of the bucket;
927 bucket.insert_after(inode_previous, *node);
928 adjust_first_last_markers_after_insert(&bucket);
929 ++inode_previous;
930
931 result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
932 result.second = true;
933 }
934 }
935
936 return result;
937 }
938#endif
939
940 //*********************************************************************
946 //*********************************************************************
947 iterator insert(const_iterator, const_reference key)
948 {
949 return insert(key).first;
950 }
951
952#if ETL_USING_CPP11
953 //*********************************************************************
959 //*********************************************************************
960 iterator insert(const_iterator, rvalue_reference key)
961 {
962 return insert(etl::move(key)).first;
963 }
964#endif
965
966 //*********************************************************************
973 //*********************************************************************
974 template <class TIterator>
975 void insert(TIterator first_, TIterator last_)
976 {
977 while (first_ != last_)
978 {
979 insert(*first_);
980 ++first_;
981 }
982 }
983
984 //*********************************************************************
988 //*********************************************************************
989 size_t erase(key_parameter_t key)
990 {
991 size_t n = 0UL;
992 size_t index = get_bucket_index(key);
993
994 bucket_t& bucket = pbuckets[index];
995
996 local_iterator iprevious = bucket.before_begin();
997 local_iterator icurrent = bucket.begin();
998
999 // Search for the key, if we have it.
1000 while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
1001 {
1002 ++iprevious;
1003 ++icurrent;
1004 }
1005
1006 // Did we find it?
1007 if (icurrent != bucket.end())
1008 {
1009 delete_data_node(iprevious, icurrent, bucket);
1010 n = 1;
1011 }
1012
1013 return n;
1014 }
1015
1016#if ETL_USING_CPP11
1017 //*********************************************************************
1021 //*********************************************************************
1022 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1023 size_t erase(const K& key)
1024 {
1025 size_t n = 0UL;
1026 size_t index = get_bucket_index(key);
1027
1028 bucket_t& bucket = pbuckets[index];
1029
1030 local_iterator iprevious = bucket.before_begin();
1031 local_iterator icurrent = bucket.begin();
1032
1033 // Search for the key, if we have it.
1034 while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
1035 {
1036 ++iprevious;
1037 ++icurrent;
1038 }
1039
1040 // Did we find it?
1041 if (icurrent != bucket.end())
1042 {
1043 delete_data_node(iprevious, icurrent, bucket);
1044 n = 1;
1045 }
1046
1047 return n;
1048 }
1049#endif
1050
1051 //*********************************************************************
1054 //*********************************************************************
1055 iterator erase(const_iterator ielement)
1056 {
1057 // Make a note of the next one.
1058 iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator());
1059 ++inext;
1060
1061 bucket_t& bucket = ielement.get_bucket();
1062 local_iterator iprevious = bucket.before_begin();
1063 local_iterator icurrent = ielement.get_local_iterator();
1064
1065 // Find the node previous to the one we're interested in.
1066 while (iprevious->etl_next != &*icurrent)
1067 {
1068 ++iprevious;
1069 }
1070
1071 delete_data_node(iprevious, icurrent, bucket);
1072
1073 return inext;
1074 }
1075
1076 //*********************************************************************
1082 //*********************************************************************
1083 iterator erase(const_iterator first_, const_iterator last_)
1084 {
1085 // Erasing everything?
1086 if ((first_ == begin()) && (last_ == end()))
1087 {
1088 clear();
1089 return end();
1090 }
1091
1092 // Get the starting point.
1093 bucket_t* pbucket = first_.get_bucket_list_iterator();
1094 bucket_t* pend_bucket = last_.get_bucket_list_iterator();
1095 local_iterator iprevious = pbucket->before_begin();
1096 local_iterator icurrent = first_.get_local_iterator();
1097 local_iterator iend = last_.get_local_iterator(); // Note: May not be in the same bucket as
1098 // icurrent.
1099
1100 // Find the node previous to the first one.
1101 while (iprevious->etl_next != &*icurrent)
1102 {
1103 ++iprevious;
1104 }
1105
1106 // Remember the item before the first erased one.
1107 iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
1108
1109 // Until we reach the end.
1110 while ((icurrent != iend) || (pbucket != pend_bucket))
1111 {
1112 icurrent = delete_data_node(iprevious, icurrent, *pbucket);
1113
1114 // Have we not reached the end?
1115 if ((icurrent != iend) || (pbucket != pend_bucket))
1116 {
1117 // At the end of this bucket?
1118 if ((icurrent == pbucket->end()))
1119 {
1120 // Find the next non-empty one.
1121 do {
1122 ++pbucket;
1123 } while (pbucket->empty());
1124
1125 iprevious = pbucket->before_begin();
1126 icurrent = pbucket->begin();
1127 }
1128 }
1129 }
1130
1131 return ++ibefore_erased;
1132 }
1133
1134 //*************************************************************************
1136 //*************************************************************************
1137 void clear()
1138 {
1139 initialise();
1140 }
1141
1142 //*********************************************************************
1146 //*********************************************************************
1147 size_t count(key_parameter_t key) const
1148 {
1149 return (find(key) == end()) ? 0 : 1;
1150 }
1151
1152#if ETL_USING_CPP11
1153 //*********************************************************************
1157 //*********************************************************************
1158 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1159 size_t count(const K& key) const
1160 {
1161 return (find(key) == end()) ? 0 : 1;
1162 }
1163#endif
1164
1165 //*********************************************************************
1169 //*********************************************************************
1170 iterator find(key_parameter_t key)
1171 {
1172 size_t index = get_bucket_index(key);
1173
1174 bucket_t* pbucket = pbuckets + index;
1175 bucket_t& bucket = *pbucket;
1176
1177 // Is the bucket not empty?
1178 if (!bucket.empty())
1179 {
1180 // Step though the list until we find the end or an equivalent key.
1181 local_iterator inode = bucket.begin();
1182 local_iterator iend = bucket.end();
1183
1184 while (inode != iend)
1185 {
1186 // Do we have this one?
1187 if (key_equal_function(key, inode->key))
1188 {
1189 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1190 }
1191
1192 ++inode;
1193 }
1194 }
1195
1196 return end();
1197 }
1198
1199 //*********************************************************************
1203 //*********************************************************************
1204 const_iterator find(key_parameter_t key) const
1205 {
1206 size_t index = get_bucket_index(key);
1207
1208 bucket_t* pbucket = pbuckets + index;
1209 bucket_t& bucket = *pbucket;
1210
1211 // Is the bucket not empty?
1212 if (!bucket.empty())
1213 {
1214 // Step though the list until we find the end or an equivalent key.
1215 local_iterator inode = bucket.begin();
1216 local_iterator iend = bucket.end();
1217
1218 while (inode != iend)
1219 {
1220 // Do we have this one?
1221 if (key_equal_function(key, inode->key))
1222 {
1223 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1224 }
1225
1226 ++inode;
1227 }
1228 }
1229
1230 return end();
1231 }
1232
1233#if ETL_USING_CPP11
1234 //*********************************************************************
1238 //*********************************************************************
1239 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1240 iterator find(const K& key)
1241 {
1242 size_t index = get_bucket_index(key);
1243
1244 bucket_t* pbucket = pbuckets + index;
1245 bucket_t& bucket = *pbucket;
1246
1247 // Is the bucket not empty?
1248 if (!bucket.empty())
1249 {
1250 // Step though the list until we find the end or an equivalent key.
1251 local_iterator inode = bucket.begin();
1252 local_iterator iend = bucket.end();
1253
1254 while (inode != iend)
1255 {
1256 // Do we have this one?
1257 if (key_equal_function(key, inode->key))
1258 {
1259 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1260 }
1261
1262 ++inode;
1263 }
1264 }
1265
1266 return end();
1267 }
1268#endif
1269
1270#if ETL_USING_CPP11
1271 //*********************************************************************
1275 //*********************************************************************
1276 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1277 const_iterator find(const K& key) const
1278 {
1279 size_t index = get_bucket_index(key);
1280
1281 bucket_t* pbucket = pbuckets + index;
1282 bucket_t& bucket = *pbucket;
1283
1284 // Is the bucket not empty?
1285 if (!bucket.empty())
1286 {
1287 // Step though the list until we find the end or an equivalent key.
1288 local_iterator inode = bucket.begin();
1289 local_iterator iend = bucket.end();
1290
1291 while (inode != iend)
1292 {
1293 // Do we have this one?
1294 if (key_equal_function(key, inode->key))
1295 {
1296 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1297 }
1298
1299 ++inode;
1300 }
1301 }
1302
1303 return end();
1304 }
1305#endif
1306
1307 //*********************************************************************
1315 //*********************************************************************
1316 ETL_OR_STD::pair<iterator, iterator> equal_range(key_parameter_t key)
1317 {
1318 iterator f = find(key);
1319 iterator l = f;
1320
1321 if (l != end())
1322 {
1323 ++l;
1324 }
1325
1326 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1327 }
1328
1329 //*********************************************************************
1337 //*********************************************************************
1338 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(key_parameter_t key) const
1339 {
1340 const_iterator f = find(key);
1341 const_iterator l = f;
1342
1343 if (l != end())
1344 {
1345 ++l;
1346 }
1347
1348 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1349 }
1350
1351#if ETL_USING_CPP11
1352 //*********************************************************************
1360 //*********************************************************************
1361 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1362 ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
1363 {
1364 iterator f = find(key);
1365 iterator l = f;
1366
1367 if (l != end())
1368 {
1369 ++l;
1370 }
1371
1372 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1373 }
1374#endif
1375
1376#if ETL_USING_CPP11
1377 //*********************************************************************
1385 //*********************************************************************
1386 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1387 ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
1388 {
1389 const_iterator f = find(key);
1390 const_iterator l = f;
1391
1392 if (l != end())
1393 {
1394 ++l;
1395 }
1396
1397 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1398 }
1399#endif
1400
1401 //*************************************************************************
1403 //*************************************************************************
1404 size_type size() const
1405 {
1406 return pnodepool->size();
1407 }
1408
1409 //*************************************************************************
1411 //*************************************************************************
1412 size_type max_size() const
1413 {
1414 return pnodepool->max_size();
1415 }
1416
1417 //*************************************************************************
1419 //*************************************************************************
1420 size_type capacity() const
1421 {
1422 return pnodepool->max_size();
1423 }
1424
1425 //*************************************************************************
1427 //*************************************************************************
1428 bool empty() const
1429 {
1430 return pnodepool->empty();
1431 }
1432
1433 //*************************************************************************
1435 //*************************************************************************
1436 bool full() const
1437 {
1438 return pnodepool->full();
1439 }
1440
1441 //*************************************************************************
1444 //*************************************************************************
1445 size_t available() const
1446 {
1447 return pnodepool->available();
1448 }
1449
1450 //*************************************************************************
1453 //*************************************************************************
1454 float load_factor() const
1455 {
1456 return static_cast<float>(size()) / static_cast<float>(bucket_count());
1457 }
1458
1459 //*************************************************************************
1462 //*************************************************************************
1463 hasher hash_function() const
1464 {
1465 return key_hash_function;
1466 }
1467
1468 //*************************************************************************
1471 //*************************************************************************
1472 key_equal key_eq() const
1473 {
1474 return key_equal_function;
1475 }
1476
1477 //*************************************************************************
1479 //*************************************************************************
1481 {
1482 // Skip if doing self assignment
1483 if (this != &rhs)
1484 {
1485 key_hash_function = rhs.hash_function();
1486 key_equal_function = rhs.key_eq();
1487 assign(rhs.cbegin(), rhs.cend());
1488 }
1489
1490 return *this;
1491 }
1492
1493#if ETL_USING_CPP11
1494 //*************************************************************************
1496 //*************************************************************************
1498 {
1499 // Skip if doing self assignment
1500 if (this != &rhs)
1501 {
1502 clear();
1503 key_hash_function = rhs.hash_function();
1504 key_equal_function = rhs.key_eq();
1505 move(rhs.begin(), rhs.end());
1506 }
1507
1508 return *this;
1509 }
1510#endif
1511
1512 //*************************************************************************
1514 //*************************************************************************
1515 bool contains(key_parameter_t key) const
1516 {
1517 return find(key) != end();
1518 }
1519
1520#if ETL_USING_CPP11
1521 //*************************************************************************
1523 //*************************************************************************
1524 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
1525 bool contains(const K& key) const
1526 {
1527 return find(key) != end();
1528 }
1529#endif
1530
1531 protected:
1532
1533 //*********************************************************************
1535 //*********************************************************************
1536 iunordered_set(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_)
1537 : pnodepool(&node_pool_)
1538 , pbuckets(pbuckets_)
1539 , number_of_buckets(number_of_buckets_)
1540 , first(pbuckets)
1541 , last(pbuckets)
1542 , key_hash_function(key_hash_function_)
1543 , key_equal_function(key_equal_function_)
1544 {
1545 }
1546
1547 //*********************************************************************
1549 //*********************************************************************
1551 {
1552 if (!empty())
1553 {
1554 // For each bucket...
1555 for (size_t i = 0UL; i < number_of_buckets; ++i)
1556 {
1557 bucket_t& bucket = pbuckets[i];
1558
1559 if (!bucket.empty())
1560 {
1561 // For each item in the bucket...
1562 local_iterator it = bucket.begin();
1563
1564 while (it != bucket.end())
1565 {
1566 // Destroy the value contents.
1567 it->key.~value_type();
1568 ++it;
1569 ETL_DECREMENT_DEBUG_COUNT;
1570 }
1571
1572 // Now it's safe to clear the bucket.
1573 bucket.clear();
1574 }
1575 }
1576
1577 // Now it's safe to clear the entire pool in one go.
1578 pnodepool->release_all();
1579 }
1580
1581 first = pbuckets;
1582 last = first;
1583 }
1584
1585#if ETL_USING_CPP11
1586 //*************************************************************************
1588 //*************************************************************************
1589 void move(iterator b, iterator e)
1590 {
1591 #if ETL_IS_DEBUG_BUILD
1592 difference_type d = etl::distance(b, e);
1593 ETL_ASSERT(d >= 0, ETL_ERROR(unordered_set_iterator));
1594 ETL_ASSERT(size_t(d) <= max_size(), ETL_ERROR(unordered_set_full));
1595 #endif
1596
1597 while (b != e)
1598 {
1599 iterator temp = b;
1600 ++temp;
1601 insert(etl::move(*b));
1602 b = temp;
1603 }
1604 }
1605#endif
1606
1607 private:
1608
1609 //*************************************************************************
1611 //*************************************************************************
1612 node_t* allocate_data_node()
1613 {
1614 node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
1615 return (pnodepool->*func)();
1616 }
1617
1618 //*********************************************************************
1620 //*********************************************************************
1621 void adjust_first_last_markers_after_insert(bucket_t* pbucket)
1622 {
1623 if (size() == 1)
1624 {
1625 first = pbucket;
1626 last = pbucket;
1627 }
1628 else
1629 {
1630 if (pbucket < first)
1631 {
1632 first = pbucket;
1633 }
1634 else if (pbucket > last)
1635 {
1636 last = pbucket;
1637 }
1638 }
1639 }
1640
1641 //*********************************************************************
1643 //*********************************************************************
1644 void adjust_first_last_markers_after_erase(bucket_t* pbucket)
1645 {
1646 if (empty())
1647 {
1648 first = pbuckets;
1649 last = pbuckets;
1650 }
1651 else
1652 {
1653 if (pbucket == first)
1654 {
1655 // We erased the first so, we need to search again from where we
1656 // erased.
1657 while (first->empty())
1658 {
1659 ++first;
1660 }
1661 }
1662 else if (pbucket == last)
1663 {
1664 // We erased the last, so we need to search again. Start from the
1665 // first, go no further than the current last.
1666 pbucket = first;
1667 bucket_t* pend = last;
1668
1669 last = first;
1670
1671 while (pbucket != pend)
1672 {
1673 if (!pbucket->empty())
1674 {
1675 last = pbucket;
1676 }
1677
1678 ++pbucket;
1679 }
1680 }
1681 }
1682 }
1683
1684 //*********************************************************************
1686 //*********************************************************************
1687 local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
1688 {
1689 local_iterator inext = bucket.erase_after(iprevious); // Unlink from the bucket.
1690 icurrent->key.~value_type(); // Destroy the value.
1691 pnodepool->release(&*icurrent); // Release it back to the pool.
1692 adjust_first_last_markers_after_erase(&bucket);
1693 ETL_DECREMENT_DEBUG_COUNT;
1694
1695 return inext;
1696 }
1697
1698 // Disable copy construction.
1700
1702 pool_t* pnodepool;
1703
1705 bucket_t* pbuckets;
1706
1708 const size_t number_of_buckets;
1709
1711 bucket_t* first;
1712 bucket_t* last;
1713
1715 hasher key_hash_function;
1716
1718 key_equal key_equal_function;
1719
1721 ETL_DECLARE_DEBUG_COUNT;
1722
1723 //*************************************************************************
1725 //*************************************************************************
1726#if defined(ETL_POLYMORPHIC_UNORDERED_SET) || defined(ETL_POLYMORPHIC_CONTAINERS)
1727
1728 public:
1729
1730 virtual ~iunordered_set() {}
1731#else
1732
1733 protected:
1734
1736#endif
1737 };
1738
1739 //***************************************************************************
1745 //***************************************************************************
1746 template <typename TKey, typename THash, typename TKeyEqual>
1748 {
1749 const bool sizes_match = (lhs.size() == rhs.size());
1750 bool elements_match = true;
1751
1753
1754 if (sizes_match)
1755 {
1756 itr_t l_begin = lhs.begin();
1757 itr_t l_end = lhs.end();
1758
1759 while ((l_begin != l_end) && elements_match)
1760 {
1761 const TKey l_value = *l_begin;
1762
1763 // See if the lhs key exists in the rhs.
1764 ETL_OR_STD::pair<itr_t, itr_t> range = rhs.equal_range(l_value);
1765
1766 if (range.first != rhs.end())
1767 {
1768 // See if the values match
1769 const TKey r_value = *(range.first);
1770
1771 elements_match = (r_value == l_value);
1772 }
1773 else
1774 {
1775 elements_match = false;
1776 }
1777
1778 ++l_begin;
1779 }
1780 }
1781
1782 return (sizes_match && elements_match);
1783 }
1784
1785 //***************************************************************************
1791 //***************************************************************************
1792 template <typename TKey, typename THash, typename TKeyEqual>
1794 {
1795 return !(lhs == rhs);
1796 }
1797
1798 //*************************************************************************
1800 //*************************************************************************
1801 template <typename TKey, const size_t MAX_SIZE_, size_t MAX_BUCKETS_ = MAX_SIZE_, typename THash = etl::hash<TKey>,
1802 typename TKeyEqual = etl::equal_to<TKey> >
1803 class unordered_set : public etl::iunordered_set<TKey, THash, TKeyEqual>
1804 {
1805 private:
1806
1808
1809 public:
1810
1811 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
1812 static ETL_CONSTANT size_t MAX_BUCKETS = MAX_BUCKETS_;
1813
1814 //*************************************************************************
1816 //*************************************************************************
1817 unordered_set(const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual())
1818 : base(node_pool, buckets, MAX_BUCKETS, hash, equal)
1819 {
1820 }
1821
1822 //*************************************************************************
1824 //*************************************************************************
1826 : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq())
1827 {
1828 // Skip if doing self assignment
1829 if (this != &other)
1830 {
1831 base::assign(other.cbegin(), other.cend());
1832 }
1833 }
1834
1835#if ETL_USING_CPP11
1836 //*************************************************************************
1838 //*************************************************************************
1840 : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq())
1841 {
1842 // Skip if doing self assignment
1843 if (this != &other)
1844 {
1845 base::move(other.begin(), other.end());
1846 }
1847 }
1848#endif
1849
1850 //*************************************************************************
1855 //*************************************************************************
1856 template <typename TIterator>
1857 unordered_set(TIterator first_, TIterator last_, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual())
1858 : base(node_pool, buckets, MAX_BUCKETS, hash, equal)
1859 {
1860 base::assign(first_, last_);
1861 }
1862
1863#if ETL_HAS_INITIALIZER_LIST
1864 //*************************************************************************
1866 //*************************************************************************
1867 unordered_set(std::initializer_list<TKey> init, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual())
1868 : base(node_pool, buckets, MAX_BUCKETS, hash, equal)
1869 {
1870 base::assign(init.begin(), init.end());
1871 }
1872#endif
1873
1874 //*************************************************************************
1876 //*************************************************************************
1878 {
1880 }
1881
1882 //*************************************************************************
1884 //*************************************************************************
1886 {
1887 base::operator=(rhs);
1888
1889 return *this;
1890 }
1891
1892#if ETL_USING_CPP11
1893 //*************************************************************************
1895 //*************************************************************************
1896 unordered_set& operator=(unordered_set&& rhs)
1897 {
1898 base::operator=(etl::move(rhs));
1899
1900 return *this;
1901 }
1902#endif
1903
1904 private:
1905
1908
1910 typename base::bucket_t buckets[MAX_BUCKETS_];
1911 };
1912
1913 //*************************************************************************
1915 //*************************************************************************
1916#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1917 template <typename... T>
1918 unordered_set(T...) -> unordered_set<etl::nth_type_t<0, T...>, sizeof...(T)>;
1919#endif
1920
1921 //*************************************************************************
1923 //*************************************************************************
1924#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
1925 template <typename TKey, typename THash = etl::hash<TKey>, typename TKeyEqual = etl::equal_to<TKey>, typename... T>
1926 constexpr auto make_unordered_set(T&&... keys) -> etl::unordered_set<TKey, sizeof...(T), sizeof...(T), THash, TKeyEqual>
1927 {
1928 return {etl::forward<T>(keys)...};
1929 }
1930#endif
1931} // namespace etl
1932
1933#endif
bool empty() const
Returns true if the list has no elements.
Definition intrusive_forward_list.h:250
void clear()
Clears the intrusive_forward_list.
Definition intrusive_forward_list.h:154
Definition intrusive_forward_list.h:457
iterator insert_after(iterator position, value_type &value)
Definition intrusive_forward_list.h:760
iterator end()
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:713
iterator before_begin()
Gets before the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:689
iterator begin()
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:673
Definition unordered_set.h:324
Definition unordered_set.h:184
A templated unordered_set implementation that uses a fixed size buffer.
Definition unordered_set.h:1804
unordered_set(TIterator first_, TIterator last_, const THash &hash=THash(), const TKeyEqual &equal=TKeyEqual())
Definition unordered_set.h:1857
~unordered_set()
Destructor.
Definition unordered_set.h:1877
unordered_set(const THash &hash=THash(), const TKeyEqual &equal=TKeyEqual())
Default constructor.
Definition unordered_set.h:1817
unordered_set(const unordered_set &other)
Copy constructor.
Definition unordered_set.h:1825
unordered_set & operator=(const unordered_set &rhs)
Assignment operator.
Definition unordered_set.h:1885
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
Definition exception.h:59
T * allocate()
Definition ipool.h:333
Definition ipool.h:109
Definition pool.h:54
size_t count(key_parameter_t key) const
Definition unordered_set.h:1147
const_local_iterator begin(size_t i) const
Definition unordered_set.h:513
key_equal key_eq() const
Definition unordered_set.h:1472
iterator erase(const_iterator first_, const_iterator last_)
Definition unordered_set.h:1083
local_iterator end(size_t i)
Definition unordered_set.h:558
size_type bucket_count() const
Definition unordered_set.h:640
size_type max_size() const
Gets the maximum possible size of the unordered_set.
Definition unordered_set.h:1412
size_type size() const
Gets the size of the unordered_set.
Definition unordered_set.h:1404
iunordered_set(pool_t &node_pool_, bucket_t *pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_)
Constructor.
Definition unordered_set.h:1536
iunordered_set & operator=(const iunordered_set &rhs)
Assignment operator.
Definition unordered_set.h:1480
local_iterator begin(size_t i)
Definition unordered_set.h:504
void insert(TIterator first_, TIterator last_)
Definition unordered_set.h:975
float load_factor() const
Definition unordered_set.h:1454
const_iterator begin() const
Definition unordered_set.h:486
bool contains(key_parameter_t key) const
Check if the unordered_set contains the key.
Definition unordered_set.h:1515
const_local_iterator cbegin(size_t i) const
Definition unordered_set.h:522
bool full() const
Checks to see if the unordered_set is full.
Definition unordered_set.h:1436
size_type bucket_size(key_parameter_t key) const
Definition unordered_set.h:606
~iunordered_set()
Destructor.
Definition unordered_set.h:1735
size_type get_bucket_index(key_parameter_t key) const
Definition unordered_set.h:585
const_iterator end() const
Definition unordered_set.h:540
void clear()
Clears the unordered_set.
Definition unordered_set.h:1137
size_t available() const
Definition unordered_set.h:1445
ETL_OR_STD::pair< iterator, bool > insert(const_reference key)
Definition unordered_set.h:677
iterator insert(const_iterator, const_reference key)
Definition unordered_set.h:947
void assign(TIterator first_, TIterator last_)
Definition unordered_set.h:654
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(key_parameter_t key) const
Definition unordered_set.h:1338
iterator find(key_parameter_t key)
Definition unordered_set.h:1170
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition unordered_set.h:1316
iterator end()
Definition unordered_set.h:531
size_t erase(key_parameter_t key)
Definition unordered_set.h:989
const_iterator find(key_parameter_t key) const
Definition unordered_set.h:1204
hasher hash_function() const
Definition unordered_set.h:1463
bool empty() const
Checks to see if the unordered_set is empty.
Definition unordered_set.h:1428
size_type max_bucket_count() const
Definition unordered_set.h:631
iterator begin()
Definition unordered_set.h:477
const_local_iterator cend(size_t i) const
Definition unordered_set.h:576
const_iterator cend() const
Definition unordered_set.h:549
const_local_iterator end(size_t i) const
Definition unordered_set.h:567
void initialise()
Initialise the unordered_set.
Definition unordered_set.h:1550
size_type capacity() const
Gets the maximum possible size of the unordered_set.
Definition unordered_set.h:1420
const_iterator cbegin() const
Definition unordered_set.h:495
iterator erase(const_iterator ielement)
Definition unordered_set.h:1055
Definition unordered_set.h:129
Definition unordered_set.h:70
Definition unordered_set.h:84
Definition unordered_set.h:112
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
iterator
Definition iterator.h:424
Definition unordered_set.h:152