31 #ifndef ETL_UNORDERED_MULTISET_INCLUDED
32 #define ETL_UNORDERED_MULTISET_INCLUDED
55 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
56 #include <initializer_list>
130 template <
typename TKey,
typename THash = etl::hash<TKey>,
typename TKeyEqual = etl::equal_to<TKey> >
135 typedef TKey value_type;
136 typedef TKey key_type;
137 typedef THash hasher;
138 typedef TKeyEqual key_equal;
139 typedef value_type& reference;
140 typedef const value_type& const_reference;
141 #if ETL_CPP11_SUPPORTED
142 typedef value_type&& rvalue_reference;
144 typedef value_type* pointer;
145 typedef const value_type* const_pointer;
146 typedef size_t size_type;
155 node_t(const_reference key_)
179 typedef typename iunordered_multiset::value_type value_type;
180 typedef typename iunordered_multiset::key_type key_type;
181 typedef typename iunordered_multiset::hasher hasher;
182 typedef typename iunordered_multiset::key_equal key_equal;
183 typedef typename iunordered_multiset::reference reference;
184 typedef typename iunordered_multiset::const_reference const_reference;
185 typedef typename iunordered_multiset::pointer pointer;
186 typedef typename iunordered_multiset::const_pointer const_pointer;
187 typedef typename iunordered_multiset::size_type size_type;
199 : pbuckets_end(other.pbuckets_end),
200 pbucket(other.pbucket),
211 if (inode == pbucket->
end())
215 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
221 if (pbucket != pbuckets_end)
223 inode = pbucket->
begin();
241 pbuckets_end = other.pbuckets_end;
242 pbucket = other.pbucket;
248 reference operator *()
254 const_reference operator *()
const
262 return &(inode->key);
268 return &(inode->key);
272 pointer operator ->()
274 return &(inode->key);
278 const_pointer operator ->()
const
280 return &(inode->key);
286 return lhs.compare(rhs);
292 return !(lhs == rhs);
299 : pbuckets_end(pbuckets_end_),
308 return rhs.inode == inode;
318 bucket_t*& get_bucket_list_iterator()
339 typedef typename iunordered_multiset::value_type value_type;
340 typedef typename iunordered_multiset::key_type key_type;
341 typedef typename iunordered_multiset::hasher hasher;
342 typedef typename iunordered_multiset::key_equal key_equal;
343 typedef typename iunordered_multiset::reference reference;
344 typedef typename iunordered_multiset::const_reference const_reference;
345 typedef typename iunordered_multiset::pointer pointer;
346 typedef typename iunordered_multiset::const_pointer const_pointer;
347 typedef typename iunordered_multiset::size_type size_type;
359 : pbuckets_end(other.pbuckets_end),
360 pbucket(other.pbucket),
367 : pbuckets_end(other.pbuckets_end),
368 pbucket(other.pbucket),
379 if (inode == pbucket->
end())
384 while ((pbucket != pbuckets_end) && (pbucket->
empty()))
390 if (pbucket != pbuckets_end)
392 inode = pbucket->
begin();
410 pbuckets_end = other.pbuckets_end;
411 pbucket = other.pbucket;
417 const_reference operator *()
const
425 return &(inode->key);
429 const_pointer operator ->()
const
431 return &(inode->key);
437 return lhs.compare(rhs);
443 return !(lhs == rhs);
450 : pbuckets_end(pbuckets_end_),
459 return rhs.inode == inode;
469 bucket_t*& get_bucket_list_iterator()
485 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
493 return iterator((pbuckets + number_of_buckets), first, first->
begin());
520 return pbuckets[i].
begin();
529 return pbuckets[i].
cbegin();
538 return pbuckets[i].
cbegin();
547 return iterator((pbuckets + number_of_buckets), last, last->
end());
574 return pbuckets[i].
end();
583 return pbuckets[i].
cend();
592 return pbuckets[i].
cend();
601 return key_hash_function(key) % number_of_buckets;
610 size_t index = bucket(key);
612 return etl::distance(pbuckets[index].
begin(), pbuckets[index].
end());
621 return number_of_buckets;
630 return number_of_buckets;
640 template <
typename TIterator>
641 void assign(TIterator first_, TIterator last_)
643 #if defined(ETL_DEBUG)
644 difference_type d = etl::distance(first_, last_);
651 while (first_ != last_)
662 ETL_OR_STD::pair<iterator, bool>
insert(const_reference key)
664 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
672 bucket_t* pbucket = pbuckets + index;
679 node_t& node = create_data_node();
680 ::new (&node.key) value_type(key);
681 ETL_INCREMENT_DEBUG_COUNT
685 adjust_first_last_markers_after_insert(&bucket);
687 result.first =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
688 result.second =
true;
696 while (inode != bucket.
end())
699 if (inode->key == key)
709 node_t& node = create_data_node();
710 ::new (&node.key) value_type(key);
711 ETL_INCREMENT_DEBUG_COUNT
715 adjust_first_last_markers_after_insert(&bucket);
718 result.first =
iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
719 result.second =
true;
725 #if ETL_CPP11_SUPPORTED
731 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference key)
733 ETL_OR_STD::pair<iterator, bool> result(
end(),
false);
741 bucket_t* pbucket = pbuckets + index;
742 bucket_t& bucket = *pbucket;
748 node_t& node = create_data_node();
749 ::new (&node.key) value_type(
etl::move(key));
750 ETL_INCREMENT_DEBUG_COUNT
753 bucket.insert_after(bucket.before_begin(), node);
754 adjust_first_last_markers_after_insert(&bucket);
756 result.first =
iterator((pbuckets + number_of_buckets), pbucket, pbucket->
begin());
757 result.second = true;
762 local_iterator inode_previous = bucket.before_begin();
763 local_iterator inode = bucket.begin();
765 while (inode != bucket.end())
768 if (inode->key == key)
778 node_t& node = create_data_node();
779 ::new (&node.key) value_type(
etl::move(key));
780 ETL_INCREMENT_DEBUG_COUNT
783 bucket.insert_after(inode_previous, node);
784 adjust_first_last_markers_after_insert(&bucket);
787 result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
788 result.second = true;
813 template <
class TIterator>
814 void insert(TIterator first_, TIterator last_)
816 while (first_ != last_)
832 bucket_t& bucket = pbuckets[bucket_id];
837 while (icurrent != bucket.
end())
839 if (icurrent->key == key)
842 icurrent->key.~value_type();
843 pnodepool->
release(&*icurrent);
844 adjust_first_last_markers_after_erase(&bucket);
846 icurrent = iprevious;
847 ETL_DECREMENT_DEBUG_COUNT
867 iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator());
870 bucket_t& bucket = ielement.get_bucket();
875 while (iprevious->etl_next != &*icurrent)
881 icurrent->key.~value_type();
882 pnodepool->
release(&*icurrent);
883 adjust_first_last_markers_after_erase(&bucket);
884 ETL_DECREMENT_DEBUG_COUNT
899 if ((first_ ==
begin()) && (last_ ==
end()))
906 iterator result((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
909 bucket_t* pbucket = first_.get_bucket_list_iterator();
910 bucket_t* pend_bucket = last_.get_bucket_list_iterator();
916 while (iprevious->etl_next != &*icurrent)
922 while ((icurrent != iend) || (pbucket != pend_bucket))
926 icurrent->key.~value_type();
927 pnodepool->
release(&*icurrent);
928 adjust_first_last_markers_after_erase(pbucket);
929 ETL_DECREMENT_DEBUG_COUNT
934 if ((icurrent != iend) || (pbucket != pend_bucket))
937 if ((icurrent == pbucket->
end()))
943 }
while (pbucket->
empty());
946 icurrent = pbucket->
begin();
978 while ((l !=
end()) && (key == *l))
997 bucket_t* pbucket = pbuckets + index;
1001 if (!bucket.
empty())
1007 while (inode != iend)
1010 if (key_equal_function(key, inode->key))
1012 return iterator((pbuckets + number_of_buckets), pbucket, inode);
1031 bucket_t* pbucket = pbuckets + index;
1035 if (!bucket.
empty())
1041 while (inode != iend)
1044 if (key_equal_function(key, inode->key))
1046 return iterator((pbuckets + number_of_buckets), pbucket, inode);
1073 while ((l !=
end()) && (key == *l))
1079 return ETL_OR_STD::pair<iterator, iterator>(f, l);
1099 while ((l !=
end()) && (key == *l))
1105 return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
1113 return pnodepool->
size();
1137 return pnodepool->
empty();
1145 return pnodepool->
full();
1172 return key_hash_function;
1181 return key_equal_function;
1198 #if ETL_CPP11_SUPPORTED
1208 move(rhs.begin(), rhs.end());
1221 : pnodepool(&node_pool_),
1222 pbuckets(pbuckets_),
1223 number_of_buckets(number_of_buckets_)
1235 for (
size_t i = 0; i < number_of_buckets; ++i)
1239 if (!bucket.
empty())
1244 while (it != bucket.
end())
1247 it->key.~value_type();
1249 ETL_DECREMENT_DEBUG_COUNT
1265 #if ETL_CPP11_SUPPORTED
1271 while (first != last)
1273 insert(etl::move(*first++));
1283 node_t& create_data_node()
1285 node_t* (
etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
1286 return *(pnodepool->*func)();
1292 void adjust_first_last_markers_after_insert(bucket_t* pbucket)
1301 if (pbucket < first)
1305 else if (pbucket > last)
1315 void adjust_first_last_markers_after_erase(bucket_t* pbucket)
1324 if (pbucket == first)
1327 while (first->empty())
1332 else if (pbucket == last)
1335 bucket_t* pbucket = first;
1336 bucket_t* pend = last;
1340 while (pbucket != pend)
1342 if (!pbucket->empty())
1367 const size_t number_of_buckets;
1374 hasher key_hash_function;
1377 key_equal key_equal_function;
1380 ETL_DECLARE_DEBUG_COUNT
1385 #if defined(ETL_POLYMORPHIC_UNORDERED_MULTISET) || defined(ETL_POLYMORPHIC_CONTAINERS)
1405 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1418 template <
typename TKey,
typename TMapped,
typename TKeyCompare>
1421 return !(lhs == rhs);
1427 template <
typename TKey, const
size_t MAX_SIZE_,
size_t MAX_BUCKETS_ = MAX_SIZE_,
typename THash = etl::hash<TKey>,
typename TKeyEqual = etl::equal_to<TKey> >
1436 static const size_t MAX_SIZE = MAX_SIZE_;
1437 static const size_t MAX_BUCKETS = MAX_BUCKETS_;
1444 :
base(node_pool, buckets, MAX_BUCKETS)
1453 :
base(node_pool, buckets, MAX_BUCKETS)
1463 #if ETL_CPP11_SUPPORTED
1468 : base(node_pool, buckets, MAX_BUCKETS)
1473 base::move(other.begin(), other.end());
1484 template <
typename TIterator>
1486 :
base(node_pool, buckets, MAX_BUCKETS)
1488 base::assign(first_, last_);
1491 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1496 : base(node_pool, buckets, MAX_BUCKETS)
1498 base::assign(init.begin(), init.end());
1524 #if ETL_CPP11_SUPPORTED
1534 base::move(rhs.begin(), rhs.end());
1553 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1554 template <
typename T,
typename... Ts>
1555 unordered_multiset(T, Ts...)
1556 ->unordered_multiset<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 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_multiset.h:336
Definition: unordered_multiset.h:176
A templated unordered_multiset implementation that uses a fixed size buffer.
Definition: unordered_multiset.h:1429
unordered_multiset(TIterator first_, TIterator last_)
Definition: unordered_multiset.h:1485
~unordered_multiset()
Destructor.
Definition: unordered_multiset.h:1505
unordered_multiset(const unordered_multiset &other)
Copy constructor.
Definition: unordered_multiset.h:1452
unordered_multiset()
Default constructor.
Definition: unordered_multiset.h:1443
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
iunordered_multiset(pool_t &node_pool_, bucket_t *pbuckets_, size_t number_of_buckets_)
Constructor.
Definition: unordered_multiset.h:1220
~iunordered_multiset()
For library debugging purposes only.
Definition: unordered_multiset.h:1392
size_t available() const
Definition: unordered_multiset.h:1152
const_iterator cend() const
Definition: unordered_multiset.h:563
const_iterator begin() const
Definition: unordered_multiset.h:500
size_t erase(key_parameter_t key)
Definition: unordered_multiset.h:827
void initialise()
Initialise the unordered_multiset.
Definition: unordered_multiset.h:1230
iterator end()
Definition: unordered_multiset.h:545
size_type max_size() const
Gets the maximum possible size of the unordered_multiset.
Definition: unordered_multiset.h:1119
size_type get_bucket_index(key_parameter_t key) const
Definition: unordered_multiset.h:599
ETL_OR_STD::pair< const_iterator, const_iterator > equal_range(key_parameter_t key) const
Definition: unordered_multiset.h:1090
const_iterator find(key_parameter_t key) const
Definition: unordered_multiset.h:1027
local_iterator begin(size_t i)
Definition: unordered_multiset.h:518
void assign(TIterator first_, TIterator last_)
Definition: unordered_multiset.h:641
const_iterator cbegin() const
Definition: unordered_multiset.h:509
const_iterator end() const
Definition: unordered_multiset.h:554
size_type bucket_size(key_parameter_t key) const
Definition: unordered_multiset.h:608
local_const_iterator cbegin(size_t i) const
Definition: unordered_multiset.h:536
void insert(TIterator first_, TIterator last_)
Definition: unordered_multiset.h:814
void clear()
Clears the unordered_multiset.
Definition: unordered_multiset.h:957
iterator erase(const_iterator first_, const_iterator last_)
Definition: unordered_multiset.h:896
iterator find(key_parameter_t key)
Definition: unordered_multiset.h:993
iunordered_multiset & operator=(const iunordered_multiset &rhs)
Assignment operator.
Definition: unordered_multiset.h:1187
iterator insert(const_iterator position, const_reference key)
Definition: unordered_multiset.h:801
local_const_iterator begin(size_t i) const
Definition: unordered_multiset.h:527
iterator begin()
Definition: unordered_multiset.h:491
iterator erase(const_iterator ielement)
Definition: unordered_multiset.h:864
ETL_OR_STD::pair< iterator, bool > insert(const_reference key)
Definition: unordered_multiset.h:662
local_const_iterator end(size_t i) const
Definition: unordered_multiset.h:581
key_equal key_eq() const
Definition: unordered_multiset.h:1179
local_iterator end(size_t i)
Definition: unordered_multiset.h:572
size_type max_bucket_count() const
Definition: unordered_multiset.h:619
local_const_iterator cend(size_t i) const
Definition: unordered_multiset.h:590
size_type size() const
Gets the size of the unordered_multiset.
Definition: unordered_multiset.h:1111
hasher hash_function() const
Definition: unordered_multiset.h:1170
size_type bucket_count() const
Definition: unordered_multiset.h:628
size_type capacity() const
Gets the maximum possible size of the unordered_multiset.
Definition: unordered_multiset.h:1127
size_t count(key_parameter_t key) const
Definition: unordered_multiset.h:967
bool full() const
Checks to see if the unordered_multiset is full.
Definition: unordered_multiset.h:1143
ETL_OR_STD::pair< iterator, iterator > equal_range(key_parameter_t key)
Definition: unordered_multiset.h:1064
float load_factor() const
Definition: unordered_multiset.h:1161
bool empty() const
Checks to see if the unordered_multiset is empty.
Definition: unordered_multiset.h:1135
Definition: unordered_multiset.h:132
Definition: unordered_multiset.h:75
Definition: unordered_multiset.h:89
Definition: unordered_multiset.h:116
Definition: unordered_multiset.h:103
bool operator==(const etl::iunordered_multiset< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_multiset< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_multiset.h:1406
bool operator!=(const etl::iunordered_multiset< TKey, TMapped, TKeyCompare > &lhs, const etl::iunordered_multiset< TKey, TMapped, TKeyCompare > &rhs)
Definition: unordered_multiset.h:1419
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_multiset.h:154