Skip to content

Commit 21725fe

Browse files
committed
Add C++23 transparent extract() method to set/multiset/map/multimap
1 parent d179658 commit 21725fe

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed

include/boost/container/detail/tree.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,21 @@ class tree
11901190
return node_type();
11911191
}
11921192

1193+
template<class K>
1194+
inline typename dtl::enable_if_c<
1195+
dtl::is_transparent<key_compare>::value && //transparent
1196+
!dtl::is_convertible<K, iterator>::value && //not convertible to iterator
1197+
!dtl::is_convertible<K, const_iterator>::value //not convertible to const_iterator
1198+
, node_type>::type
1199+
extract(BOOST_FWD_REF(K) k)
1200+
{
1201+
iterator const it = this->find(k);
1202+
if(this->end() != it){
1203+
return this->extract(it);
1204+
}
1205+
return node_type();
1206+
}
1207+
11931208
node_type extract(const_iterator position)
11941209
{
11951210
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));

include/boost/container/map.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,29 @@ class map
10691069
return BOOST_MOVE_RET(node_type, nh);
10701070
}
10711071

1072+
//! <b>Requires</b>: This overload is available only if
1073+
//! key_compare::is_transparent exists.
1074+
//!
1075+
//! <b>Effects</b>: Removes the first element in the container with key equivalent to k.
1076+
//!
1077+
//! <b>Returns</b>: A node_type owning the element if found, otherwise an empty node_type.
1078+
//!
1079+
//! <b>Complexity</b>: log(size()).
1080+
template<class K>
1081+
inline BOOST_CONTAINER_DOC1ST
1082+
(node_type
1083+
, typename dtl::enable_if_c<
1084+
dtl::is_transparent<key_compare>::value && //transparent
1085+
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
1086+
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
1087+
BOOST_MOVE_I node_type>::type)
1088+
extract(BOOST_FWD_REF(K) k)
1089+
{
1090+
typename base_t::node_type base_nh(this->base_t::extract(k));
1091+
node_type nh(boost::move(base_nh));
1092+
return BOOST_MOVE_RET(node_type, nh);
1093+
}
1094+
10721095
//! <b>Effects</b>: Removes the element pointed to by "position".
10731096
//!
10741097
//! <b>Returns</b>: A node_type owning the element, otherwise an empty node_type.
@@ -2043,6 +2066,22 @@ class multimap
20432066
return node_type(boost::move(base_nh));
20442067
}
20452068

2069+
//! @copydoc ::boost::container::map::extract(K&&)
2070+
template<class K>
2071+
inline BOOST_CONTAINER_DOC1ST
2072+
(node_type
2073+
, typename dtl::enable_if_c<
2074+
dtl::is_transparent<key_compare>::value && //transparent
2075+
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
2076+
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
2077+
BOOST_MOVE_I node_type>::type)
2078+
extract(BOOST_FWD_REF(K) k)
2079+
{
2080+
typename base_t::node_type base_nh(this->base_t::extract(k));
2081+
node_type nh(boost::move(base_nh));
2082+
return BOOST_MOVE_RET(node_type, nh);
2083+
}
2084+
20462085
//! @copydoc ::boost::container::map::extract(const_iterator)
20472086
node_type extract(const_iterator position)
20482087
{

include/boost/container/set.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,10 @@ class set
722722
//! @copydoc ::boost::container::map::extract(const key_type&)
723723
node_type extract(const key_type& x);
724724

725+
//! @copydoc ::boost::container::map::extract(K&&)
726+
template <class K>
727+
node_type extract(BOOST_FWD_REF(K) x);
728+
725729
//! <b>Effects</b>: Swaps the contents of *this and x.
726730
//!
727731
//! <b>Throws</b>: Nothing.
@@ -1508,6 +1512,10 @@ class multiset
15081512
//! @copydoc ::boost::container::multimap::extract(const key_type&)
15091513
node_type extract(const key_type& x);
15101514

1515+
//! @copydoc ::boost::container::multimap::extract(K&&)
1516+
template <class K>
1517+
node_type extract(BOOST_FWD_REF(K) x);
1518+
15111519
//! @copydoc ::boost::container::set::swap
15121520
void swap(multiset& x)
15131521
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value

test/map_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,27 @@ bool test_heterogeneous_lookups()
371371
return false;
372372
if (mmap1.erase(find_me) != 0)
373373
return false;
374+
375+
//extract
376+
map1.clear();
377+
map1.insert(value_type(1, 'a'));
378+
mmap1.clear();
379+
mmap1.insert(value_type(1, 'a'));
380+
mmap1.insert(value_type(1, 'b'));
381+
382+
const test::non_copymovable_int extract_me(1);
383+
384+
if (!map1.extract(extract_me))
385+
return false;
386+
if (map1.extract(extract_me))
387+
return false;
388+
389+
if (!mmap1.extract(extract_me))
390+
return false;
391+
if (!mmap1.extract(extract_me))
392+
return false;
393+
if (mmap1.extract(extract_me))
394+
return false;
374395
}
375396
{
376397
typedef map<test::movable_int, char, less_transparent> map_t;

test/set_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,27 @@ bool test_heterogeneous_lookups()
447447
if (mset1.erase(find_me) != 0)
448448
return false;
449449

450+
//extract
451+
set1.clear();
452+
set1.insert(1);
453+
mset1.clear();
454+
mset1.insert(1);
455+
mset1.insert(1);
456+
457+
const test::non_copymovable_int extract_me(1);
458+
459+
if (!set1.extract(extract_me))
460+
return false;
461+
if (set1.extract(extract_me))
462+
return false;
463+
464+
if (!mset1.extract(extract_me))
465+
return false;
466+
if (!mset1.extract(extract_me))
467+
return false;
468+
if (mset1.extract(extract_me))
469+
return false;
470+
450471
return true;
451472
}
452473

0 commit comments

Comments
 (0)