31 #ifndef ETL_UNORDERED_MULTIMAP_INCLUDED
32 #define ETL_UNORDERED_MULTIMAP_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;
157 node_t(const_reference key_value_pair_)
158 : key_value_pair(key_value_pair_)
162 value_type key_value_pair;
181 typedef typename iunordered_multimap::value_type value_type;
182 typedef typename iunordered_multimap::key_type key_type;
183 typedef typename iunordered_multimap::mapped_type mapped_type;
184 typedef typename iunordered_multimap::hasher hasher;
185 typedef typename iunordered_multimap::key_equal key_equal;
186 typedef typename iunordered_multimap::reference reference;
187 typedef typename iunordered_multimap::const_reference const_reference;
188 typedef typename iunordered_multimap::pointer pointer;
189 typedef typename iunordered_multimap::const_pointer const_pointer;
190 typedef typename iunordered_multimap::size_type size_type;
202 : pbuckets_end(other.pbuckets_end),
203 pbucket(other.pbucket),
214 if (inode == pbucket->
end())
218 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
224 if (pbucket != pbuckets_end)
226 inode = pbucket->
begin();
244 pbuckets_end = other.pbuckets_end;
245 pbucket = other.pbucket;
251 reference operator *()
253 return inode->key_value_pair;
257 const_reference operator *()
const
259 return inode->key_value_pair;
265 return &(inode->key_value_pair);
271 return &(inode->key_value_pair);
275 pointer operator ->()
277 return &(inode->key_value_pair);
281 const_pointer operator ->()
const
283 return &(inode->key_value_pair);
289 return lhs.compare(rhs);
295 return !(lhs == rhs);
302 : pbuckets_end(pbuckets_end_),
311 return rhs.inode == inode;
321 bucket_t*& get_bucket_list_iterator()
342 typedef typename iunordered_multimap::value_type value_type;
343 typedef typename iunordered_multimap::key_type key_type;
344 typedef typename iunordered_multimap::mapped_type mapped_type;
345 typedef typename iunordered_multimap::hasher hasher;
346 typedef typename iunordered_multimap::key_equal key_equal;
347 typedef typename iunordered_multimap::reference reference;
348 typedef typename iunordered_multimap::const_reference const_reference;
349 typedef typename iunordered_multimap::pointer pointer;
350 typedef typename iunordered_multimap::const_pointer const_pointer;
351 typedef typename iunordered_multimap::size_type size_type;
363 : pbuckets_end(other.pbuckets_end),
364 pbucket(other.pbucket),
371 : pbuckets_end(other.pbuckets_end),
372 pbucket(other.pbucket),
383 if (inode == pbucket->
end())
388 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
394 if (pbucket != pbuckets_end)
396 inode = pbucket->
begin();
414 pbuckets_end = other.pbuckets_end;
415 pbucket = other.pbucket;
421 const_reference operator *()
const
423 return inode->key_value_pair;
429 return &(inode->key_value_pair);
433 const_pointer operator ->()
const
435 return &(inode->key_value_pair);
441 return lhs.compare(rhs);
447 return !(lhs == rhs);
454 : pbuckets_end(pbuckets_end_),
463 return rhs.inode == inode;
473 bucket_t*& get_bucket_list_iterator()
489 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
497 return iterator((pbuckets + number_of_buckets), first, first->
begin());
524 return pbuckets[i].
begin();
533 return pbuckets[i].
cbegin();
542 return pbuckets[i].
cbegin();
551 return iterator((pbuckets + number_of_buckets), last, last->
end());
578 return pbuckets[i].
end();
587 return pbuckets[i].
cend();
596 return pbuckets[i].
cend();
605 return key_hash_function(key) % number_of_buckets;
614 size_t index = bucket(key);
616 return etl::distance(pbuckets[index].
begin(), pbuckets[index].
end());
625 return number_of_buckets;
634 return number_of_buckets;
644 template <
typename TIterator>
645 void assign(TIterator first_, TIterator last_)
647 #if defined(ETL_DEBUG)
648 difference_type d = etl::distance(first_, last_);
655 while (first_ != last_)
672 const key_type& key = key_value_pair.first;
678 bucket_t* pbucket = pbuckets + index;
685 node_t& node = create_data_node();
686 ::new (&node.key_value_pair) value_type(key_value_pair);
687 ETL_INCREMENT_DEBUG_COUNT
691 adjust_first_last_markers_after_insert(pbucket);
693 result =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
701 while (inode != bucket.
end())
704 if (inode->key_value_pair.first == key)
714 node_t& node = create_data_node();
715 ::new (&node.key_value_pair) value_type(key_value_pair);
716 ETL_INCREMENT_DEBUG_COUNT
720 adjust_first_last_markers_after_insert(&bucket);
723 result =
iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
729 #if ETL_CPP11_SUPPORTED
741 const key_type& key = key_value_pair.first;
747 bucket_t* pbucket = pbuckets + index;
748 bucket_t& bucket = *pbucket;
754 node_t& node = create_data_node();
755 ::new (&node.key_value_pair) value_type(
etl::move(key_value_pair));
756 ETL_INCREMENT_DEBUG_COUNT
759 bucket.insert_after(bucket.before_begin(), node);
760 adjust_first_last_markers_after_insert(pbucket);
762 result =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
767 local_iterator inode_previous = bucket.before_begin();
768 local_iterator inode = bucket.begin();
770 while (inode != bucket.end())
773 if (inode->key_value_pair.first == key)
783 node_t& node = create_data_node();
784 ::new (&node.key_value_pair) value_type(
etl::move(key_value_pair));
785 ETL_INCREMENT_DEBUG_COUNT
788 bucket.insert_after(inode_previous, node);
789 adjust_first_last_markers_after_insert(&bucket);
792 result = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
807 return insert(key_value_pair);
810 #if ETL_CPP11_SUPPORTED
819 return insert(etl::move(key_value_pair));
830 template <
class TIterator>
831 void insert(TIterator first_, TIterator last_)
833 while (first_ != last_)
849 bucket_t& bucket = pbuckets[bucket_id];
854 while (icurrent != bucket.
end())
856 if (icurrent->key_value_pair.first == key)
859 icurrent->key_value_pair.~value_type();
860 pnodepool->
release(&*icurrent);
861 adjust_first_last_markers_after_erase(&bucket);
863 icurrent = iprevious;
864 ETL_DECREMENT_DEBUG_COUNT
884 iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator());
887 bucket_t& bucket = ielement.get_bucket();
892 while (iprevious->etl_next != &*icurrent)
898 icurrent->key_value_pair.~value_type();
899 pnodepool->
release(&*icurrent);
900 adjust_first_last_markers_after_erase(&bucket);
901 ETL_DECREMENT_DEBUG_COUNT
916 if ((first_ ==
begin()) && (last_ ==
end()))
923 iterator result((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
926 bucket_t* pbucket = first_.get_bucket_list_iterator();
927 bucket_t* pend_bucket = last_.get_bucket_list_iterator();
933 while (iprevious->etl_next != &*icurrent)
939 while ((icurrent != iend) || (pbucket != pend_bucket))
943 icurrent->key_value_pair.~value_type();
944 pnodepool->
release(&*icurrent);
945 adjust_first_last_markers_after_erase(pbucket);
946 ETL_DECREMENT_DEBUG_COUNT
951 if ((icurrent != iend) || (pbucket != pend_bucket))
954 if ((icurrent == pbucket->
end()))
960 }
while (pbucket->
empty());
963 icurrent = pbucket->
begin();
995 while ((l !=
end()) && (key == l->first))
1014 bucket_t* pbucket = pbuckets + index;
1018 if (!bucket.
empty())
1024 while (inode != iend)
1027 if (key_equal_function(key, inode->key_value_pair.first))
1029 return iterator((pbuckets + number_of_buckets), pbucket, inode);
1048 bucket_t* pbucket = pbuckets + index;
1052 if (!bucket.
empty())
1058 while (inode != iend)
1061 if (key_equal_function(key, inode->key_value_pair.first))
1063 return const_iterator((pbuckets + number_of_buckets), pbucket, inode);
1090 while ((l !=
end()) && (key == l->first))
1096 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1116 while ((l !=
end()) && (key == l->first))
1122 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1130 return pnodepool->
size();
1154 return pnodepool->
empty();
1162 return pnodepool->
full();
1189 return key_hash_function;
1198 return key_equal_function;
1215 #if ETL_CPP11_SUPPORTED
1224 move(rhs.begin(), rhs.end());
1237 : pnodepool(&node_pool_),
1238 pbuckets(pbuckets_),
1239 number_of_buckets(number_of_buckets_)
1251 for (
size_t i = 0; i < number_of_buckets; ++i)
1255 if (!bucket.
empty())
1260 while (it != bucket.
end())
1263 it->key_value_pair.~value_type();
1265 ETL_DECREMENT_DEBUG_COUNT
1281 #if ETL_CPP11_SUPPORTED
1287 while (first != last)
1289 insert(etl::move(*first++));
1299 node_t& create_data_node()
1301 node_t* (
etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
1302 return *(pnodepool->*func)();
1308 void adjust_first_last_markers_after_insert(bucket_t* pbucket)
1317 if (pbucket < first)
1321 else if (pbucket > last)
1331 void adjust_first_last_markers_after_erase(bucket_t* pbucket)
1340 if (pbucket == first)
1343 while (first->empty())
1348 else if (pbucket == last)
1351 bucket_t* pbucket = first;
1352 bucket_t* pend = last;
1356 while (pbucket != pend)
1358 if (!pbucket->empty())
1383 const size_t number_of_buckets;
1390 hasher key_hash_function;
1393 key_equal key_equal_function;
1396 ETL_DECLARE_DEBUG_COUNT
1401 #if defined(ETL_POLYMORPHIC_UNORDERED_MULTIMAP) || defined(ETL_POLYMORPHIC_CONTAINERS)
1421 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1434 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1437 return !(lhs == rhs);
1443 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> >
1452 static const size_t MAX_SIZE = MAX_SIZE_;
1453 static const size_t MAX_BUCKETS = MAX_BUCKETS_;
1459 :
base(node_pool, buckets, MAX_BUCKETS)
1468 :
base(node_pool, buckets, MAX_BUCKETS)
1477 #if ETL_CPP11_SUPPORTED
1482 : base(node_pool, buckets, MAX_BUCKETS)
1487 base::move(other.begin(), other.end());
1498 template <
typename TIterator>
1500 :
base(node_pool, buckets, MAX_BUCKETS)
1502 base::assign(first_, last_);
1505 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1510 : base(node_pool, buckets, MAX_BUCKETS_)
1512 base::assign(init.begin(), init.end());
1538 #if ETL_CPP11_SUPPORTED
1548 base::move(rhs.begin(), rhs.end());
1567 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1568 template <
typename T,
typename... Ts>
1569 unordered_multimap(T, Ts...)
1570 ->unordered_multimap<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...),
typename T::first_type>,
1571 typename T::second_type,
1572 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_multimap.h:339
Definition: unordered_multimap.h:178
A templated unordered_multimap implementation that uses a fixed size buffer.
Definition: unordered_multimap.h:1445
unordered_multimap(const unordered_multimap &other)
Copy constructor.
Definition: unordered_multimap.h:1467
unordered_multimap(TIterator first_, TIterator last_)
Definition: unordered_multimap.h:1499
unordered_multimap()
Default constructor.
Definition: unordered_multimap.h:1458
~unordered_multimap()
Destructor.
Definition: unordered_multimap.h:1519
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
iterator end()
Definition: unordered_multimap.h:549
float load_factor() const
Definition: unordered_multimap.h:1178
size_t erase(key_parameter_t key)
Definition: unordered_multimap.h:844
size_type get_bucket_index(key_parameter_t key) const
Definition: unordered_multimap.h:603
void assign(TIterator first_, TIterator last_)
Definition: unordered_multimap.h:645
size_t available() const
Definition: unordered_multimap.h:1169
key_equal key_eq() const
Definition: unordered_multimap.h:1196
iterator find(key_parameter_t key)
Definition: unordered_multimap.h:1010
bool empty() const
Checks to see if the unordered_multimap is empty.
Definition: unordered_multimap.h:1152
size_type bucket_count() const
Definition: unordered_multimap.h:632
iterator insert(const_reference key_value_pair)
Definition: unordered_multimap.h:666
iterator erase(const_iterator ielement)
Definition: unordered_multimap.h:881
local_iterator end(size_t i)
Definition: unordered_multimap.h:576
size_type capacity() const
Gets the maximum possible size of the unordered_multimap.
Definition: unordered_multimap.h:1144
void initialise()
Initialise the unordered_multimap.
Definition: unordered_multimap.h:1246
const_iterator end() const
Definition: unordered_multimap.h:558
size_t count(key_parameter_t key) const
Definition: unordered_multimap.h:984
size_type size() const
Gets the size of the unordered_multimap.
Definition: unordered_multimap.h:1128
void clear()
Clears the unordered_multimap.
Definition: unordered_multimap.h:974
const_iterator begin() const
Definition: unordered_multimap.h:504
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(key_parameter_t key) const
Definition: unordered_multimap.h:1107
hasher hash_function() const
Definition: unordered_multimap.h:1187
iterator erase(const_iterator first_, const_iterator last_)
Definition: unordered_multimap.h:913
local_const_iterator cbegin(size_t i) const
Definition: unordered_multimap.h:540
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition: unordered_multimap.h:1081
iterator insert(const_iterator, const_reference key_value_pair)
Definition: unordered_multimap.h:805
size_type max_size() const
Gets the maximum possible size of the unordered_multimap.
Definition: unordered_multimap.h:1136
const_iterator cbegin() const
Definition: unordered_multimap.h:513
local_iterator begin(size_t i)
Definition: unordered_multimap.h:522
~iunordered_multimap()
For library debugging purposes only.
Definition: unordered_multimap.h:1408
const_iterator find(key_parameter_t key) const
Definition: unordered_multimap.h:1044
local_const_iterator end(size_t i) const
Definition: unordered_multimap.h:585
iunordered_multimap(pool_t &node_pool_, bucket_t *pbuckets_, size_t number_of_buckets_)
Constructor.
Definition: unordered_multimap.h:1236
size_type bucket_size(key_parameter_t key) const
Definition: unordered_multimap.h:612
local_const_iterator begin(size_t i) const
Definition: unordered_multimap.h:531
size_type max_bucket_count() const
Definition: unordered_multimap.h:623
const_iterator cend() const
Definition: unordered_multimap.h:567
void insert(TIterator first_, TIterator last_)
Definition: unordered_multimap.h:831
bool full() const
Checks to see if the unordered_multimap is full.
Definition: unordered_multimap.h:1160
iunordered_multimap & operator=(const iunordered_multimap &rhs)
Assignment operator.
Definition: unordered_multimap.h:1204
local_const_iterator cend(size_t i) const
Definition: unordered_multimap.h:594
iterator begin()
Definition: unordered_multimap.h:495
Definition: unordered_multimap.h:133
Definition: unordered_multimap.h:76
Definition: unordered_multimap.h:90
Definition: unordered_multimap.h:117
Definition: unordered_multimap.h:104
bool operator==(const etl::iunordered_multimap< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_multimap< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_multimap.h:1422
bool operator!=(const etl::iunordered_multimap< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_multimap< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_multimap.h:1435
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_multimap.h:156