mirror of
https://github.com/boostorg/container.git
synced 2025-07-31 13:07:17 +02:00
Fixes #241: flat_map should support same interface as std::map
This commit is contained in:
@ -1421,6 +1421,7 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
* [@https://github.com/boostorg/container/issues/266 GitHub #266: ['"small_vector<T> is misaligned on the stack in 32 bits"]].
|
||||
* [@https://github.com/boostorg/container/issues/259 GitHub #259: ['"Global variables"]].
|
||||
* [@https://github.com/boostorg/container/issues/245 GitHub #245: ['"flat_tree::insert ordered range doesn't assert sorting"]].
|
||||
* [@https://github.com/boostorg/container/issues/241 GitHub #241: ['"flat_map should support same interface as std::map"]].
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -1127,9 +1127,6 @@ class flat_tree
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_seq.erase(position); }
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
std::pair<iterator,iterator > itp = this->equal_range(k);
|
||||
@ -1149,6 +1146,40 @@ class flat_tree
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
inline typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K, iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K, const_iterator>::value //not convertible to const_iterator
|
||||
, size_type>::type
|
||||
erase(const K& k)
|
||||
{
|
||||
std::pair<iterator, iterator > itp = this->equal_range(k);
|
||||
size_type ret = static_cast<size_type>(itp.second - itp.first);
|
||||
if (ret) {
|
||||
this->m_data.m_seq.erase(itp.first, itp.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
inline typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K, iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K, const_iterator>::value //not convertible to const_iterator
|
||||
, size_type>::type
|
||||
erase_unique(const K& k)
|
||||
{
|
||||
const_iterator i = static_cast<const flat_tree&>(*this).find(k);
|
||||
size_type ret = static_cast<size_type>(i != this->cend());
|
||||
if (ret)
|
||||
this->erase(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_seq.erase(position); }
|
||||
|
||||
inline iterator erase(const_iterator first, const_iterator last)
|
||||
{ return this->m_data.m_seq.erase(first, last); }
|
||||
|
||||
|
@ -536,6 +536,19 @@ struct node_alloc_holder
|
||||
return this->icont().erase_and_dispose(k, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
template<class Key, class KeyCompare>
|
||||
inline size_type erase_key(const Key& k, KeyCompare cmp, version_1)
|
||||
{
|
||||
return this->icont().erase_and_dispose(k, cmp, Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
template<class Key, class KeyCompare>
|
||||
inline size_type erase_key(const Key& k, KeyCompare cmp, version_2)
|
||||
{
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
||||
return this->icont().erase_and_dispose(k, cmp, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
protected:
|
||||
struct cloner
|
||||
{
|
||||
|
@ -1142,6 +1142,31 @@ class tree
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
inline typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K, iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K, const_iterator>::value //not convertible to const_iterator
|
||||
, size_type>::type
|
||||
erase(const K& k)
|
||||
{ return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); }
|
||||
|
||||
template <class K>
|
||||
inline typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K, iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K, const_iterator>::value //not convertible to const_iterator
|
||||
, size_type>::type
|
||||
erase_unique(const K& k)
|
||||
{
|
||||
iterator i = this->find(k);
|
||||
size_type ret = static_cast<size_type>(i != this->end());
|
||||
|
||||
if (ret)
|
||||
this->erase(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
|
||||
|
@ -1315,6 +1315,23 @@ class flat_map
|
||||
inline size_type erase(const key_type& x)
|
||||
{ return m_flat_tree.erase_unique(x); }
|
||||
|
||||
//! <b>Requires</b>: This overload is available only if
|
||||
//! key_compare::is_transparent exists.
|
||||
//!
|
||||
//! <b>Effects</b>: If present, erases the element in the container with key equivalent to x.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns the number of erased elements (0/1).
|
||||
template <class K>
|
||||
inline BOOST_CONTAINER_DOC1ST
|
||||
(size_type
|
||||
, typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||
BOOST_MOVE_I size_type>::type)
|
||||
erase(const K& x)
|
||||
{ return m_flat_tree.erase_unique(x); }
|
||||
|
||||
//! <b>Effects</b>: Erases all the elements in the range [first, last).
|
||||
//!
|
||||
//! <b>Returns</b>: Returns last.
|
||||
@ -2678,6 +2695,23 @@ class flat_multimap
|
||||
inline size_type erase(const key_type& x)
|
||||
{ return m_flat_tree.erase(x); }
|
||||
|
||||
//! <b>Requires</b>: This overload is available only if
|
||||
//! key_compare::is_transparent exists.
|
||||
//!
|
||||
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns the number of erased elements.
|
||||
template <class K>
|
||||
inline BOOST_CONTAINER_DOC1ST
|
||||
(size_type
|
||||
, typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||
BOOST_MOVE_I size_type>::type)
|
||||
erase(const K& x)
|
||||
{ return m_flat_tree.erase(x); }
|
||||
|
||||
//! <b>Effects</b>: Erases all the elements in the range [first, last).
|
||||
//!
|
||||
//! <b>Returns</b>: Returns last.
|
||||
|
@ -969,6 +969,23 @@ class map
|
||||
inline size_type erase(const key_type& x)
|
||||
{ return this->base_t::erase_unique(x); }
|
||||
|
||||
//! <b>Requires</b>: This overload is available only if
|
||||
//! key_compare::is_transparent exists.
|
||||
//!
|
||||
//! <b>Effects</b>: If present, erases the element in the container with key equivalent to x.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns the number of erased elements (0/1).
|
||||
template <class K>
|
||||
inline BOOST_CONTAINER_DOC1ST
|
||||
(size_type
|
||||
, typename dtl::enable_if_c<
|
||||
dtl::is_transparent<key_compare>::value && //transparent
|
||||
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||
BOOST_MOVE_I size_type>::type)
|
||||
erase(const K& x)
|
||||
{ return this->base_t::erase_unique(x); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
|
@ -560,6 +560,15 @@ bool test_heterogeneous_lookups()
|
||||
if(cmmap1.equal_range(find_me).second->second != 'e')
|
||||
return false;
|
||||
|
||||
//erase
|
||||
if (map1.erase(find_me) != 1)
|
||||
return false;
|
||||
if (map1.erase(find_me) != 0)
|
||||
return false;
|
||||
if (mmap1.erase(find_me) != 2)
|
||||
return false;
|
||||
if (mmap1.erase(find_me) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -361,6 +361,15 @@ bool test_heterogeneous_lookups()
|
||||
if(cmmap1.equal_range(find_me).second->second != 'e')
|
||||
return false;
|
||||
|
||||
//erase
|
||||
if (map1.erase(find_me) != 1)
|
||||
return false;
|
||||
if (map1.erase(find_me) != 0)
|
||||
return false;
|
||||
if (mmap1.erase(find_me) != 2)
|
||||
return false;
|
||||
if (mmap1.erase(find_me) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user