Fixes #187 ("flat_map::erase and unique keys")

This commit is contained in:
Ion Gaztañaga
2021-08-08 00:38:29 +02:00
parent aaa2485ebf
commit 1cc35bbc98
7 changed files with 55 additions and 27 deletions

View File

@ -1341,6 +1341,7 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes_boost_1_78_00 Boost 1.78 Release]
* Fixed bugs/issues:
* [@https://github.com/boostorg/container/issues/187 GitHub #187: ['"flat_map::erase and unique keys"]].
* [@https://github.com/boostorg/container/issues/188 GitHub #188: ['"Build fails when RTTI is disabled"]].
[endsect]

View File

@ -1124,6 +1124,15 @@ class flat_tree
return ret;
}
size_type erase_unique(const key_type& k)
{
iterator i = this->find(k);
size_type ret = static_cast<size_type>(i != this->end());
if (ret)
this->erase(i);
return ret;
}
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
{ return this->m_data.m_seq.erase(first, last); }

View File

@ -1260,6 +1260,15 @@ class tree
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k)
{ return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); }
size_type erase_unique(const key_type& 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)));

View File

@ -1265,14 +1265,14 @@ class flat_map
(m_flat_tree.erase(dtl::force_copy<impl_const_iterator>(p)));
}
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//! <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.
//! <b>Returns</b>: Returns the number of erased elements (0/1).
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return m_flat_tree.erase(x); }
{ return m_flat_tree.erase_unique(x); }
//! <b>Effects</b>: Erases all the elements in the range [first, last).
//!

View File

@ -767,6 +767,15 @@ class flat_set
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
{ return this->merge(static_cast<flat_multiset<Key, C2, AllocatorOrContainer>&>(source)); }
//! <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).
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return this->tree_t::erase_unique(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p.
@ -781,14 +790,6 @@ class flat_set
//! not less than the erased element.
iterator erase(const_iterator p);
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
size_type erase(const key_type& x);
//! <b>Effects</b>: Erases all the elements in the range [first, last).
//!
//! <b>Returns</b>: Returns last.
@ -909,6 +910,8 @@ class flat_set
//! <b>Note</b>: Non-standard extension
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
#else
using tree_t::erase;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Returns</b>: The number of elements with key equivalent to x.

View File

@ -964,6 +964,14 @@ class map
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <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).
//!
//! <b>Complexity</b>: log(size()) + count(k)
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return this->base_t::erase_unique(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p.
@ -975,13 +983,6 @@ class map
//! <b>Complexity</b>: Amortized constant time
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: log(size()) + count(k)
size_type erase(const key_type& x) BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Erases all the elements in the range [first, last).
//!
//! <b>Returns</b>: Returns last.
@ -989,7 +990,9 @@ class map
//! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW;
#endif
#else
using base_t::erase;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Removes the first element in the container with key equivalent to k.
//!

View File

@ -680,6 +680,14 @@ class set
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
{ return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
//! <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).
//!
//! <b>Complexity</b>: log(size()) + count(k)
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return this->base_t::erase_unique(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p.
@ -691,13 +699,6 @@ class set
//! <b>Complexity</b>: Amortized constant time
iterator erase(const_iterator p);
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: log(size()) + count(k)
size_type erase(const key_type& x);
//! <b>Effects</b>: Erases all the elements in the range [first, last).
//!
//! <b>Returns</b>: Returns last.
@ -771,7 +772,9 @@ class set
template<typename K>
const_iterator find(const K& x) const;
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#else
using base_t::erase;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!