[PATCH] Finish implementing P0426R1 "Constexpr for std::char_traits" for C++17
Pedro Alves
palves@redhat.com
Mon Jun 12 22:28:00 GMT 2017
On 06/05/2017 03:27 PM, Jonathan Wakely wrote:
> Pedro, this is OK for trunk now we're in stage 1. Please go ahead and
> commit it - thanks.
Thanks Jonathan. I've pushed it in now.
>
> It's probably safe for gcc-7-branch too, but let's leave it on trunk
> for a while first.
OK.
BTW, for extra thoroughness, to confirm we're handling both
const & non-const arrays correctly, I had written this testsuite
tweak too. Would you like to have this in?
>From 3f7adab8bab68955aafd760467bb860057140d40 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Mon, 12 Jun 2017 20:23:23 +0100
Subject: [PATCH] constexpr char_traits: Test non-const strings/arrays too
libstdc++-v3/ChangeLog
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
(test_assign, test_compare, test_length, test_find): Test
non-const strings/arrays too.
(struct C): Add a generic conversion ctor.
---
.../requirements/constexpr_functions_c++17.cc | 173 ++++++++++++++++++---
1 file changed, 150 insertions(+), 23 deletions(-)
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
index efd280f..c41b490 100644
--- 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
@@ -25,10 +25,40 @@ template<typename CT>
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};
+
+ auto check = [](char_type* s1, const char_type* s2)
+ {
+ CT::assign(s1[0], s2[0]);
+ return s1[0] == char_type{1};
+ };
+
+ // const strings.
+
+ {
+ char_type s1[2] = {};
+ const char_type s2[2] = {1, 0};
+ if (!check (s1, s2))
+ return false;
+ }
+
+ // non-const strings.
+
+ {
+ char_type s1[2] = {};
+ char_type s2[2] = {1, 0};
+ if (!check (s1, s2))
+ return false;
+ }
+
+ {
+ char_type s1[2] = {};
+ char_type s2[2] = {};
+ s2[0] = char_type{1};
+ if (!check (s1, s2))
+ return false;
+ }
+
+ return true;
}
template<typename CT>
@@ -36,14 +66,48 @@ template<typename CT>
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;
+
+ auto check = [](const char_type* s1, const char_type* s2)
+ {
+ 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;
+ };
+
+ // const arrays.
+
+ {
+ const char_type s1[3] = {1, 2, 3};
+ const char_type s2[3] = {1, 2, 3};
+ if (!check (s1, s2))
+ return false;
+ }
+
+ // non-const arrays.
+
+ {
+ char_type s1[3] = {1, 2, 3};
+ char_type s2[3] = {1, 2, 3};
+ if (!check (s1, s2))
+ return false;
+ }
+
+ {
+ char_type s1[3] = {};
+ char_type s2[3] = {};
+ for (size_t i = 0; i < 3; i++)
+ {
+ s1[i] = char_type(i+1);
+ s2[i] = char_type(i+1);
+ }
+ if (!check (s1, s2))
+ return false;
+ }
+
return true;
}
@@ -52,11 +116,40 @@ template<typename CT>
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;
+
+ auto check = [](const char_type* s)
+ {
+ if (CT::length(s) != 3)
+ return false;
+ if (CT::length(s+1) != 2)
+ return false;
+ return true;
+ };
+
+ // const strings.
+
+ {
+ const char_type s[4] = {1, 2, 3, 0};
+ if (!check (s))
+ return false;
+ }
+
+ // non-const strings.
+
+ {
+ char_type s[4] = {1, 2, 3, 0};
+ if (!check (s))
+ return false;
+ }
+
+ {
+ char_type s[4] = {};
+ for (size_t i = 0; i < 3; i++)
+ s[i] = char_type(i+1);
+ if (!check (s))
+ return false;
+ }
+
return true;
}
@@ -65,11 +158,40 @@ template<typename CT>
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;
+
+ auto check = [](const char_type* s)
+ {
+ if (CT::find(s, 3, char_type{2}) != s+1)
+ return false;
+ if (CT::find(s, 3, char_type{4}) != nullptr)
+ return false;
+ return true;
+ };
+
+ // const arrays.
+
+ {
+ const char_type s[3] = {1, 2, 3};
+ if (!check(s))
+ return false;
+ }
+
+ // non-const arrays.
+
+ {
+ char_type s[3] = {1, 2, 3};
+ if (!check(s))
+ return false;
+ }
+
+ {
+ char_type s[3] = {};
+ for (size_t i = 0; i < 3; i++)
+ s[i] = char_type(i+1);
+ if (!check(s))
+ return false;
+ }
+
return true;
}
@@ -98,7 +220,12 @@ 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; };
+struct C
+{
+ C() = default;
+ constexpr C(auto c_) : c(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>>() );
--
2.5.5
More information about the Gcc-patches
mailing list