From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by sourceware.org (Postfix) with ESMTPS id 24994389FC1F; Wed, 13 Jan 2021 01:21:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 24994389FC1F Received: by mail-lj1-x230.google.com with SMTP id x23so688848lji.7; Tue, 12 Jan 2021 17:21:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=+sGkyqXcLvo/YmiV8QoY0w1Mqi0zQRcoZjTDH2P/TfU=; b=AiFeV+zXiwau5PhNnVM7dz9ZqkhSNSXQAX6AyOrxKnO/Ir4mI6Ahn3lOWnevrYpWnQ MCCS8Y0SMnTyNhr+B6j9LX/GwRRK9baONuDuiIKiywsXLFOP9Ol+uGCoKJDthsyty+fJ x5rdh6bWDm7y5djYDA6+mAlGCp1yqzFbybd9bswL9j5Jm2F+K/SubQ9JcCAneNvYlrGP HXdXi8bLRavRihJR1gx/4ga2cM4gx8aml+E/LqPgWNgHQmXPZquCOF5v5wLp56rnSjz/ irYlvqKJyYj+C9tEUBN+D/Iif3nO6oGDfPHOM5hZ+pqFhCAufikGaWeHOk8MscyPw/gP iMJA== X-Gm-Message-State: AOAM533VKDnObea0bHXRuktuC4+lf5PCaI6sgPSofZU/vaxjMeXMwDjk A16BYIzKDJtN7oOHRb8fQBLNSgZNOldazK99LZ6YChrOS6NN8Q== X-Google-Smtp-Source: ABdhPJy0KtpB4gTLRNzkclobTnFY2FsSokCZNeSeJlgG8XC6pZclJ9OSGLJQ6ArhFOwopEgzMXpcRO6kaW/3mtGd5r4= X-Received: by 2002:a2e:8652:: with SMTP id i18mr828143ljj.63.1610500907376; Tue, 12 Jan 2021 17:21:47 -0800 (PST) MIME-Version: 1.0 From: Paul Fee Date: Wed, 13 Jan 2021 01:21:36 +0000 Message-ID: Subject: [PATCH] libstdc++: c++2b, implement WG21 P1679R3 To: gcc-patches , "libstdc++" Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2021 01:21:51 -0000 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 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 +// . + +// basic_string contains + +#include +#include + +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 +// . + +// basic_string begins_with + +#include +#include + +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 +// . + +// basic_string_view contains + +#include + +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 +// . + +// basic_string_view contains + +#include + +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')); +}