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.
This commit is contained in:
parent
f84aded848
commit
b696698767
5 changed files with 167 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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() );
|
|
@ -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() );
|
Loading…
Add table
Reference in a new issue