Add contains member function to basic_string_view and basic_string. The new method is enabled for -std=gnu++20, gnu++2b and c++2b. This allows users to access the method as a GNU extension to C++20. The conditional test may be reduced to "__cplusplus > 202011L" once GCC has a c++2b switch.
libstdc++-v3/ Add contains member function to basic_string_view. Likewise to basic_string_view, both with and without _GLIBCXX_USE_CXX11_ABI. Enabled with -std=gnu++20, gnu++2b and c++2b. * include/bits/basic_string.h (basic_string::contains): New. * libstdc++-v3/include/std/string_view (basic_string_view::contains): New. * testsuite/21_strings/basic_string/operations/contains/char/1.cc: New test. * testsuite/21_strings/basic_string/operations/contains/wchar_t/1.cc: New test. * testsuite/21_strings/basic_string/operations/starts_with/char/1.cc: Remove trailing whitespace * testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc: Remove trailing whitespace * testsuite/21_strings/basic_string_view/operations/contains/char/1.cc: New test. * testsuite/21_strings/basic_string_view/operations/contains/wchar_t/1.cc: New test. --- libstdc++-v3/include/bits/basic_string.h | 30 ++++ libstdc++-v3/include/std/string_view | 16 ++ libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/char/1.cc | 65 ++++++++++ libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/wchar_t/1.cc | 65 ++++++++++ libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char/1.cc | 2 libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc | 2 libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/char/1.cc | 51 +++++++ libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/wchar_t/1.cc | 51 +++++++ 8 files changed, 280 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index e272d332934..a569ecd8c08 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -3073,6 +3073,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return __sv_type(this->data(), this->size()).ends_with(__x); } #endif // C++20 +#if __cplusplus > 202011L || \ + (__cplusplus == 202002L && !defined __STRICT_ANSI__) + bool + contains(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } + + bool + contains(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } + + bool + contains(const _CharT* __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } +#endif // C++23 + // Allow basic_stringbuf::__xfer_bufptrs to call _M_length: template<typename, typename, typename> friend class basic_stringbuf; }; @@ -5998,6 +6013,21 @@ _GLIBCXX_END_NAMESPACE_CXX11 { return __sv_type(this->data(), this->size()).ends_with(__x); } #endif // C++20 +#if __cplusplus > 202011L || \ + (__cplusplus == 202002L && !defined __STRICT_ANSI__) + bool + contains(basic_string_view<_CharT, _Traits> __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } + + bool + contains(_CharT __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } + + bool + contains(const _CharT* __x) const noexcept + { return __sv_type(this->data(), this->size()).contains(__x); } +#endif // C++23 + # ifdef _GLIBCXX_TM_TS_INTERNAL friend void ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s, diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index e33e1bc4b79..2f47ef6ed12 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -352,6 +352,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->ends_with(basic_string_view(__x)); } #endif // C++20 +#if __cplusplus > 202011L || \ + (__cplusplus == 202002L && !defined __STRICT_ANSI__) +#define __cpp_lib_string_contains 202011L + constexpr bool + contains(basic_string_view __x) const noexcept + { return this->find(__x) != npos; } + + constexpr bool + contains(_CharT __x) const noexcept + { return this->find(__x) != npos; } + + constexpr bool + contains(const _CharT* __x) const noexcept + { return this->find(__x) != npos; } +#endif // C++23 + // [string.view.find], searching constexpr size_type diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/char/1.cc new file mode 100644 index 00000000000..5d81dcee0ad --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/char/1.cc @@ -0,0 +1,65 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do run { target c++2b } } + +// Copyright (C) 2018-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// basic_string contains + +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + const std::string haystack("no place for needles"); + + VERIFY(haystack.contains(std::string(""))); + VERIFY(haystack.contains(std::string("no"))); + VERIFY(haystack.contains(std::string("needles"))); + VERIFY(haystack.contains(std::string(" for "))); + VERIFY(!haystack.contains(std::string("places"))); + + VERIFY(haystack.contains(std::string_view(""))); + VERIFY(haystack.contains(std::string_view("no"))); + VERIFY(haystack.contains(std::string_view("needles"))); + VERIFY(haystack.contains(std::string_view(" for "))); + VERIFY(!haystack.contains(std::string_view("places"))); + + VERIFY(!haystack.contains('\0')); + VERIFY(haystack.contains('n')); + VERIFY(haystack.contains('e')); + VERIFY(haystack.contains('s')); + VERIFY(!haystack.contains('x')); + + VERIFY(haystack.contains("")); + VERIFY(haystack.contains("no")); + VERIFY(haystack.contains("needles")); + VERIFY(haystack.contains(" for ")); + VERIFY(!haystack.contains("places")); + + const std::string nothing; + VERIFY(nothing.contains("")); + VERIFY(!nothing.contains('\0')); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/wchar_t/1.cc new file mode 100644 index 00000000000..21196add4dc --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/wchar_t/1.cc @@ -0,0 +1,65 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do run { target c++2b } } + +// Copyright (C) 2018-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// basic_string begins_with + +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + const std::wstring haystack(L"no place for needles"); + + VERIFY(haystack.contains(std::wstring(L""))); + VERIFY(haystack.contains(std::wstring(L"no"))); + VERIFY(haystack.contains(std::wstring(L"needles"))); + VERIFY(haystack.contains(std::wstring(L" for "))); + VERIFY(!haystack.contains(std::wstring(L"places"))); + + VERIFY(haystack.contains(std::wstring_view(L""))); + VERIFY(haystack.contains(std::wstring_view(L"no"))); + VERIFY(haystack.contains(std::wstring_view(L"needles"))); + VERIFY(haystack.contains(std::wstring_view(L" for "))); + VERIFY(!haystack.contains(std::wstring_view(L"places"))); + + VERIFY(!haystack.contains('\0')); + VERIFY(haystack.contains('n')); + VERIFY(haystack.contains('e')); + VERIFY(haystack.contains('s')); + VERIFY(!haystack.contains('x')); + + VERIFY(haystack.contains(L"")); + VERIFY(haystack.contains(L"no")); + VERIFY(haystack.contains(L"needles")); + VERIFY(haystack.contains(L" for ")); + VERIFY(!haystack.contains(L"places")); + + const std::wstring nothing; + VERIFY(nothing.contains(L"")); + VERIFY(!nothing.contains('\0')); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char/1.cc index 7445942679b..4f4a8d2c20c 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char/1.cc @@ -50,7 +50,7 @@ test01() int main() -{ +{ test01(); return 0; } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc index 5c4e94aba75..022f128a2a0 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t/1.cc @@ -50,7 +50,7 @@ test01() int main() -{ +{ test01(); return 0; } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/char/1.cc new file mode 100644 index 00000000000..6acc2baf28a --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/char/1.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++2b } } + +// Copyright (C) 2018-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// basic_string_view contains + +#include <string_view> + +void +test01() +{ + constexpr std::string_view haystack("no place for needles"); + + static_assert(haystack.contains(std::string_view(""))); + static_assert(haystack.contains(std::string_view("no"))); + static_assert(haystack.contains(std::string_view("needles"))); + static_assert(haystack.contains(std::string_view(" for "))); + static_assert(!haystack.contains(std::string_view("places"))); + + static_assert(!haystack.contains('\0')); + static_assert(haystack.contains('n')); + static_assert(haystack.contains('e')); + static_assert(haystack.contains('s')); + static_assert(!haystack.contains('x')); + + static_assert(haystack.contains("")); + static_assert(haystack.contains("no")); + static_assert(haystack.contains("needles")); + static_assert(haystack.contains(" for ")); + static_assert(!haystack.contains("places")); + + constexpr std::string_view nothing; + static_assert(nothing.contains("")); + static_assert(!nothing.contains('\0')); +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/wchar_t/1.cc new file mode 100644 index 00000000000..ba64f613633 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/wchar_t/1.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++2b } } + +// Copyright (C) 2018-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// basic_string_view contains + +#include <string_view> + +void +test01() +{ + constexpr std::wstring_view haystack = L"no place for needles"; + + static_assert(haystack.contains(std::wstring_view(L""))); + static_assert(haystack.contains(std::wstring_view(L"no"))); + static_assert(haystack.contains(std::wstring_view(L"needles"))); + static_assert(haystack.contains(std::wstring_view(L" for "))); + static_assert(!haystack.contains(std::wstring_view(L"places"))); + + static_assert(!haystack.contains('\0')); + static_assert(haystack.contains('n')); + static_assert(haystack.contains('e')); + static_assert(haystack.contains('s')); + static_assert(!haystack.contains('x')); + + static_assert(haystack.contains(L"")); + static_assert(haystack.contains(L"no")); + static_assert(haystack.contains(L"needles")); + static_assert(haystack.contains(L" for ")); + static_assert(!haystack.contains(L"places")); + + constexpr std::wstring_view nothing; + static_assert(nothing.contains(L"")); + static_assert(!nothing.contains('\0')); +}