mirror of
https://github.com/boostorg/container.git
synced 2026-01-19 04:02:17 +00:00
Add C++23 transparent extract() method to set/multiset/map/multimap
This commit is contained in:
@@ -1190,6 +1190,21 @@ class tree
|
||||
return node_type();
|
||||
}
|
||||
|
||||
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
|
||||
, node_type>::type
|
||||
extract(BOOST_FWD_REF(K) k)
|
||||
{
|
||||
iterator const it = this->find(k);
|
||||
if(this->end() != it){
|
||||
return this->extract(it);
|
||||
}
|
||||
return node_type();
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||
|
||||
@@ -1069,6 +1069,29 @@ class map
|
||||
return BOOST_MOVE_RET(node_type, nh);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: This overload is available only if
|
||||
//! key_compare::is_transparent exists.
|
||||
//!
|
||||
//! <b>Effects</b>: Removes the first element in the container with key equivalent to k.
|
||||
//!
|
||||
//! <b>Returns</b>: A node_type owning the element if found, otherwise an empty node_type.
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size()).
|
||||
template<class K>
|
||||
inline BOOST_CONTAINER_DOC1ST
|
||||
(node_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 node_type>::type)
|
||||
extract(BOOST_FWD_REF(K) k)
|
||||
{
|
||||
typename base_t::node_type base_nh(this->base_t::extract(k));
|
||||
node_type nh(boost::move(base_nh));
|
||||
return BOOST_MOVE_RET(node_type, nh);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Removes the element pointed to by "position".
|
||||
//!
|
||||
//! <b>Returns</b>: A node_type owning the element, otherwise an empty node_type.
|
||||
@@ -2043,6 +2066,22 @@ class multimap
|
||||
return node_type(boost::move(base_nh));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::map::extract(K&&)
|
||||
template<class K>
|
||||
inline BOOST_CONTAINER_DOC1ST
|
||||
(node_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 node_type>::type)
|
||||
extract(BOOST_FWD_REF(K) k)
|
||||
{
|
||||
typename base_t::node_type base_nh(this->base_t::extract(k));
|
||||
node_type nh(boost::move(base_nh));
|
||||
return BOOST_MOVE_RET(node_type, nh);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::map::extract(const_iterator)
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
|
||||
@@ -722,6 +722,10 @@ class set
|
||||
//! @copydoc ::boost::container::map::extract(const key_type&)
|
||||
node_type extract(const key_type& x);
|
||||
|
||||
//! @copydoc ::boost::container::map::extract(K&&)
|
||||
template <class K>
|
||||
node_type extract(BOOST_FWD_REF(K) x);
|
||||
|
||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
@@ -1508,6 +1512,10 @@ class multiset
|
||||
//! @copydoc ::boost::container::multimap::extract(const key_type&)
|
||||
node_type extract(const key_type& x);
|
||||
|
||||
//! @copydoc ::boost::container::multimap::extract(K&&)
|
||||
template <class K>
|
||||
node_type extract(BOOST_FWD_REF(K) x);
|
||||
|
||||
//! @copydoc ::boost::container::set::swap
|
||||
void swap(multiset& x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
|
||||
@@ -371,6 +371,27 @@ bool test_heterogeneous_lookups()
|
||||
return false;
|
||||
if (mmap1.erase(find_me) != 0)
|
||||
return false;
|
||||
|
||||
//extract
|
||||
map1.clear();
|
||||
map1.insert(value_type(1, 'a'));
|
||||
mmap1.clear();
|
||||
mmap1.insert(value_type(1, 'a'));
|
||||
mmap1.insert(value_type(1, 'b'));
|
||||
|
||||
const test::non_copymovable_int extract_me(1);
|
||||
|
||||
if (!map1.extract(extract_me))
|
||||
return false;
|
||||
if (map1.extract(extract_me))
|
||||
return false;
|
||||
|
||||
if (!mmap1.extract(extract_me))
|
||||
return false;
|
||||
if (!mmap1.extract(extract_me))
|
||||
return false;
|
||||
if (mmap1.extract(extract_me))
|
||||
return false;
|
||||
}
|
||||
{
|
||||
typedef map<test::movable_int, char, less_transparent> map_t;
|
||||
|
||||
@@ -447,6 +447,27 @@ bool test_heterogeneous_lookups()
|
||||
if (mset1.erase(find_me) != 0)
|
||||
return false;
|
||||
|
||||
//extract
|
||||
set1.clear();
|
||||
set1.insert(1);
|
||||
mset1.clear();
|
||||
mset1.insert(1);
|
||||
mset1.insert(1);
|
||||
|
||||
const test::non_copymovable_int extract_me(1);
|
||||
|
||||
if (!set1.extract(extract_me))
|
||||
return false;
|
||||
if (set1.extract(extract_me))
|
||||
return false;
|
||||
|
||||
if (!mset1.extract(extract_me))
|
||||
return false;
|
||||
if (!mset1.extract(extract_me))
|
||||
return false;
|
||||
if (mset1.extract(extract_me))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user