Commit 8c3b5c71 by Jonathan Wakely Committed by Jonathan Wakely

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.

From-SVN: r246655
parent bbdf4e81
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
......
......@@ -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)
......
// { 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>>() );
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment