Skip to content

Commit

Permalink
[libc++][P1115][C++20] Improving the Return Value of Erase-Like Algor…
Browse files Browse the repository at this point in the history
…ithms II: Free erase/erase if.

Summary:
This patch adds return type to std::erase and std::erase_if functions.

Also:
* Update __cpp_lib_erase_if to 202002L.
* Fix synopsis in unordered_map.
* Fix generate_feature_test_macro_components.py script.

Reviewers: EricWF, mclow.lists, ldionne, #libc

Reviewed By: ldionne, #libc

Subscribers: broadwaylamb, zoecarver, dexonsmith, ldionne, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D75905
  • Loading branch information
mkurdej committed May 2, 2020
1 parent 8148b11 commit 3e89508
Show file tree
Hide file tree
Showing 42 changed files with 722 additions and 672 deletions.
2 changes: 1 addition & 1 deletion libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_endian`` ``201907L``
------------------------------------------------- -----------------
``__cpp_lib_erase_if`` ``201811L``
``__cpp_lib_erase_if`` ``202002L``
------------------------------------------------- -----------------
``__cpp_lib_generic_unordered_lookup`` *unimplemented*
------------------------------------------------- -----------------
Expand Down
24 changes: 16 additions & 8 deletions libcxx/include/deque
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,11 @@ template <class T, class Allocator>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(deque<T, Allocator>& c, const U& value); // C++20
typename deque<T, Allocator>::size_type
erase(deque<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
typename deque<T, Allocator>::size_type
erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
} // std
Expand Down Expand Up @@ -3021,14 +3023,20 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)

#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
return __old_size - __c.size();
}

template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
return __old_size - __c.size();
}
#endif


Expand Down
18 changes: 12 additions & 6 deletions libcxx/include/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ template <class T, class Allocator>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(forward_list<T, Allocator>& c, const U& value); // C++20
typename forward_list<T, Allocator>::size_type
erase(forward_list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
typename forward_list<T, Allocator>::size_type
erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
} // std
Expand Down Expand Up @@ -1765,13 +1767,17 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
typename forward_list<_Tp, _Allocator>::size_type
erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}

template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
typename forward_list<_Tp, _Allocator>::size_type
erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
}
#endif

_LIBCPP_END_NAMESPACE_STD
Expand Down
22 changes: 13 additions & 9 deletions libcxx/include/functional
Original file line number Diff line number Diff line change
Expand Up @@ -3163,15 +3163,19 @@ using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
#endif // > C++17

template <class _Container, class _Predicate>
inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred)
{
for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;)
{
if (__pred(*__iter))
__iter = __c.erase(__iter);
else
++__iter;
}
inline typename _Container::size_type
__libcpp_erase_if_container(_Container& __c, _Predicate __pred) {
typename _Container::size_type __old_size = __c.size();

const typename _Container::iterator __last = __c.end();
for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
if (__pred(*__iter))
__iter = __c.erase(__iter);
else
++__iter;
}

return __old_size - __c.size();
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
20 changes: 12 additions & 8 deletions libcxx/include/list
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,11 @@ template <class T, class Alloc>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(list<T, Allocator>& c, const U& value); // C++20
typename list<T, Allocator>::size_type
erase(list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(list<T, Allocator>& c, Predicate pred); // C++20
typename list<T, Allocator>::size_type
erase_if(list<T, Allocator>& c, Predicate pred); // C++20
} // std
Expand Down Expand Up @@ -2471,14 +2473,16 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)

#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}

template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
erase(list<_Tp, _Allocator>& __c, const _Up& __v) {
return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
}
#endif

_LIBCPP_END_NAMESPACE_STD
Expand Down
25 changes: 17 additions & 8 deletions libcxx/include/map
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
typename map<Key, T, Compare, Allocator>::size_type
erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class T, class Compare = less<Key>,
Expand Down Expand Up @@ -469,7 +470,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
typename multimap<Key, T, Compare, Allocator>::size_type
erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
} // std
Expand Down Expand Up @@ -1653,10 +1655,13 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
template <class _Key, class _Tp, class _Compare, class _Allocator,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename map<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif


Expand Down Expand Up @@ -2235,10 +2240,14 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
template <class _Key, class _Tp, class _Compare, class _Allocator,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif

_LIBCPP_END_NAMESPACE_STD
Expand Down
18 changes: 12 additions & 6 deletions libcxx/include/set
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
typename set<Key, Compare, Allocator>::size_type
erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key>>
Expand Down Expand Up @@ -417,7 +418,8 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
typename multiset<Key, Compare, Allocator>::size_type
erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
} // std
Expand Down Expand Up @@ -960,8 +962,10 @@ swap(set<_Key, _Compare, _Allocator>& __x,
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename set<_Key, _Compare, _Allocator>::size_type
erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif

template <class _Key, class _Compare = less<_Key>,
Expand Down Expand Up @@ -1484,8 +1488,10 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename multiset<_Key, _Compare, _Allocator>::size_type
erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif

_LIBCPP_END_NAMESPACE_STD
Expand Down
28 changes: 20 additions & 8 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,11 @@ basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator, class U>
void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
typename basic_string<charT, traits, Allocator>::size_type
erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
template<class charT, class traits, class Allocator, class Predicate>
void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
typename basic_string<charT, traits, Allocator>::size_type
erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
Expand Down Expand Up @@ -4379,15 +4381,25 @@ getline(basic_istream<_CharT, _Traits>&& __is,
#endif // _LIBCPP_CXX03_LANG

#if _LIBCPP_STD_VER > 17
template<class _CharT, class _Traits, class _Allocator, class _Up>
template <class _CharT, class _Traits, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v)
{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); }
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
auto __old_size = __str.size();
__str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end());
return __old_size - __str.size();
}

template<class _CharT, class _Traits, class _Allocator, class _Predicate>
template <class _CharT, class _Traits, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred)
{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); }
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
_Predicate __pred) {
auto __old_size = __str.size();
__str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred),
__str.end());
return __old_size - __str.size();
}
#endif

#if _LIBCPP_DEBUG_LEVEL >= 2
Expand Down
26 changes: 18 additions & 8 deletions libcxx/include/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -386,10 +386,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
noexcept(noexcept(x.swap(y)));
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_map<K, T, H, P, A>::size_type
erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred); // C++20
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_multimap<K, T, H, P, A>::size_type
erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred); // C++20
template <class Key, class T, class Hash, class Pred, class Alloc>
bool
Expand Down Expand Up @@ -1704,10 +1706,14 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Expand Down Expand Up @@ -2402,10 +2408,14 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Expand Down
Loading

0 comments on commit 3e89508

Please sign in to comment.