public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: Make string_view::copy usable in constant expressions (PR 94498) Date: Wed, 17 Jun 2020 20:12:29 +0000 (GMT) [thread overview] Message-ID: <20200617201229.2C7D5395C029@sourceware.org> (raw) https://gcc.gnu.org/g:b696698767ba45b4d61a93205167e2f1f744d3f1 commit b696698767ba45b4d61a93205167e2f1f744d3f1 Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Apr 6 18:30:53 2020 +0100 libstdc++: Make string_view::copy usable in constant expressions (PR 94498) PR libstdc++/94498 * include/bits/char_traits.h (__gnu_cxx::char_traits::move): Make it usable in constant expressions for C++20. (__gnu_cxx::char_traits::copy, __gnu_cxx::char_traits::assign): Add _GLIBCXX20_CONSTEXPR. (std::char_traits<char>, std::char_traits<wchar_t>) (std::char_traits<char8_t>): Make move, copy and assign usable in constant expressions for C++20. (std::char_traits<char16_t>, std::char_traits<char32_t>): Make move and copy usable in constant expressions for C++20. * include/std/string_view (basic_string_view::copy): Add _GLIBCXX20_CONSTEXPR. * testsuite/21_strings/basic_string_view/operations/copy/char/ constexpr.cc: New test. * testsuite/21_strings/basic_string_view/operations/copy/wchar_t/ constexpr.cc: New test. Diff: --- libstdc++-v3/ChangeLog | 19 ++++ libstdc++-v3/include/bits/char_traits.h | 101 +++++++++++++++++---- libstdc++-v3/include/std/string_view | 1 + .../operations/copy/char/constexpr.cc | 32 +++++++ .../operations/copy/wchar_t/constexpr.cc | 32 +++++++ 5 files changed, 167 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index eb092792229..4d7b5780189 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2020-04-06 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/94498 + * include/bits/char_traits.h (__gnu_cxx::char_traits::move): Make it + usable in constant expressions for C++20. + (__gnu_cxx::char_traits::copy, __gnu_cxx::char_traits::assign): Add + _GLIBCXX20_CONSTEXPR. + (std::char_traits<char>, std::char_traits<wchar_t>) + (std::char_traits<char8_t>): Make move, copy and assign usable in + constant expressions for C++20. + (std::char_traits<char16_t>, std::char_traits<char32_t>): Make move + and copy usable in constant expressions for C++20. + * include/std/string_view (basic_string_view::copy): Add + _GLIBCXX20_CONSTEXPR. + * testsuite/21_strings/basic_string_view/operations/copy/char/ + constexpr.cc: New test. + * testsuite/21_strings/basic_string_view/operations/copy/wchar_t/ + constexpr.cc: New test. + 2020-04-05 Gerald Pfeifer <gerald@pfeifer.com> * doc/xml/manual/appendix_contributing.xml: Refer to Git diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 2edb84ca3b8..65031d3ac83 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -113,13 +113,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX14_CONSTEXPR const char_type* find(const char_type* __s, std::size_t __n, const char_type& __a); - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, std::size_t __n); - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, std::size_t __n); - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, std::size_t __n, char_type __a); static _GLIBCXX_CONSTEXPR char_type @@ -179,17 +179,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _CharT> + _GLIBCXX20_CONSTEXPR typename char_traits<_CharT>::char_type* char_traits<_CharT>:: move(char_type* __s1, const char_type* __s2, std::size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + { + if (__s1 > __s2 && __s1 < __s2 + __n) + std::copy_backward(__s2, __s2 + __n, __s1); + else + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } +#endif return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))); } template<typename _CharT> + _GLIBCXX20_CONSTEXPR typename char_traits<_CharT>::char_type* char_traits<_CharT>:: copy(char_type* __s1, const char_type* __s2, std::size_t __n) @@ -200,6 +212,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _CharT> + _GLIBCXX20_CONSTEXPR typename char_traits<_CharT>::char_type* char_traits<_CharT>:: assign(char_type* __s, std::size_t __n, char_type __a) @@ -349,27 +362,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); +#endif return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); +#endif return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, size_t __n, char_type __a) { if (__n == 0) return __s; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); +#endif return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } @@ -458,27 +483,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return wmemchr(__s, __a, __n); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); +#endif return wmemmove(__s1, __s2, __n); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); +#endif return wmemcpy(__s1, __s2, __n); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, size_t __n, char_type __a) { if (__n == 0) return __s; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); +#endif return wmemset(__s, __a, __n); } @@ -567,27 +604,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); +#endif return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); +#endif return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, size_t __n, char_type __a) { if (__n == 0) return __s; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); +#endif return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } @@ -680,25 +729,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return 0; } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); +#endif return (static_cast<char_type*> (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); +#endif return (static_cast<char_type*> (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, size_t __n, char_type __a) { for (size_t __i = 0; __i < __n; ++__i) @@ -783,25 +840,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return 0; } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); +#endif return (static_cast<char_type*> (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); +#endif return (static_cast<char_type*> (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); } - static char_type* + static _GLIBCXX20_CONSTEXPR char_type* assign(char_type* __s, size_t __n, char_type __a) { for (size_t __i = 0; __i < __n; ++__i) diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 99a81bb04fa..ea1ccc9bb21 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -263,6 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [string.view.ops], string operations: + _GLIBCXX20_CONSTEXPR size_type copy(_CharT* __str, size_type __n, size_type __pos = 0) const { diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/constexpr.cc new file mode 100644 index 00000000000..f3042c25dc4 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/constexpr.cc @@ -0,0 +1,32 @@ +// Copyright (C) 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/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <string_view> + +constexpr bool +test01() +{ + std::string_view s = "Everything changes and nothing stands still."; + char buf[7]; + auto n = s.copy(buf, 7, 11); + return std::string_view(buf, n) == "changes"; +} + +static_assert( test01() ); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/constexpr.cc new file mode 100644 index 00000000000..f48a17eade8 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/constexpr.cc @@ -0,0 +1,32 @@ +// Copyright (C) 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/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <string_view> + +constexpr bool +test01() +{ + std::wstring_view s = L"Everything changes and nothing stands still."; + wchar_t buf[7]; + auto n = s.copy(buf, 7, 11); + return std::wstring_view(buf, n) == L"changes"; +} + +static_assert( test01() );
reply other threads:[~2020-06-17 20:12 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200617201229.2C7D5395C029@sourceware.org \ --to=aldyh@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).