summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-03 17:15:53 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-03 17:15:53 +0000
commit323abb909e021f08b2a9fba6b04aebbeda728667 (patch)
treefa7c526148be6e05e2784374cb256b76b6fb482f /libstdc++-v3
parent6d127468dd1d0db677142eb32a97ce93f0f7fc5e (diff)
downloadgcc-323abb909e021f08b2a9fba6b04aebbeda728667.tar.gz
Implement P0426R1 "Constexpr for std::char_traits" for C++17 (partial)
* include/bits/char_traits.h (__gnu_cxx::char_traits): Add _GLIBCXX14_CONSTEXPR on assign, compare, find, and length. (std::char_traits<char>, std::char_traits<wchar_t>): Add _GLIBCXX17_CONSTEXPR on assign. (std::char_traits<char16_t>, std::char_traits<char32_t>): Add _GLIBCXX17_CONSTEXPR on assign, compare, find, and length. * testsuite/21_strings/char_traits/requirements/ constexpr_functions_c++17.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@246655 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/char_traits.h48
-rw-r--r--libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc107
3 files changed, 143 insertions, 23 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4073a82e2a3..caad393416e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2017-04-03 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/char_traits.h (__gnu_cxx::char_traits): Add
+ _GLIBCXX14_CONSTEXPR on assign, compare, find, and length.
+ (std::char_traits<char>, std::char_traits<wchar_t>): Add
+ _GLIBCXX17_CONSTEXPR on assign.
+ (std::char_traits<char16_t>, std::char_traits<char32_t>): Add
+ _GLIBCXX17_CONSTEXPR on assign, compare, find, and length.
+ * testsuite/21_strings/char_traits/requirements/
+ constexpr_functions_c++17.cc: New test.
+
2017-04-03 Ville Voutilainen <ville.voutilainen@gmail.com>
PR libstdc++/79141
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index bcfc23a93b8..75db5b89321 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename _Char_types<_CharT>::off_type off_type;
typedef typename _Char_types<_CharT>::state_type state_type;
- static void
+ static _GLIBCXX14_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2)
{ __c1 = __c2; }
@@ -100,13 +100,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX14_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
- static std::size_t
+ static _GLIBCXX14_CONSTEXPR std::size_t
length(const char_type* __s);
- static const char_type*
+ static _GLIBCXX14_CONSTEXPR const char_type*
find(const char_type* __s, std::size_t __n, const char_type& __a);
static char_type*
@@ -139,8 +139,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
+// #define __cpp_lib_constexpr_char_traits 201611
+
template<typename _CharT>
- int
+ _GLIBCXX14_CONSTEXPR int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
@@ -153,7 +155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _CharT>
- std::size_t
+ _GLIBCXX14_CONSTEXPR std::size_t
char_traits<_CharT>::
length(const char_type* __p)
{
@@ -164,7 +166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _CharT>
- const typename char_traits<_CharT>::char_type*
+ _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
find(const char_type* __s, std::size_t __n, const char_type& __a)
{
@@ -238,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streamoff off_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
@@ -254,7 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
< static_cast<unsigned char>(__c2));
}
- static int
+ static /* _GLIBCXX17_CONSTEXPR */ int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
@@ -262,11 +264,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __builtin_memcmp(__s1, __s2, __n);
}
- static size_t
+ static /* _GLIBCXX17_CONSTEXPR */ size_t
length(const char_type* __s)
{ return __builtin_strlen(__s); }
- static const char_type*
+ static /* _GLIBCXX17_CONSTEXPR */ const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
@@ -333,7 +335,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef wstreampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
@@ -345,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
- static int
+ static /* _GLIBCXX17_CONSTEXPR */ int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
@@ -353,11 +355,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return wmemcmp(__s1, __s2, __n);
}
- static size_t
+ static /* _GLIBCXX17_CONSTEXPR */ size_t
length(const char_type* __s)
{ return wcslen(__s); }
- static const char_type*
+ static /* _GLIBCXX17_CONSTEXPR */ const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
@@ -432,7 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef u16streampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
@@ -444,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -455,7 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return 0;
}
- static size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
@@ -464,7 +466,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __i;
}
- static const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -529,7 +531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef u32streampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
@@ -541,7 +543,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -552,7 +554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return 0;
}
- static size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
@@ -561,7 +563,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __i;
}
- static const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
new file mode 100644
index 00000000000..014caa02313
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
@@ -0,0 +1,107 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+// Copyright (C) 2017 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/>.
+
+#include <string>
+
+template<typename CT>
+ constexpr bool
+ test_assign()
+ {
+ using char_type = typename CT::char_type;
+ char_type s1[2] = {};
+ const char_type s2[2] = {1, 0};
+ CT::assign(s1[0], s2[0]);
+ return s1[0] == char_type{1};
+ }
+
+template<typename CT>
+ constexpr bool
+ test_compare()
+ {
+ using char_type = typename CT::char_type;
+ const char_type s1[3] = {1, 2, 3};
+ const char_type s2[3] = {1, 2, 3};
+ if (CT::compare(s1, s2, 3) != 0)
+ return false;
+ if (CT::compare(s2, s1, 3) != 0)
+ return false;
+ if (CT::compare(s1+1, s2, 2) <= 0)
+ return false;
+ return true;
+ }
+
+template<typename CT>
+ constexpr bool
+ test_length()
+ {
+ using char_type = typename CT::char_type;
+ const char_type s1[4] = {1, 2, 3, 0};
+ if (CT::length(s1) != 3)
+ return false;
+ if (CT::length(s1+1) != 2)
+ return false;
+ return true;
+ }
+
+template<typename CT>
+ constexpr bool
+ test_find()
+ {
+ using char_type = typename CT::char_type;
+ const char_type s1[3] = {1, 2, 3};
+ if (CT::find(s1, 3, char_type{2}) != s1+1)
+ return false;
+ if (CT::find(s1, 3, char_type{4}) != nullptr)
+ return false;
+ return true;
+ }
+
+#ifndef __cpp_lib_constexpr_char_traits
+// #error Feature-test macro for constexpr char_traits is missing
+#elif __cpp_lib_constexpr_char_traits != 201611
+// #error Feature-test macro for constexpr char_traits has the wrong value
+#endif
+
+static_assert( test_assign<std::char_traits<char>>() );
+// static_assert( test_compare<std::char_traits<char>>() );
+// static_assert( test_length<std::char_traits<char>>() );
+// static_assert( test_find<std::char_traits<char>>() );
+#ifdef _GLIBCXX_USE_WCHAR_T
+static_assert( test_assign<std::char_traits<wchar_t>>() );
+// static_assert( test_compare<std::char_traits<wchar_t>>() );
+// static_assert( test_length<std::char_traits<wchar_t>>() );
+// static_assert( test_find<std::char_traits<wchar_t>>() );
+#endif
+static_assert( test_assign<std::char_traits<char16_t>>() );
+static_assert( test_compare<std::char_traits<char16_t>>() );
+static_assert( test_length<std::char_traits<char16_t>>() );
+static_assert( test_find<std::char_traits<char16_t>>() );
+static_assert( test_assign<std::char_traits<char32_t>>() );
+static_assert( test_compare<std::char_traits<char32_t>>() );
+static_assert( test_length<std::char_traits<char32_t>>() );
+static_assert( test_find<std::char_traits<char32_t>>() );
+
+struct C { unsigned char c; };
+constexpr bool operator==(const C& c1, const C& c2) { return c1.c == c2.c; }
+constexpr bool operator<(const C& c1, const C& c2) { return c1.c < c2.c; }
+static_assert( test_assign<std::char_traits<C>>() );
+static_assert( test_compare<std::char_traits<C>>() );
+static_assert( test_length<std::char_traits<C>>() );
+static_assert( test_find<std::char_traits<C>>() );