Skip to content

Commit

Permalink
ADL-proof implementation of erase_if and related algorithms (#4217)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Nov 29, 2023
1 parent c9d52cd commit 21b16b4
Show file tree
Hide file tree
Showing 21 changed files with 76 additions and 46 deletions.
4 changes: 2 additions & 2 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1768,12 +1768,12 @@ _NODISCARD bool operator>=(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Al
#if _HAS_CXX20
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty>
deque<_Ty, _Alloc>::size_type erase(deque<_Ty, _Alloc>& _Cont, const _Uty& _Val) {
return _Erase_remove(_Cont, _Val);
return _STD _Erase_remove(_Cont, _Val);
}

_EXPORT_STD template <class _Ty, class _Alloc, class _Pr>
deque<_Ty, _Alloc>::size_type erase_if(deque<_Ty, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_remove_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/deque
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace experimental {

template <class _Ty, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(deque<_Ty, _Alloc>& _Cont, _Pr _Pred) {
_Erase_remove_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Ty, class _Alloc, class _Uty>
_DEPRECATE_EXPERIMENTAL_ERASE void erase(deque<_Ty, _Alloc>& _Cont, const _Uty& _Val) {
_Erase_remove(_Cont, _Val);
_STD _Erase_remove(_Cont, _Val);
}

} // namespace fundamentals_v2
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/experimental/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace experimental {

template <class _Ty, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(forward_list<_Ty, _Alloc>& _Cont, _Pr _Pred) {
_Cont.remove_if(_Pass_fn(_Pred));
_Cont.remove_if(_STD _Pass_fn(_Pred));
}

template <class _Ty, class _Alloc, class _Uty>
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/experimental/list
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace experimental {

template <class _Ty, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(list<_Ty, _Alloc>& _Cont, _Pr _Pred) {
_Cont.remove_if(_Pass_fn(_Pred));
_Cont.remove_if(_STD _Pass_fn(_Pred));
}

template <class _Ty, class _Alloc, class _Uty>
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/map
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace experimental {

template <class _Kty, class _Ty, class _Keylt, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(map<_Kty, _Ty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Kty, class _Ty, class _Keylt, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(multimap<_Kty, _Ty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

} // namespace fundamentals_v2
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/set
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace experimental {

template <class _Kty, class _Keylt, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(set<_Kty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Kty, class _Keylt, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(multiset<_Kty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

} // namespace fundamentals_v2
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/string
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace experimental {

template <class _Elem, class _Traits, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(basic_string<_Elem, _Traits, _Alloc>& _Cont, _Pr _Pred) {
_Erase_remove_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Elem, class _Traits, class _Alloc, class _Uty>
_DEPRECATE_EXPERIMENTAL_ERASE void erase(basic_string<_Elem, _Traits, _Alloc>& _Cont, const _Uty& _Val) {
_Erase_remove(_Cont, _Val);
_STD _Erase_remove(_Cont, _Val);
}

} // namespace fundamentals_v2
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ namespace experimental {
template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(
unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(
unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

} // namespace fundamentals_v2
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/unordered_set
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ namespace experimental {

template <class _Kty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Kty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(
unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
_Erase_nodes_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}

} // namespace fundamentals_v2
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/experimental/vector
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace experimental {

template <class _Ty, class _Alloc, class _Pr>
_DEPRECATE_EXPERIMENTAL_ERASE void erase_if(vector<_Ty, _Alloc>& _Cont, _Pr _Pred) {
_Erase_remove_if(_Cont, _Pass_fn(_Pred));
_STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}

template <class _Ty, class _Alloc, class _Uty>
_DEPRECATE_EXPERIMENTAL_ERASE void erase(vector<_Ty, _Alloc>& _Cont, const _Uty& _Val) {
_Erase_remove(_Cont, _Val);
_STD _Erase_remove(_Cont, _Val);
}

} // namespace fundamentals_v2
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ forward_list<_Ty, _Alloc>::size_type erase(forward_list<_Ty, _Alloc>& _Cont, con

_EXPORT_STD template <class _Ty, class _Alloc, class _Pr>
forward_list<_Ty, _Alloc>::size_type erase_if(forward_list<_Ty, _Alloc>& _Cont, _Pr _Pred) {
return _Cont.remove_if(_Pass_fn(_Pred));
return _Cont.remove_if(_STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
8 changes: 4 additions & 4 deletions stl/inc/list
Original file line number Diff line number Diff line change
Expand Up @@ -1722,12 +1722,12 @@ public:

template <class _Pr2>
void merge(list& _Right, _Pr2 _Pred) { // merge in elements from _Right, both ordered by _Pred
_Merge1(_Right, _Pass_fn(_Pred));
_Merge1(_Right, _STD _Pass_fn(_Pred));
}

template <class _Pr2>
void merge(list&& _Right, _Pr2 _Pred) { // merge in elements from _Right, both ordered by _Pred
_Merge1(_Right, _Pass_fn(_Pred));
_Merge1(_Right, _STD _Pass_fn(_Pred));
}

private:
Expand Down Expand Up @@ -1773,7 +1773,7 @@ public:
template <class _Pr2>
void sort(_Pr2 _Pred) { // order sequence
auto& _My_data = _Mypair._Myval2;
_Scary_val::_Sort(_My_data._Myhead->_Next, _My_data._Mysize, _Pass_fn(_Pred));
_Scary_val::_Sort(_My_data._Myhead->_Next, _My_data._Mysize, _STD _Pass_fn(_Pred));
}

void reverse() noexcept { // reverse sequence
Expand Down Expand Up @@ -1921,7 +1921,7 @@ list<_Ty, _Alloc>::size_type erase(list<_Ty, _Alloc>& _Cont, const _Uty& _Val) {

_EXPORT_STD template <class _Ty, class _Alloc, class _Pr>
list<_Ty, _Alloc>::size_type erase_if(list<_Ty, _Alloc>& _Cont, _Pr _Pred) {
return _Cont.remove_if(_Pass_fn(_Pred));
return _Cont.remove_if(_STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/map
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ void swap(map<_Kty, _Ty, _Pr, _Alloc>& _Left, map<_Kty, _Ty, _Pr, _Alloc>& _Righ
#if _HAS_CXX20
_EXPORT_STD template <class _Kty, class _Ty, class _Keylt, class _Alloc, class _Pr>
map<_Kty, _Ty, _Keylt, _Alloc>::size_type erase_if(map<_Kty, _Ty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down Expand Up @@ -687,7 +687,7 @@ void swap(multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, multimap<_Kty, _Ty, _Pr, _All
#if _HAS_CXX20
_EXPORT_STD template <class _Kty, class _Ty, class _Keylt, class _Alloc, class _Pr>
multimap<_Kty, _Ty, _Keylt, _Alloc>::size_type erase_if(multimap<_Kty, _Ty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/set
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ void swap(set<_Kty, _Pr, _Alloc>& _Left, set<_Kty, _Pr, _Alloc>& _Right) noexcep
#if _HAS_CXX20
_EXPORT_STD template <class _Kty, class _Keylt, class _Alloc, class _Pr>
set<_Kty, _Keylt, _Alloc>::size_type erase_if(set<_Kty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down Expand Up @@ -474,7 +474,7 @@ void swap(multiset<_Kty, _Pr, _Alloc>& _Left, multiset<_Kty, _Pr, _Alloc>& _Righ
#if _HAS_CXX20
_EXPORT_STD template <class _Kty, class _Keylt, class _Alloc, class _Pr>
multiset<_Kty, _Keylt, _Alloc>::size_type erase_if(multiset<_Kty, _Keylt, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ void swap(unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Left,
_EXPORT_STD template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>::size_type erase_if(
unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down Expand Up @@ -903,7 +903,7 @@ void swap(unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Left,
_EXPORT_STD template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>::size_type erase_if(
unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/unordered_set
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void swap(unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
_EXPORT_STD template <class _Kty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>::size_type erase_if(
unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down Expand Up @@ -730,7 +730,7 @@ void swap(unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
_EXPORT_STD template <class _Kty, class _Hasher, class _Keyeq, class _Alloc, class _Pr>
unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>::size_type erase_if(
unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_nodes_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_nodes_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -2369,12 +2369,12 @@ _CONSTEXPR20 void swap(vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right)
#if _HAS_CXX20
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty>
constexpr vector<_Ty, _Alloc>::size_type erase(vector<_Ty, _Alloc>& _Cont, const _Uty& _Val) {
return _Erase_remove(_Cont, _Val);
return _STD _Erase_remove(_Cont, _Val);
}

_EXPORT_STD template <class _Ty, class _Alloc, class _Pr>
constexpr vector<_Ty, _Alloc>::size_type erase_if(vector<_Ty, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_remove_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
22 changes: 11 additions & 11 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2215,9 +2215,9 @@ _NODISCARD_RAW_PTR_ALLOC _CONSTEXPR20 typename allocator_traits<_Alloc>::pointer
_EXPORT_STD template <class _FwdIt, class _Ty>
_NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
// remove each matching _Val
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
_UFirst = _STD _Find_unchecked(_UFirst, _ULast, _Val);
auto _UNext = _UFirst;
if (_UFirst != _ULast) {
Expand All @@ -2229,17 +2229,17 @@ _NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove(_FwdIt _First, const _FwdIt _La
}
}

_Seek_wrapped(_First, _UNext);
_STD _Seek_wrapped(_First, _UNext);
return _First;
}

_EXPORT_STD template <class _FwdIt, class _Pr>
_NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove_if(_FwdIt _First, const _FwdIt _Last, _Pr _Pred) {
// remove each satisfying _Pred
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_UFirst = _STD find_if(_UFirst, _ULast, _Pass_fn(_Pred));
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
_UFirst = _STD find_if(_UFirst, _ULast, _STD _Pass_fn(_Pred));
auto _UNext = _UFirst;
if (_UFirst != _ULast) {
while (++_UFirst != _ULast) {
Expand All @@ -2250,7 +2250,7 @@ _NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove_if(_FwdIt _First, const _FwdIt
}
}

_Seek_wrapped(_First, _UNext);
_STD _Seek_wrapped(_First, _UNext);
return _First;
}

Expand All @@ -2260,7 +2260,7 @@ _CONSTEXPR20 typename _Container::size_type _Erase_remove(_Container& _Cont, con
auto _First = _Cont.begin();
const auto _Last = _Cont.end();
const auto _Old_size = _Cont.size();
_Seek_wrapped(_First, _STD remove(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Val));
_STD _Seek_wrapped(_First, _STD remove(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _Val));
_Cont.erase(_First, _Last);
return _Old_size - _Cont.size();
}
Expand All @@ -2271,7 +2271,7 @@ _CONSTEXPR20 typename _Container::size_type _Erase_remove_if(_Container& _Cont,
auto _First = _Cont.begin();
const auto _Last = _Cont.end();
const auto _Old_size = _Cont.size();
_Seek_wrapped(_First, _STD remove_if(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pred));
_STD _Seek_wrapped(_First, _STD remove_if(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _Pred));
_Cont.erase(_First, _Last);
return _Old_size - _Cont.size();
}
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/xstring
Original file line number Diff line number Diff line change
Expand Up @@ -5260,13 +5260,13 @@ inline namespace literals {
_EXPORT_STD template <class _Elem, class _Traits, class _Alloc, class _Uty>
constexpr basic_string<_Elem, _Traits, _Alloc>::size_type erase(
basic_string<_Elem, _Traits, _Alloc>& _Cont, const _Uty& _Val) {
return _Erase_remove(_Cont, _Val);
return _STD _Erase_remove(_Cont, _Val);
}

_EXPORT_STD template <class _Elem, class _Traits, class _Alloc, class _Pr>
constexpr basic_string<_Elem, _Traits, _Alloc>::size_type erase_if(
basic_string<_Elem, _Traits, _Alloc>& _Cont, _Pr _Pred) {
return _Erase_remove_if(_Cont, _Pass_fn(_Pred));
return _STD _Erase_remove_if(_Cont, _STD _Pass_fn(_Pred));
}
#endif // _HAS_CXX20

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ void test_algorithms() {

(void) std::search(varr, varr, varr, varr);
(void) std::search(iarr, iarr, iarr, iarr, validating_equal{});

(void) std::remove(varr, varr, validator{});

(void) std::remove_if(varr, varr, simple_truth{});
(void) std::remove_if(iarr, iarr, validating_truth{});
}

#if _HAS_CXX17
Expand Down
Loading

0 comments on commit 21b16b4

Please sign in to comment.