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] [section:release_notes_boost_1_78_00 Boost 1.78 Release]
* Fixed bugs/issues: * 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"]]. * [@https://github.com/boostorg/container/issues/188 GitHub #188: ['"Build fails when RTTI is disabled"]].
[endsect] [endsect]

View File

@@ -1124,6 +1124,15 @@ class flat_tree
return ret; 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) BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
{ return this->m_data.m_seq.erase(first, 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) BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k)
{ return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); } { 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) iterator erase(const_iterator first, const_iterator last)
{ {
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first))); 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))); (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 //! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys. //! linear to the elements with bigger keys.
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) 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). //! <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) 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)); } { 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) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p. //! <b>Effects</b>: Erases the element pointed to by p.
@@ -781,14 +790,6 @@ class flat_set
//! not less than the erased element. //! not less than the erased element.
iterator erase(const_iterator p); 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>Effects</b>: Erases all the elements in the range [first, last).
//! //!
//! <b>Returns</b>: Returns last. //! <b>Returns</b>: Returns last.
@@ -909,6 +910,8 @@ class flat_set
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW; size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
#else
using tree_t::erase;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Returns</b>: The number of elements with key equivalent to x. //! <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) #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) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p. //! <b>Effects</b>: Erases the element pointed to by p.
@@ -975,13 +983,6 @@ class map
//! <b>Complexity</b>: Amortized constant time //! <b>Complexity</b>: Amortized constant time
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW; 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>Effects</b>: Erases all the elements in the range [first, last).
//! //!
//! <b>Returns</b>: Returns 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. //! <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; 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. //! <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) 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)); } { 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) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Erases the element pointed to by p. //! <b>Effects</b>: Erases the element pointed to by p.
@@ -691,13 +699,6 @@ class set
//! <b>Complexity</b>: Amortized constant time //! <b>Complexity</b>: Amortized constant time
iterator erase(const_iterator p); 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>Effects</b>: Erases all the elements in the range [first, last).
//! //!
//! <b>Returns</b>: Returns last. //! <b>Returns</b>: Returns last.
@@ -771,7 +772,9 @@ class set
template<typename K> template<typename K>
const_iterator find(const K& x) const; 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. //! <b>Returns</b>: The number of elements with key equivalent to x.
//! //!