131 typedef TKey value_type;
132 typedef TKey key_type;
133 typedef THash hasher;
134 typedef TKeyEqual key_equal;
135 typedef value_type& reference;
136 typedef const value_type& const_reference;
138 typedef value_type&& rvalue_reference;
140 typedef value_type* pointer;
141 typedef const value_type* const_pointer;
142 typedef size_t size_type;
144 typedef const TKey& key_parameter_t;
150 struct node_t :
public link_t
152 node_t(const_reference key_)
160 friend bool operator==(
const node_t& lhs,
const node_t& rhs)
162 return (lhs.key == rhs.key);
165 friend bool operator!=(
const node_t& lhs,
const node_t& rhs)
167 return !(lhs == rhs);
178 typedef typename bucket_t::iterator local_iterator;
179 typedef typename bucket_t::const_iterator const_local_iterator;
182 class iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, TKey>
186 typedef typename etl::iterator<ETL_OR_STD::forward_iterator_tag, TKey>::value_type value_type;
187 typedef typename iunordered_set::key_type key_type;
188 typedef typename iunordered_set::hasher hasher;
189 typedef typename iunordered_set::key_equal key_equal;
190 typedef typename iunordered_set::reference reference;
191 typedef typename iunordered_set::const_reference const_reference;
192 typedef typename iunordered_set::pointer pointer;
193 typedef typename iunordered_set::const_pointer const_pointer;
194 typedef typename iunordered_set::size_type size_type;
196 friend class iunordered_set;
197 friend class const_iterator;
203 iterator(
const iterator& other)
204 : pbuckets_end(other.pbuckets_end)
205 , pbucket(other.pbucket)
211 iterator& operator++()
216 if (inode == pbucket->end())
220 while ((pbucket != pbuckets_end) && (pbucket->empty()))
226 if (pbucket != pbuckets_end)
228 inode = pbucket->begin();
236 iterator operator++(
int)
238 iterator temp(*
this);
244 iterator& operator=(
const iterator& other)
246 pbuckets_end = other.pbuckets_end;
247 pbucket = other.pbucket;
253 reference operator*()
const
259 pointer operator&()
const
261 return &(inode->key);
265 pointer operator->()
const
267 return &(inode->key);
271 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
273 return lhs.compare(rhs);
277 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
279 return !(lhs == rhs);
285 iterator(bucket_t* pbuckets_end_, bucket_t* pbucket_, local_iterator inode_)
286 : pbuckets_end(pbuckets_end_)
293 bool compare(
const iterator& rhs)
const
295 return rhs.inode == inode;
299 bucket_t& get_bucket()
305 bucket_t*& get_bucket_list_iterator()
311 local_iterator get_local_iterator()
316 bucket_t* pbuckets_end;
318 local_iterator inode;
322 class const_iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, const TKey>
326 typedef typename etl::iterator<ETL_OR_STD::forward_iterator_tag, const TKey>::value_type value_type;
327 typedef typename iunordered_set::key_type key_type;
328 typedef typename iunordered_set::hasher hasher;
329 typedef typename iunordered_set::key_equal key_equal;
330 typedef typename iunordered_set::reference reference;
331 typedef typename iunordered_set::const_reference const_reference;
332 typedef typename iunordered_set::pointer pointer;
333 typedef typename iunordered_set::const_pointer const_pointer;
334 typedef typename iunordered_set::size_type size_type;
336 friend class iunordered_set;
337 friend class iterator;
344 : pbuckets_end(other.pbuckets_end)
345 , pbucket(other.pbucket)
351 const_iterator(
const const_iterator& other)
352 : pbuckets_end(other.pbuckets_end)
353 , pbucket(other.pbucket)
359 const_iterator& operator++()
364 if (inode == pbucket->end())
369 while ((pbucket != pbuckets_end) && (pbucket->empty()))
375 if (pbucket != pbuckets_end)
377 inode = pbucket->begin();
385 const_iterator operator++(
int)
387 const_iterator temp(*
this);
393 const_iterator& operator=(
const const_iterator& other)
395 pbuckets_end = other.pbuckets_end;
396 pbucket = other.pbucket;
402 const_reference operator*()
const
408 const_pointer operator&()
const
410 return &(inode->key);
414 const_pointer operator->()
const
416 return &(inode->key);
420 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
422 return lhs.compare(rhs);
426 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
428 return !(lhs == rhs);
434 const_iterator(bucket_t* pbuckets_end_, bucket_t* pbucket_, local_iterator inode_)
435 : pbuckets_end(pbuckets_end_)
442 bool compare(
const const_iterator& rhs)
const
444 return rhs.inode == inode;
448 bucket_t& get_bucket()
454 bucket_t*& get_bucket_list_iterator()
460 local_iterator get_local_iterator()
465 bucket_t* pbuckets_end;
467 local_iterator inode;
470 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
478 return iterator(pbuckets + number_of_buckets, first, first->begin());
487 return const_iterator(pbuckets + number_of_buckets, first, first->begin());
496 return const_iterator(pbuckets + number_of_buckets, first, first->begin());
505 return pbuckets[i].begin();
512 const_local_iterator
begin(
size_t i)
const
514 return pbuckets[i].cbegin();
521 const_local_iterator
cbegin(
size_t i)
const
523 return pbuckets[i].cbegin();
532 return iterator(pbuckets + number_of_buckets, last, last->end());
539 const_iterator
end()
const
541 return const_iterator(pbuckets + number_of_buckets, last, last->end());
550 return const_iterator(pbuckets + number_of_buckets, last, last->end());
557 local_iterator
end(
size_t i)
559 return pbuckets[i].end();
566 const_local_iterator
end(
size_t i)
const
568 return pbuckets[i].cend();
575 const_local_iterator
cend(
size_t i)
const
577 return pbuckets[i].cend();
586 return key_hash_function(key) % number_of_buckets;
594 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
597 return key_hash_function(key) % number_of_buckets;
607 size_t index = bucket(key);
609 return etl::distance(pbuckets[index].
begin(), pbuckets[index].
end());
617 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
620 size_t index = bucket(key);
622 return etl::distance(pbuckets[index].
begin(), pbuckets[index].
end());
632 return number_of_buckets;
641 return number_of_buckets;
652 template <
typename TIterator>
653 void assign(TIterator first_, TIterator last_)
655#if ETL_IS_DEBUG_BUILD
656 difference_type d = etl::distance(first_, last_);
663 while (first_ != last_)
676 ETL_OR_STD::pair<iterator, bool>
insert(const_reference key)
678 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
682 iterator iter =
find(key);
690 result.second =
false;
699 bucket_t* pbucket = pbuckets + index;
700 bucket_t& bucket = *pbucket;
706 node_t* node = allocate_data_node();
708 ::new (&node->key) value_type(key);
709 ETL_INCREMENT_DEBUG_COUNT;
713 adjust_first_last_markers_after_insert(&bucket);
715 result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->
begin());
716 result.second =
true;
722 local_iterator inode = bucket.
begin();
724 while (inode != bucket.
end())
727 if (key_equal_function(inode->key, key))
737 if (inode == bucket.
end())
740 node_t* node = allocate_data_node();
742 ::new (&node->key) value_type(key);
743 ETL_INCREMENT_DEBUG_COUNT;
747 adjust_first_last_markers_after_insert(&bucket);
750 result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
751 result.second =
true;
765 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
766 ETL_OR_STD::pair<iterator, bool>
insert(
const K& key)
768 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
780 result.second =
false;
789 bucket_t* pbucket = pbuckets + index;
790 bucket_t& bucket = *pbucket;
796 node_t* node = allocate_data_node();
798 ::new (&node->key) value_type(key);
799 ETL_INCREMENT_DEBUG_COUNT;
802 bucket.insert_after(bucket.before_begin(), *node);
803 adjust_first_last_markers_after_insert(&bucket);
805 result.first =
iterator(pbuckets + number_of_buckets, pbucket, pbucket->
begin());
806 result.second = true;
811 local_iterator inode_previous = bucket.before_begin();
812 local_iterator inode = bucket.begin();
814 while (inode != bucket.end())
817 if (key_equal_function(inode->key, key))
827 if (inode == bucket.end())
830 node_t* node = allocate_data_node();
832 ::new (&node->key) value_type(key);
833 ETL_INCREMENT_DEBUG_COUNT;
836 bucket.insert_after(inode_previous, *node);
837 adjust_first_last_markers_after_insert(&bucket);
840 result.first =
iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
841 result.second = true;
856 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference key)
858 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
865 ETL_ASSERT_FAIL(ETL_ERROR(unordered_set_full));
870 result.second =
false;
879 bucket_t* pbucket = pbuckets + index;
880 bucket_t& bucket = *pbucket;
886 node_t* node = allocate_data_node();
888 ::new (&node->key) value_type(etl::move(key));
889 ETL_INCREMENT_DEBUG_COUNT;
892 bucket.insert_after(bucket.before_begin(), *node);
893 adjust_first_last_markers_after_insert(&bucket);
895 result.first =
iterator(pbuckets + number_of_buckets, pbucket, pbucket->
begin());
896 result.second = true;
901 local_iterator inode_previous = bucket.before_begin();
902 local_iterator inode = bucket.begin();
904 while (inode != bucket.end())
907 if (key_equal_function(inode->key, key))
917 if (inode == bucket.end())
920 node_t* node = allocate_data_node();
922 ::new (&node->key) value_type(etl::move(key));
923 ETL_INCREMENT_DEBUG_COUNT;
926 bucket.insert_after(inode_previous, *node);
927 adjust_first_last_markers_after_insert(&bucket);
930 result.first =
iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
931 result.second = true;
946 iterator
insert(const_iterator, const_reference key)
961 return insert(etl::move(key)).first;
973 template <
class TIterator>
974 void insert(TIterator first_, TIterator last_)
976 while (first_ != last_)
983#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
987 template <
typename... Args>
988 ETL_OR_STD::pair<iterator, bool> emplace(Args&&... args)
990 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
998 value_type temp_value(etl::forward<Args>(args)...);
1001 if (position ==
end())
1007 result.first = position;
1008 result.second =
false;
1013 node_t* node = allocate_data_node();
1015 ::new (&node->key) value_type(etl::forward<Args>(args)...);
1016 ETL_INCREMENT_DEBUG_COUNT;
1018 key_parameter_t key = node->key;
1024 bucket_t* pbucket = pbuckets + index;
1025 bucket_t& bucket = *pbucket;
1031 bucket.insert_after(bucket.before_begin(), *node);
1032 adjust_first_last_markers_after_insert(&bucket);
1034 result.first =
iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
1035 result.second =
true;
1040 local_iterator inode_previous = bucket.before_begin();
1041 local_iterator inode = bucket.begin();
1043 while (inode != bucket.end())
1046 if (key_equal_function(inode->key, key))
1056 if (inode == bucket.end())
1059 bucket.insert_after(inode_previous, *node);
1060 adjust_first_last_markers_after_insert(&bucket);
1063 result.first =
iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
1064 result.second =
true;
1069 node->key.~value_type();
1070 pnodepool->release(node);
1071 ETL_DECREMENT_DEBUG_COUNT;
1089 bucket_t& bucket = pbuckets[index];
1092 local_iterator icurrent = bucket.
begin();
1095 while ((icurrent != bucket.
end()) && (!key_equal_function(icurrent->key, key)))
1102 if (icurrent != bucket.
end())
1104 delete_data_node(iprevious, icurrent, bucket);
1117 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1118 size_t erase(
const K& key)
1123 bucket_t& bucket = pbuckets[index];
1126 local_iterator icurrent = bucket.begin();
1129 while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
1136 if (icurrent != bucket.end())
1138 delete_data_node(iprevious, icurrent, bucket);
1153 iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator());
1156 bucket_t& bucket = ielement.get_bucket();
1158 local_iterator icurrent = ielement.get_local_iterator();
1161 while (iprevious->etl_next != &*icurrent)
1166 delete_data_node(iprevious, icurrent, bucket);
1178 iterator
erase(const_iterator first_, const_iterator last_)
1181 if ((first_ ==
begin()) && (last_ ==
end()))
1188 bucket_t* pbucket = first_.get_bucket_list_iterator();
1189 bucket_t* pend_bucket = last_.get_bucket_list_iterator();
1191 local_iterator icurrent = first_.get_local_iterator();
1192 local_iterator iend = last_.get_local_iterator();
1196 while (iprevious->etl_next != &*icurrent)
1202 iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
1205 while ((icurrent != iend) || (pbucket != pend_bucket))
1207 icurrent = delete_data_node(iprevious, icurrent, *pbucket);
1210 if ((icurrent != iend) || (pbucket != pend_bucket))
1213 if ((icurrent == pbucket->
end()))
1218 }
while (pbucket->
empty());
1221 icurrent = pbucket->
begin();
1226 return ++ibefore_erased;
1244 return (
find(key) ==
end()) ? 0 : 1;
1253 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1254 size_t count(
const K& key)
const
1256 return (
find(key) ==
end()) ? 0 : 1;
1269 bucket_t* pbucket = pbuckets + index;
1270 bucket_t& bucket = *pbucket;
1273 if (!bucket.
empty())
1276 local_iterator inode = bucket.
begin();
1277 local_iterator iend = bucket.
end();
1279 while (inode != iend)
1282 if (key_equal_function(key, inode->key))
1284 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1299 const_iterator
find(key_parameter_t key)
const
1303 bucket_t* pbucket = pbuckets + index;
1304 bucket_t& bucket = *pbucket;
1307 if (!bucket.
empty())
1310 local_iterator inode = bucket.
begin();
1311 local_iterator iend = bucket.
end();
1313 while (inode != iend)
1316 if (key_equal_function(key, inode->key))
1318 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1334 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1339 bucket_t* pbucket = pbuckets + index;
1340 bucket_t& bucket = *pbucket;
1343 if (!bucket.empty())
1346 local_iterator inode = bucket.begin();
1347 local_iterator iend = bucket.end();
1349 while (inode != iend)
1352 if (key_equal_function(key, inode->key))
1354 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1371 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1376 bucket_t* pbucket = pbuckets + index;
1377 bucket_t& bucket = *pbucket;
1380 if (!bucket.empty())
1383 local_iterator inode = bucket.begin();
1384 local_iterator iend = bucket.end();
1386 while (inode != iend)
1389 if (key_equal_function(key, inode->key))
1391 return iterator(pbuckets + number_of_buckets, pbucket, inode);
1413 iterator f =
find(key);
1421 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1433 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(key_parameter_t key)
const
1435 const_iterator f =
find(key);
1436 const_iterator l = f;
1443 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1456 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1457 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
1467 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1481 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1482 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1492 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1501 return pnodepool->size();
1509 return pnodepool->max_size();
1517 return pnodepool->max_size();
1525 return pnodepool->empty();
1533 return pnodepool->full();
1542 return pnodepool->available();
1560 return key_hash_function;
1569 return key_equal_function;
1581 key_equal_function = rhs.
key_eq();
1598 key_hash_function = rhs.hash_function();
1599 key_equal_function = rhs.key_eq();
1600 move(rhs.begin(), rhs.end());
1619 template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value,
int> = 0>
1631 iunordered_set(pool_t& node_pool_, bucket_t* pbuckets_,
size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_)
1632 : pnodepool(&node_pool_)
1633 , pbuckets(pbuckets_)
1634 , number_of_buckets(number_of_buckets_)
1637 , key_hash_function(key_hash_function_)
1638 , key_equal_function(key_equal_function_)
1650 for (
size_t i = 0UL; i < number_of_buckets; ++i)
1652 bucket_t& bucket = pbuckets[i];
1654 if (!bucket.
empty())
1657 local_iterator it = bucket.
begin();
1659 while (it != bucket.
end())
1662 it->key.~value_type();
1664 ETL_DECREMENT_DEBUG_COUNT;
1673 pnodepool->release_all();
1686 #if ETL_IS_DEBUG_BUILD
1707 node_t* allocate_data_node()
1710 return (pnodepool->*func)();
1716 void adjust_first_last_markers_after_insert(bucket_t* pbucket)
1725 if (pbucket < first)
1729 else if (pbucket > last)
1739 void adjust_first_last_markers_after_erase(bucket_t* pbucket)
1748 if (pbucket == first)
1752 while (first->empty())
1757 else if (pbucket == last)
1762 bucket_t* pend = last;
1766 while (pbucket != pend)
1768 if (!pbucket->empty())
1782 local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
1784 local_iterator inext = bucket.erase_after(iprevious);
1785 icurrent->key.~value_type();
1786 pnodepool->release(&*icurrent);
1787 adjust_first_last_markers_after_erase(&bucket);
1788 ETL_DECREMENT_DEBUG_COUNT;
1803 const size_t number_of_buckets;
1810 hasher key_hash_function;
1813 key_equal key_equal_function;
1816 ETL_DECLARE_DEBUG_COUNT;
1821#if defined(ETL_POLYMORPHIC_UNORDERED_SET) || defined(ETL_POLYMORPHIC_CONTAINERS)