Skip to content

[libc++] Add missed constexpr to erase(_if) in <string> #129666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,10 @@ 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>
typename basic_string<charT, traits, Allocator>::size_type
constexpr 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>
typename basic_string<charT, traits, Allocator>::size_type
constexpr 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;
Expand Down Expand Up @@ -4022,15 +4022,15 @@ getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Al

# if _LIBCPP_STD_VER >= 20
template <class _CharT, class _Traits, class _Allocator, class _Up>
inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type
inline _LIBCPP_HIDE_FROM_ABI constexpr 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(std::remove(__str.begin(), __str.end(), __v), __str.end());
return __old_size - __str.size();
}

template <class _CharT, class _Traits, class _Allocator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type
inline _LIBCPP_HIDE_FROM_ABI constexpr 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(std::remove_if(__str.begin(), __str.end(), __pred), __str.end());
Expand Down
15 changes: 11 additions & 4 deletions libcxx/test/std/strings/strings.erasure/erase.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// <string>

// template <class charT, class traits, class Allocator, class U>
// typename basic_string<charT, traits, Allocator>::size_type
// constexpr typename basic_string<charT, traits, Allocator>::size_type
// erase(basic_string<charT, traits, Allocator>& c, const U& value);

#include <string>
Expand All @@ -22,15 +22,15 @@
#include "min_allocator.h"

template <class S, class U>
void test0(S s, U val, S expected, std::size_t expected_erased_count) {
constexpr void test0(S s, U val, S expected, std::size_t expected_erased_count) {
ASSERT_SAME_TYPE(typename S::size_type, decltype(std::erase(s, val)));
assert(expected_erased_count == std::erase(s, val));
LIBCPP_ASSERT(s.__invariants());
assert(s == expected);
}

template <class S>
void test() {
constexpr void test() {
test0(S(""), 'a', S(""), 0);

test0(S("a"), 'a', S(""), 1);
Expand Down Expand Up @@ -64,10 +64,17 @@ void test() {
test0(S("aba"), opt('c'), S("aba"), 0);
}

int main(int, char**) {
constexpr bool test() {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}
15 changes: 11 additions & 4 deletions libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// <string>

// template <class charT, class traits, class Allocator, class Predicate>
// typename basic_string<charT, traits, Allocator>::size_type
// constexpr typename basic_string<charT, traits, Allocator>::size_type
// erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);

#include <string>
Expand All @@ -21,15 +21,15 @@
#include "min_allocator.h"

template <class S, class Pred>
void test0(S s, Pred p, S expected, std::size_t expected_erased_count) {
constexpr void test0(S s, Pred p, S expected, std::size_t expected_erased_count) {
ASSERT_SAME_TYPE(typename S::size_type, decltype(std::erase_if(s, p)));
assert(expected_erased_count == std::erase_if(s, p));
LIBCPP_ASSERT(s.__invariants());
assert(s == expected);
}

template <typename S>
void test() {
constexpr void test() {
auto isA = [](auto ch) { return ch == 'a'; };
auto isB = [](auto ch) { return ch == 'b'; };
auto isC = [](auto ch) { return ch == 'c'; };
Expand Down Expand Up @@ -66,10 +66,17 @@ void test() {
test0(S("aba"), True, S(""), 3);
}

int main(int, char**) {
constexpr bool test() {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}