+2017-06-12 Pedro Alves <palves@redhat.com>
+
+ * doc/xml/manual/status_cxx2017.xml: Update C++17 constexpr
+ char_traits status.
+ * doc/html/*: Regenerate.
+
+ * include/bits/char_traits.h (_GLIBCXX_ALWAYS_INLINE): Define if
+ not already defined.
+ (__cpp_lib_constexpr_char_traits): Uncomment.
+ (__constant_string_p, __constant_char_array_p): New.
+ (std::char_traits<char>, std::char_traits<wchar_t>): Add
+ _GLIBCXX17_CONSTEXPR on compare, length and find and use
+ __constant_string_p, __constant_char_array_p and
+ __builtin_constant_p to defer to __gnu_cxx::char_traits at compile
+ time.
+
+ * testsuite/21_strings/char_traits/requirements/
+ constexpr_functions_c++17.cc: Uncomment
+ __cpp_lib_constexpr_char_traits tests. Uncomment
+ test_compare<char>, test_length<char>, test_find<char>,
+ test_compare<wchar_t>, test_length<wchar_t> and test_find<wchar_t>
+ static_assert tests.
+
2017-06-12 François Dumont <fdumont@gcc.gnu.org>
* include/bits/stl_tree.h (_Rb_tree_impl()): Restore _Node_allocator
#include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
+#ifndef _GLIBCXX_ALWAYS_INLINE
+#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
+#endif
+
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
-// #define __cpp_lib_constexpr_char_traits 201611
+#define __cpp_lib_constexpr_char_traits 201611
template<typename _CharT>
_GLIBCXX14_CONSTEXPR int
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+#if __cplusplus > 201402
+ /**
+ * @brief Determine whether the characters of a NULL-terminated
+ * string are known at compile time.
+ * @param __s The string.
+ *
+ * Assumes that _CharT is a built-in character type.
+ */
+ template<typename _CharT>
+ static _GLIBCXX_ALWAYS_INLINE constexpr bool
+ __constant_string_p(const _CharT* __s)
+ {
+ while (__builtin_constant_p(*__s) && *__s)
+ __s++;
+ return __builtin_constant_p(*__s);
+ }
+
+ /**
+ * @brief Determine whether the characters of a character array are
+ * known at compile time.
+ * @param __a The character array.
+ * @param __n Number of characters.
+ *
+ * Assumes that _CharT is a built-in character type.
+ */
+ template<typename _CharT>
+ static _GLIBCXX_ALWAYS_INLINE constexpr bool
+ __constant_char_array_p(const _CharT* __a, size_t __n)
+ {
+ size_t __i = 0;
+ while (__builtin_constant_p(__a[__i]) && __i < __n)
+ __i++;
+ return __i == __n;
+ }
+#endif
+
// 21.1
/**
* @brief Basis for explicit traits specializations.
< static_cast<unsigned char>(__c2));
}
- static /* _GLIBCXX17_CONSTEXPR */ int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __constant_char_array_p(__s1, __n)
+ && __constant_char_array_p(__s2, __n))
+ return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
+#endif
if (__n == 0)
return 0;
return __builtin_memcmp(__s1, __s2, __n);
}
- static /* _GLIBCXX17_CONSTEXPR */ size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
- { return __builtin_strlen(__s); }
+ {
+#if __cplusplus > 201402
+ if (__constant_string_p(__s))
+ return __gnu_cxx::char_traits<char_type>::length(__s);
+#endif
+ return __builtin_strlen(__s);
+ }
- static /* _GLIBCXX17_CONSTEXPR */ const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __builtin_constant_p(__a)
+ && __constant_char_array_p(__s, __n))
+ return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
+#endif
if (__n == 0)
return 0;
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
- static /* _GLIBCXX17_CONSTEXPR */ int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __constant_char_array_p(__s1, __n)
+ && __constant_char_array_p(__s2, __n))
+ return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
+#endif
if (__n == 0)
return 0;
- return wmemcmp(__s1, __s2, __n);
+ else
+ return wmemcmp(__s1, __s2, __n);
}
- static /* _GLIBCXX17_CONSTEXPR */ size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
- { return wcslen(__s); }
+ {
+#if __cplusplus > 201402
+ if (__constant_string_p(__s))
+ return __gnu_cxx::char_traits<char_type>::length(__s);
+ else
+#endif
+ return wcslen(__s);
+ }
- static /* _GLIBCXX17_CONSTEXPR */ const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __builtin_constant_p(__a)
+ && __constant_char_array_p(__s, __n))
+ return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
+#endif
if (__n == 0)
return 0;
- return wmemchr(__s, __a, __n);
+ else
+ return wmemchr(__s, __a, __n);
}
static char_type*
}
#ifndef __cpp_lib_constexpr_char_traits
-// #error Feature-test macro for constexpr char_traits is missing
+# 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
+# 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>>() );
+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>>() );
+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>>() );