31 #ifndef ETL_UNORDERED_MAP_INCLUDED
32 #define ETL_UNORDERED_MAP_INCLUDED
56 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
57 #include <initializer_list>
131 template <
typename TKey,
typename T,
typename THash = etl::hash<TKey>,
typename TKeyEqual = etl::equal_to<TKey> >
136 typedef ETL_OR_STD::pair<const TKey, T> value_type;
138 typedef TKey key_type;
139 typedef T mapped_type;
140 typedef THash hasher;
141 typedef TKeyEqual key_equal;
142 typedef value_type& reference;
143 typedef const value_type& const_reference;
144 #if ETL_CPP11_SUPPORTED
145 typedef value_type&& rvalue_reference;
147 typedef value_type* pointer;
148 typedef const value_type* const_pointer;
149 typedef size_t size_type;
159 node_t(const_reference key_value_pair_)
160 : key_value_pair(key_value_pair_)
164 value_type key_value_pair;
183 typedef typename iunordered_map::value_type value_type;
184 typedef typename iunordered_map::key_type key_type;
185 typedef typename iunordered_map::mapped_type mapped_type;
186 typedef typename iunordered_map::hasher hasher;
187 typedef typename iunordered_map::key_equal key_equal;
188 typedef typename iunordered_map::reference reference;
189 typedef typename iunordered_map::const_reference const_reference;
190 typedef typename iunordered_map::pointer pointer;
191 typedef typename iunordered_map::const_pointer const_pointer;
192 typedef typename iunordered_map::size_type size_type;
204 : pbuckets_end(other.pbuckets_end),
205 pbucket(other.pbucket),
216 if (inode == pbucket->
end())
220 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
226 if (pbucket != pbuckets_end)
228 inode = pbucket->
begin();
246 pbuckets_end = other.pbuckets_end;
247 pbucket = other.pbucket;
253 reference operator *()
255 return inode->key_value_pair;
259 const_reference operator *()
const
261 return inode->key_value_pair;
267 return &(inode->key_value_pair);
273 return &(inode->key_value_pair);
277 pointer operator ->()
279 return &(inode->key_value_pair);
283 const_pointer operator ->()
const
285 return &(inode->key_value_pair);
291 return lhs.compare(rhs);
297 return !(lhs == rhs);
304 : pbuckets_end(pbuckets_end_),
313 return rhs.inode == inode;
323 bucket_t* get_bucket_list_iterator()
344 typedef typename iunordered_map::value_type value_type;
345 typedef typename iunordered_map::key_type key_type;
346 typedef typename iunordered_map::mapped_type mapped_type;
347 typedef typename iunordered_map::hasher hasher;
348 typedef typename iunordered_map::key_equal key_equal;
349 typedef typename iunordered_map::reference reference;
350 typedef typename iunordered_map::const_reference const_reference;
351 typedef typename iunordered_map::pointer pointer;
352 typedef typename iunordered_map::const_pointer const_pointer;
353 typedef typename iunordered_map::size_type size_type;
365 : pbuckets_end(other.pbuckets_end),
366 pbucket(other.pbucket),
373 : pbuckets_end(other.pbuckets_end),
374 pbucket(other.pbucket),
385 if (inode == pbucket->
end())
389 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
395 if (pbucket != pbuckets_end)
397 inode = pbucket->
begin();
415 pbuckets_end = other.pbuckets_end;
416 pbucket = other.pbucket;
422 const_reference operator *()
const
424 return inode->key_value_pair;
430 return &(inode->key_value_pair);
434 const_pointer operator ->()
const
436 return &(inode->key_value_pair);
442 return lhs.compare(rhs);
448 return !(lhs == rhs);
455 : pbuckets_end(pbuckets_end_),
464 return rhs.inode == inode;
474 bucket_t* get_bucket_list_iterator()
490 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
498 return iterator((pbuckets + number_of_buckets), first, first->
begin());
525 return pbuckets[i].
begin();
534 return pbuckets[i].
cbegin();
543 return pbuckets[i].
cbegin();
552 return iterator((pbuckets + number_of_buckets), last, last->
end());
579 return pbuckets[i].
end();
588 return pbuckets[i].
cend();
597 return pbuckets[i].
cend();
606 return key_hash_function(key) % number_of_buckets;
615 size_t index = bucket(key);
617 return etl::distance(pbuckets[index].
begin(), pbuckets[index].
end());
626 return number_of_buckets;
635 return number_of_buckets;
652 while (inode != pbucket->
end())
655 if (key_equal_function(key, inode->key_value_pair.first))
658 return inode->key_value_pair.second;
668 node_t& node = create_data_node();
669 ::new (&node.key_value_pair) value_type(key, T());
670 ETL_INCREMENT_DEBUG_COUNT
674 adjust_first_last_markers_after_insert(pbucket);
676 return pbucket->
begin()->key_value_pair.second;
694 while (inode != pbucket->
end())
697 if (key_equal_function(key, inode->key_value_pair.first))
700 return inode->key_value_pair.second;
711 return begin()->second;
729 while (inode != pbucket->
end())
732 if (key_equal_function(key, inode->key_value_pair.first))
735 return inode->key_value_pair.second;
746 return begin()->second;
756 template <
typename TIterator>
757 void assign(TIterator first_, TIterator last_)
759 #if defined(ETL_DEBUG)
760 difference_type d = etl::distance(first_, last_);
767 while (first_ != last_)
778 ETL_OR_STD::pair<iterator, bool>
insert(const_reference key_value_pair)
780 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
784 const key_type& key = key_value_pair.first;
790 bucket_t* pbucket = pbuckets + index;
797 node_t& node = create_data_node();
798 ::new (&node.key_value_pair) value_type(key_value_pair);
799 ETL_INCREMENT_DEBUG_COUNT
804 adjust_first_last_markers_after_insert(pbucket);
806 result.first =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
807 result.second =
true;
815 while (inode != bucket.
end())
818 if (inode->key_value_pair.first == key)
828 if (inode == bucket.
end())
831 node_t& node = create_data_node();
832 ::new (&node.key_value_pair) value_type(key_value_pair);
833 ETL_INCREMENT_DEBUG_COUNT
837 adjust_first_last_markers_after_insert(&bucket);
840 result.first =
iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
841 result.second =
true;
848 #if ETL_CPP11_SUPPORTED
854 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference key_value_pair)
856 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
860 const key_type& key = key_value_pair.first;
866 bucket_t* pbucket = pbuckets + index;
867 bucket_t& bucket = *pbucket;
873 node_t& node = create_data_node();
874 ::new (&node.key_value_pair) value_type(
etl::move(key_value_pair));
875 ETL_INCREMENT_DEBUG_COUNT
878 bucket.insert_after(bucket.before_begin(), node);
880 adjust_first_last_markers_after_insert(pbucket);
882 result.first =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
883 result.second = true;
888 local_iterator inode_previous = bucket.before_begin();
889 local_iterator inode = bucket.begin();
891 while (inode != bucket.end())
894 if (inode->key_value_pair.first == key)
904 if (inode == bucket.end())
907 node_t& node = create_data_node();
908 ::new (&node.key_value_pair) value_type(
etl::move(key_value_pair));
909 ETL_INCREMENT_DEBUG_COUNT
912 bucket.insert_after(inode_previous, node);
913 adjust_first_last_markers_after_insert(&bucket);
916 result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
917 result.second = true;
933 return insert(key_value_pair).first;
936 #if ETL_CPP11_SUPPORTED
945 return insert(etl::move(key_value_pair)).first;
956 template <
class TIterator>
957 void insert(TIterator first_, TIterator last_)
959 while (first_ != last_)
981 while ((icurrent != bucket.
end()) && (icurrent->key_value_pair.first != key))
988 if (icurrent != bucket.
end())
991 icurrent->key_value_pair.~value_type();
992 pnodepool->
release(&*icurrent);
993 adjust_first_last_markers_after_erase(&bucket);
995 ETL_DECREMENT_DEBUG_COUNT
1008 iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator());
1011 bucket_t& bucket = ielement.get_bucket();
1016 while (iprevious->etl_next != &*icurrent)
1022 icurrent->key_value_pair.~value_type();
1023 pnodepool->
release(&*icurrent);
1024 adjust_first_last_markers_after_erase(&bucket);
1025 ETL_DECREMENT_DEBUG_COUNT
1040 if ((first_ ==
begin()) && (last_ ==
end()))
1047 bucket_t* pbucket = first_.get_bucket_list_iterator();
1048 bucket_t* pend_bucket = last_.get_bucket_list_iterator();
1054 while (iprevious->etl_next != &*icurrent)
1060 while ((icurrent != iend) || (pbucket != pend_bucket))
1063 icurrent->key_value_pair.~value_type();
1064 pnodepool->
release(&*icurrent);
1065 adjust_first_last_markers_after_erase(pbucket);
1066 ETL_DECREMENT_DEBUG_COUNT
1071 if ((icurrent != iend) || (pbucket != pend_bucket))
1074 if ((icurrent == pbucket->
end()))
1080 }
while (pbucket->
empty());
1083 icurrent = pbucket->
begin();
1088 return iterator((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
1106 return (
find(key) ==
end()) ? 0 : 1;
1118 bucket_t* pbucket = pbuckets + index;
1122 if (!bucket.
empty())
1128 while (inode != iend)
1131 if (key_equal_function(key, inode->key_value_pair.first))
1133 return iterator((pbuckets + number_of_buckets), pbucket, inode);
1152 bucket_t* pbucket = pbuckets + index;
1156 if (!bucket.
empty())
1162 while (inode != iend)
1165 if (key_equal_function(key, inode->key_value_pair.first))
1167 return iterator((pbuckets + number_of_buckets), pbucket, inode);
1195 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1216 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1224 return pnodepool->
size();
1248 return pnodepool->
empty();
1256 return pnodepool->
full();
1283 return key_hash_function;
1292 return key_equal_function;
1308 #if ETL_CPP11_SUPPORTED
1317 this->move(rhs.begin(), rhs.end());
1330 : pnodepool(&node_pool_),
1331 pbuckets(pbuckets_),
1332 number_of_buckets(number_of_buckets_)
1344 for (
size_t i = 0; i < number_of_buckets; ++i)
1348 if (!bucket.
empty())
1353 while (it != bucket.
end())
1356 it->key_value_pair.~value_type();
1357 ETL_DECREMENT_DEBUG_COUNT
1375 #if ETL_CPP11_SUPPORTED
1381 while (first != last)
1383 insert(etl::move(*first++));
1393 node_t& create_data_node()
1395 node_t* (
etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
1396 return *(pnodepool->*func)();
1402 void adjust_first_last_markers_after_insert(bucket_t* pbucket)
1411 if (pbucket < first)
1415 else if (pbucket > last)
1425 void adjust_first_last_markers_after_erase(bucket_t* pbucket)
1434 if (pbucket == first)
1437 while (first->empty())
1442 else if (pbucket == last)
1445 bucket_t* pbucket = first;
1446 bucket_t* pend = last;
1450 while (pbucket != pend)
1452 if (!pbucket->empty())
1477 const size_t number_of_buckets;
1484 hasher key_hash_function;
1487 key_equal key_equal_function;
1490 ETL_DECLARE_DEBUG_COUNT
1495 #if defined(ETL_POLYMORPHIC_UNORDERED_MAP) || defined(ETL_POLYMORPHIC_CONTAINERS)
1515 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1528 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1531 return !(lhs == rhs);
1537 template <
typename TKey,
typename TValue, const
size_t MAX_SIZE_, const
size_t MAX_BUCKETS_ = MAX_SIZE_,
typename THash = etl::hash<TKey>,
typename TKeyEqual = etl::equal_to<TKey> >
1546 static const size_t MAX_SIZE = MAX_SIZE_;
1547 static const size_t MAX_BUCKETS = MAX_BUCKETS_;
1553 :
base(node_pool, buckets, MAX_BUCKETS_)
1562 :
base(node_pool, buckets, MAX_BUCKETS_)
1567 #if ETL_CPP11_SUPPORTED
1572 : base(node_pool, buckets, MAX_BUCKETS_)
1576 base::move(other.begin(), other.end());
1587 template <
typename TIterator>
1589 :
base(node_pool, buckets, MAX_BUCKETS_)
1591 base::assign(first_, last_);
1594 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1598 unordered_map(std::initializer_list<ETL_OR_STD::pair<TKey, TValue>> init)
1599 : base(node_pool, buckets, MAX_BUCKETS_)
1601 base::assign(init.begin(), init.end());
1627 #if ETL_CPP11_SUPPORTED
1637 base::move(rhs.begin(), rhs.end());
1656 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1657 template <
typename T,
typename... Ts>
1658 unordered_map(T, Ts...)
1659 ->unordered_map<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...),
typename T::first_type>,
1660 typename T::second_type,
1661 1U +
sizeof...(Ts)>;
Definition: constant.h:45
const_iterator
Definition: intrusive_forward_list.h:423
iterator.
Definition: intrusive_forward_list.h:332
bool empty() const
Returns true if the list has no elements.
Definition: intrusive_forward_list.h:221
void clear()
Clears the intrusive_forward_list.
Definition: intrusive_forward_list.h:143
Definition: intrusive_forward_list.h:312
const_iterator cbegin() const
Gets the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:561
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition: intrusive_forward_list.h:632
iterator insert_after(iterator position, value_type &value)
Inserts a value to the intrusive_forward_list after the specified position.
Definition: intrusive_forward_list.h:609
iterator end()
Gets the end of the intrusive_forward_list.
Definition: intrusive_forward_list.h:569
iterator before_begin()
Gets before the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:545
const_iterator cend() const
Gets the end of the intrusive_forward_list.
Definition: intrusive_forward_list.h:585
iterator begin()
Gets the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:529
Definition: unordered_map.h:341
Definition: unordered_map.h:180
A templated unordered_map implementation that uses a fixed size buffer.
Definition: unordered_map.h:1539
unordered_map(const unordered_map &other)
Copy constructor.
Definition: unordered_map.h:1561
unordered_map()
Default constructor.
Definition: unordered_map.h:1552
~unordered_map()
Destructor.
Definition: unordered_map.h:1608
unordered_map(TIterator first_, TIterator last_)
Definition: unordered_map.h:1588
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
Definition: exception.h:47
size_t size() const
Returns the number of allocated items in the pool.
Definition: pool.h:309
bool empty() const
Definition: pool.h:318
void release_all()
Release all objects in the pool.
Definition: pool.h:264
bool full() const
Definition: pool.h:327
size_t max_size() const
Returns the maximum number of items in the pool.
Definition: pool.h:285
void release(const void *const p_object)
Definition: pool.h:255
size_t available() const
Returns the number of free items in the pool.
Definition: pool.h:301
float load_factor() const
Definition: unordered_map.h:1272
mapped_type & at(key_parameter_t key)
Definition: unordered_map.h:685
iterator find(key_parameter_t key)
Definition: unordered_map.h:1114
iterator erase(const_iterator first_, const_iterator last_)
Definition: unordered_map.h:1037
ETL_OR_STD::pair< iterator, bool > insert(const_reference key_value_pair)
Definition: unordered_map.h:778
iterator begin()
Definition: unordered_map.h:496
void initialise()
Initialise the unordered_map.
Definition: unordered_map.h:1339
size_t count(key_parameter_t key) const
Definition: unordered_map.h:1104
size_type size() const
Gets the size of the unordered_map.
Definition: unordered_map.h:1222
~iunordered_map()
For library debugging purposes only.
Definition: unordered_map.h:1502
iunordered_map & operator=(const iunordered_map &rhs)
Assignment operator.
Definition: unordered_map.h:1298
iterator end()
Definition: unordered_map.h:550
size_t available() const
Definition: unordered_map.h:1263
local_iterator end(size_t i)
Definition: unordered_map.h:577
size_type bucket_size(key_parameter_t key) const
Definition: unordered_map.h:613
hasher hash_function() const
Definition: unordered_map.h:1281
local_iterator begin(size_t i)
Definition: unordered_map.h:523
const mapped_type & at(key_parameter_t key) const
Definition: unordered_map.h:720
local_const_iterator begin(size_t i) const
Definition: unordered_map.h:532
void insert(TIterator first_, TIterator last_)
Definition: unordered_map.h:957
size_type max_bucket_count() const
Definition: unordered_map.h:624
const_iterator find(key_parameter_t key) const
Definition: unordered_map.h:1148
local_const_iterator end(size_t i) const
Definition: unordered_map.h:586
const_iterator end() const
Definition: unordered_map.h:559
bool full() const
Checks to see if the unordered_map is full.
Definition: unordered_map.h:1254
const_iterator begin() const
Definition: unordered_map.h:505
local_const_iterator cbegin(size_t i) const
Definition: unordered_map.h:541
mapped_type & operator[](key_parameter_t key)
Definition: unordered_map.h:643
void clear()
Clears the unordered_map.
Definition: unordered_map.h:1094
local_const_iterator cend(size_t i) const
Definition: unordered_map.h:595
iterator erase(const_iterator ielement)
Definition: unordered_map.h:1005
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(key_parameter_t key) const
Definition: unordered_map.h:1206
bool empty() const
Checks to see if the unordered_map is empty.
Definition: unordered_map.h:1246
key_equal key_eq() const
Definition: unordered_map.h:1290
iunordered_map(pool_t &node_pool_, bucket_t *pbuckets_, size_t number_of_buckets_)
Constructor.
Definition: unordered_map.h:1329
size_type capacity() const
Gets the maximum possible size of the unordered_map.
Definition: unordered_map.h:1238
size_type bucket_count() const
Definition: unordered_map.h:633
const_iterator cend() const
Definition: unordered_map.h:568
iterator insert(const_iterator, const_reference key_value_pair)
Definition: unordered_map.h:931
size_t erase(key_parameter_t key)
Definition: unordered_map.h:970
size_type max_size() const
Gets the maximum possible size of the unordered_map.
Definition: unordered_map.h:1230
size_type get_bucket_index(key_parameter_t key) const
Definition: unordered_map.h:604
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition: unordered_map.h:1185
void assign(TIterator first_, TIterator last_)
Definition: unordered_map.h:757
const_iterator cbegin() const
Definition: unordered_map.h:514
Definition: unordered_map.h:133
Definition: unordered_map.h:76
Definition: unordered_map.h:90
Definition: unordered_map.h:117
Definition: unordered_map.h:104
bool operator==(const etl::iunordered_map< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_map< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_map.h:1516
bool operator!=(const etl::iunordered_map< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_map< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_map.h:1529
Definition: absolute.h:37
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
A forward link.
Definition: intrusive_links.h:92
iterator
Definition: iterator.h:422
Definition: unordered_map.h:158