138fd1498Szrj // Character Traits for use by standard string and iostream -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj /** @file bits/char_traits.h 2638fd1498Szrj * This is an internal header file, included by other library headers. 2738fd1498Szrj * Do not attempt to use it directly. @headername{string} 2838fd1498Szrj */ 2938fd1498Szrj 3038fd1498Szrj // 3138fd1498Szrj // ISO C++ 14882: 21 Strings library 3238fd1498Szrj // 3338fd1498Szrj 3438fd1498Szrj #ifndef _CHAR_TRAITS_H 3538fd1498Szrj #define _CHAR_TRAITS_H 1 3638fd1498Szrj 3738fd1498Szrj #pragma GCC system_header 3838fd1498Szrj 3938fd1498Szrj #include <bits/stl_algobase.h> // std::copy, std::fill_n 4038fd1498Szrj #include <bits/postypes.h> // For streampos 4138fd1498Szrj #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 4238fd1498Szrj 4338fd1498Szrj #ifndef _GLIBCXX_ALWAYS_INLINE 4438fd1498Szrj #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 4538fd1498Szrj #endif 4638fd1498Szrj 4738fd1498Szrj namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 4838fd1498Szrj { 4938fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 5038fd1498Szrj 5138fd1498Szrj /** 5238fd1498Szrj * @brief Mapping from character type to associated types. 5338fd1498Szrj * 5438fd1498Szrj * @note This is an implementation class for the generic version 5538fd1498Szrj * of char_traits. It defines int_type, off_type, pos_type, and 5638fd1498Szrj * state_type. By default these are unsigned long, streamoff, 5738fd1498Szrj * streampos, and mbstate_t. Users who need a different set of 5838fd1498Szrj * types, but who don't need to change the definitions of any function 5938fd1498Szrj * defined in char_traits, can specialize __gnu_cxx::_Char_types 6038fd1498Szrj * while leaving __gnu_cxx::char_traits alone. */ 6138fd1498Szrj template<typename _CharT> 6238fd1498Szrj struct _Char_types 6338fd1498Szrj { 6438fd1498Szrj typedef unsigned long int_type; 6538fd1498Szrj typedef std::streampos pos_type; 6638fd1498Szrj typedef std::streamoff off_type; 6738fd1498Szrj typedef std::mbstate_t state_type; 6838fd1498Szrj }; 6938fd1498Szrj 7038fd1498Szrj 7138fd1498Szrj /** 7238fd1498Szrj * @brief Base class used to implement std::char_traits. 7338fd1498Szrj * 7438fd1498Szrj * @note For any given actual character type, this definition is 7538fd1498Szrj * probably wrong. (Most of the member functions are likely to be 7638fd1498Szrj * right, but the int_type and state_type typedefs, and the eof() 7738fd1498Szrj * member function, are likely to be wrong.) The reason this class 7838fd1498Szrj * exists is so users can specialize it. Classes in namespace std 7938fd1498Szrj * may not be specialized for fundamental types, but classes in 8038fd1498Szrj * namespace __gnu_cxx may be. 8138fd1498Szrj * 8238fd1498Szrj * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 8338fd1498Szrj * for advice on how to make use of this class for @a unusual character 8438fd1498Szrj * types. Also, check out include/ext/pod_char_traits.h. 8538fd1498Szrj */ 8638fd1498Szrj template<typename _CharT> 8738fd1498Szrj struct char_traits 8838fd1498Szrj { 8938fd1498Szrj typedef _CharT char_type; 9038fd1498Szrj typedef typename _Char_types<_CharT>::int_type int_type; 9138fd1498Szrj typedef typename _Char_types<_CharT>::pos_type pos_type; 9238fd1498Szrj typedef typename _Char_types<_CharT>::off_type off_type; 9338fd1498Szrj typedef typename _Char_types<_CharT>::state_type state_type; 9438fd1498Szrj 9538fd1498Szrj static _GLIBCXX14_CONSTEXPR void 9638fd1498Szrj assign(char_type& __c1, const char_type& __c2) 9738fd1498Szrj { __c1 = __c2; } 9838fd1498Szrj 9938fd1498Szrj static _GLIBCXX_CONSTEXPR bool 10038fd1498Szrj eq(const char_type& __c1, const char_type& __c2) 10138fd1498Szrj { return __c1 == __c2; } 10238fd1498Szrj 10338fd1498Szrj static _GLIBCXX_CONSTEXPR bool 10438fd1498Szrj lt(const char_type& __c1, const char_type& __c2) 10538fd1498Szrj { return __c1 < __c2; } 10638fd1498Szrj 10738fd1498Szrj static _GLIBCXX14_CONSTEXPR int 10838fd1498Szrj compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 10938fd1498Szrj 11038fd1498Szrj static _GLIBCXX14_CONSTEXPR std::size_t 11138fd1498Szrj length(const char_type* __s); 11238fd1498Szrj 11338fd1498Szrj static _GLIBCXX14_CONSTEXPR const char_type* 11438fd1498Szrj find(const char_type* __s, std::size_t __n, const char_type& __a); 11538fd1498Szrj 11638fd1498Szrj static char_type* 11738fd1498Szrj move(char_type* __s1, const char_type* __s2, std::size_t __n); 11838fd1498Szrj 11938fd1498Szrj static char_type* 12038fd1498Szrj copy(char_type* __s1, const char_type* __s2, std::size_t __n); 12138fd1498Szrj 12238fd1498Szrj static char_type* 12338fd1498Szrj assign(char_type* __s, std::size_t __n, char_type __a); 12438fd1498Szrj 12538fd1498Szrj static _GLIBCXX_CONSTEXPR char_type 12638fd1498Szrj to_char_type(const int_type& __c) 12738fd1498Szrj { return static_cast<char_type>(__c); } 12838fd1498Szrj 12938fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 13038fd1498Szrj to_int_type(const char_type& __c) 13138fd1498Szrj { return static_cast<int_type>(__c); } 13238fd1498Szrj 13338fd1498Szrj static _GLIBCXX_CONSTEXPR bool 13438fd1498Szrj eq_int_type(const int_type& __c1, const int_type& __c2) 13538fd1498Szrj { return __c1 == __c2; } 13638fd1498Szrj 13738fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 13838fd1498Szrj eof() 13938fd1498Szrj { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 14038fd1498Szrj 14138fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 14238fd1498Szrj not_eof(const int_type& __c) 14338fd1498Szrj { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 14438fd1498Szrj }; 14538fd1498Szrj 14638fd1498Szrj template<typename _CharT> 14738fd1498Szrj _GLIBCXX14_CONSTEXPR int 14838fd1498Szrj char_traits<_CharT>:: 14938fd1498Szrj compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 15038fd1498Szrj { 15138fd1498Szrj for (std::size_t __i = 0; __i < __n; ++__i) 15238fd1498Szrj if (lt(__s1[__i], __s2[__i])) 15338fd1498Szrj return -1; 15438fd1498Szrj else if (lt(__s2[__i], __s1[__i])) 15538fd1498Szrj return 1; 15638fd1498Szrj return 0; 15738fd1498Szrj } 15838fd1498Szrj 15938fd1498Szrj template<typename _CharT> 16038fd1498Szrj _GLIBCXX14_CONSTEXPR std::size_t 16138fd1498Szrj char_traits<_CharT>:: 16238fd1498Szrj length(const char_type* __p) 16338fd1498Szrj { 16438fd1498Szrj std::size_t __i = 0; 16538fd1498Szrj while (!eq(__p[__i], char_type())) 16638fd1498Szrj ++__i; 16738fd1498Szrj return __i; 16838fd1498Szrj } 16938fd1498Szrj 17038fd1498Szrj template<typename _CharT> 17138fd1498Szrj _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 17238fd1498Szrj char_traits<_CharT>:: 17338fd1498Szrj find(const char_type* __s, std::size_t __n, const char_type& __a) 17438fd1498Szrj { 17538fd1498Szrj for (std::size_t __i = 0; __i < __n; ++__i) 17638fd1498Szrj if (eq(__s[__i], __a)) 17738fd1498Szrj return __s + __i; 17838fd1498Szrj return 0; 17938fd1498Szrj } 18038fd1498Szrj 18138fd1498Szrj template<typename _CharT> 18238fd1498Szrj typename char_traits<_CharT>::char_type* 18338fd1498Szrj char_traits<_CharT>:: 18438fd1498Szrj move(char_type* __s1, const char_type* __s2, std::size_t __n) 18538fd1498Szrj { 186*58e805e6Szrj if (__n == 0) 187*58e805e6Szrj return __s1; 18838fd1498Szrj return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 18938fd1498Szrj __n * sizeof(char_type))); 19038fd1498Szrj } 19138fd1498Szrj 19238fd1498Szrj template<typename _CharT> 19338fd1498Szrj typename char_traits<_CharT>::char_type* 19438fd1498Szrj char_traits<_CharT>:: 19538fd1498Szrj copy(char_type* __s1, const char_type* __s2, std::size_t __n) 19638fd1498Szrj { 19738fd1498Szrj // NB: Inline std::copy so no recursive dependencies. 19838fd1498Szrj std::copy(__s2, __s2 + __n, __s1); 19938fd1498Szrj return __s1; 20038fd1498Szrj } 20138fd1498Szrj 20238fd1498Szrj template<typename _CharT> 20338fd1498Szrj typename char_traits<_CharT>::char_type* 20438fd1498Szrj char_traits<_CharT>:: 20538fd1498Szrj assign(char_type* __s, std::size_t __n, char_type __a) 20638fd1498Szrj { 20738fd1498Szrj // NB: Inline std::fill_n so no recursive dependencies. 20838fd1498Szrj std::fill_n(__s, __n, __a); 20938fd1498Szrj return __s; 21038fd1498Szrj } 21138fd1498Szrj 21238fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 21338fd1498Szrj } // namespace 21438fd1498Szrj 21538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 21638fd1498Szrj { 21738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 21838fd1498Szrj 21938fd1498Szrj #if __cplusplus > 201402 220*58e805e6Szrj #define __cpp_lib_constexpr_char_traits 201611 221*58e805e6Szrj 22238fd1498Szrj /** 22338fd1498Szrj * @brief Determine whether the characters of a NULL-terminated 22438fd1498Szrj * string are known at compile time. 22538fd1498Szrj * @param __s The string. 22638fd1498Szrj * 22738fd1498Szrj * Assumes that _CharT is a built-in character type. 22838fd1498Szrj */ 22938fd1498Szrj template<typename _CharT> 23038fd1498Szrj static _GLIBCXX_ALWAYS_INLINE constexpr bool 23138fd1498Szrj __constant_string_p(const _CharT* __s) 23238fd1498Szrj { 23338fd1498Szrj while (__builtin_constant_p(*__s) && *__s) 23438fd1498Szrj __s++; 23538fd1498Szrj return __builtin_constant_p(*__s); 23638fd1498Szrj } 23738fd1498Szrj 23838fd1498Szrj /** 23938fd1498Szrj * @brief Determine whether the characters of a character array are 24038fd1498Szrj * known at compile time. 24138fd1498Szrj * @param __a The character array. 24238fd1498Szrj * @param __n Number of characters. 24338fd1498Szrj * 24438fd1498Szrj * Assumes that _CharT is a built-in character type. 24538fd1498Szrj */ 24638fd1498Szrj template<typename _CharT> 24738fd1498Szrj static _GLIBCXX_ALWAYS_INLINE constexpr bool 24838fd1498Szrj __constant_char_array_p(const _CharT* __a, size_t __n) 24938fd1498Szrj { 25038fd1498Szrj size_t __i = 0; 25138fd1498Szrj while (__builtin_constant_p(__a[__i]) && __i < __n) 25238fd1498Szrj __i++; 25338fd1498Szrj return __i == __n; 25438fd1498Szrj } 25538fd1498Szrj #endif 25638fd1498Szrj 25738fd1498Szrj // 21.1 25838fd1498Szrj /** 25938fd1498Szrj * @brief Basis for explicit traits specializations. 26038fd1498Szrj * 26138fd1498Szrj * @note For any given actual character type, this definition is 26238fd1498Szrj * probably wrong. Since this is just a thin wrapper around 26338fd1498Szrj * __gnu_cxx::char_traits, it is possible to achieve a more 26438fd1498Szrj * appropriate definition by specializing __gnu_cxx::char_traits. 26538fd1498Szrj * 26638fd1498Szrj * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 26738fd1498Szrj * for advice on how to make use of this class for @a unusual character 26838fd1498Szrj * types. Also, check out include/ext/pod_char_traits.h. 26938fd1498Szrj */ 27038fd1498Szrj template<class _CharT> 27138fd1498Szrj struct char_traits : public __gnu_cxx::char_traits<_CharT> 27238fd1498Szrj { }; 27338fd1498Szrj 27438fd1498Szrj 27538fd1498Szrj /// 21.1.3.1 char_traits specializations 27638fd1498Szrj template<> 27738fd1498Szrj struct char_traits<char> 27838fd1498Szrj { 27938fd1498Szrj typedef char char_type; 28038fd1498Szrj typedef int int_type; 28138fd1498Szrj typedef streampos pos_type; 28238fd1498Szrj typedef streamoff off_type; 28338fd1498Szrj typedef mbstate_t state_type; 28438fd1498Szrj 28538fd1498Szrj static _GLIBCXX17_CONSTEXPR void 28638fd1498Szrj assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 28738fd1498Szrj { __c1 = __c2; } 28838fd1498Szrj 28938fd1498Szrj static _GLIBCXX_CONSTEXPR bool 29038fd1498Szrj eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 29138fd1498Szrj { return __c1 == __c2; } 29238fd1498Szrj 29338fd1498Szrj static _GLIBCXX_CONSTEXPR bool 29438fd1498Szrj lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 29538fd1498Szrj { 29638fd1498Szrj // LWG 467. 29738fd1498Szrj return (static_cast<unsigned char>(__c1) 29838fd1498Szrj < static_cast<unsigned char>(__c2)); 29938fd1498Szrj } 30038fd1498Szrj 30138fd1498Szrj static _GLIBCXX17_CONSTEXPR int 30238fd1498Szrj compare(const char_type* __s1, const char_type* __s2, size_t __n) 30338fd1498Szrj { 30438fd1498Szrj #if __cplusplus > 201402 30538fd1498Szrj if (__builtin_constant_p(__n) 30638fd1498Szrj && __constant_char_array_p(__s1, __n) 30738fd1498Szrj && __constant_char_array_p(__s2, __n)) 30838fd1498Szrj return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 30938fd1498Szrj #endif 31038fd1498Szrj if (__n == 0) 31138fd1498Szrj return 0; 31238fd1498Szrj return __builtin_memcmp(__s1, __s2, __n); 31338fd1498Szrj } 31438fd1498Szrj 31538fd1498Szrj static _GLIBCXX17_CONSTEXPR size_t 31638fd1498Szrj length(const char_type* __s) 31738fd1498Szrj { 31838fd1498Szrj #if __cplusplus > 201402 31938fd1498Szrj if (__constant_string_p(__s)) 32038fd1498Szrj return __gnu_cxx::char_traits<char_type>::length(__s); 32138fd1498Szrj #endif 32238fd1498Szrj return __builtin_strlen(__s); 32338fd1498Szrj } 32438fd1498Szrj 32538fd1498Szrj static _GLIBCXX17_CONSTEXPR const char_type* 32638fd1498Szrj find(const char_type* __s, size_t __n, const char_type& __a) 32738fd1498Szrj { 32838fd1498Szrj #if __cplusplus > 201402 32938fd1498Szrj if (__builtin_constant_p(__n) 33038fd1498Szrj && __builtin_constant_p(__a) 33138fd1498Szrj && __constant_char_array_p(__s, __n)) 33238fd1498Szrj return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 33338fd1498Szrj #endif 33438fd1498Szrj if (__n == 0) 33538fd1498Szrj return 0; 33638fd1498Szrj return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 33738fd1498Szrj } 33838fd1498Szrj 33938fd1498Szrj static char_type* 34038fd1498Szrj move(char_type* __s1, const char_type* __s2, size_t __n) 34138fd1498Szrj { 34238fd1498Szrj if (__n == 0) 34338fd1498Szrj return __s1; 34438fd1498Szrj return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 34538fd1498Szrj } 34638fd1498Szrj 34738fd1498Szrj static char_type* 34838fd1498Szrj copy(char_type* __s1, const char_type* __s2, size_t __n) 34938fd1498Szrj { 35038fd1498Szrj if (__n == 0) 35138fd1498Szrj return __s1; 35238fd1498Szrj return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 35338fd1498Szrj } 35438fd1498Szrj 35538fd1498Szrj static char_type* 35638fd1498Szrj assign(char_type* __s, size_t __n, char_type __a) 35738fd1498Szrj { 35838fd1498Szrj if (__n == 0) 35938fd1498Szrj return __s; 36038fd1498Szrj return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 36138fd1498Szrj } 36238fd1498Szrj 36338fd1498Szrj static _GLIBCXX_CONSTEXPR char_type 36438fd1498Szrj to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 36538fd1498Szrj { return static_cast<char_type>(__c); } 36638fd1498Szrj 36738fd1498Szrj // To keep both the byte 0xff and the eof symbol 0xffffffff 36838fd1498Szrj // from ending up as 0xffffffff. 36938fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 37038fd1498Szrj to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 37138fd1498Szrj { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 37238fd1498Szrj 37338fd1498Szrj static _GLIBCXX_CONSTEXPR bool 37438fd1498Szrj eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 37538fd1498Szrj { return __c1 == __c2; } 37638fd1498Szrj 37738fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 37838fd1498Szrj eof() _GLIBCXX_NOEXCEPT 37938fd1498Szrj { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 38038fd1498Szrj 38138fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 38238fd1498Szrj not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 38338fd1498Szrj { return (__c == eof()) ? 0 : __c; } 38438fd1498Szrj }; 38538fd1498Szrj 38638fd1498Szrj 38738fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 38838fd1498Szrj /// 21.1.3.2 char_traits specializations 38938fd1498Szrj template<> 39038fd1498Szrj struct char_traits<wchar_t> 39138fd1498Szrj { 39238fd1498Szrj typedef wchar_t char_type; 39338fd1498Szrj typedef wint_t int_type; 39438fd1498Szrj typedef streamoff off_type; 39538fd1498Szrj typedef wstreampos pos_type; 39638fd1498Szrj typedef mbstate_t state_type; 39738fd1498Szrj 39838fd1498Szrj static _GLIBCXX17_CONSTEXPR void 39938fd1498Szrj assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 40038fd1498Szrj { __c1 = __c2; } 40138fd1498Szrj 40238fd1498Szrj static _GLIBCXX_CONSTEXPR bool 40338fd1498Szrj eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 40438fd1498Szrj { return __c1 == __c2; } 40538fd1498Szrj 40638fd1498Szrj static _GLIBCXX_CONSTEXPR bool 40738fd1498Szrj lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 40838fd1498Szrj { return __c1 < __c2; } 40938fd1498Szrj 41038fd1498Szrj static _GLIBCXX17_CONSTEXPR int 41138fd1498Szrj compare(const char_type* __s1, const char_type* __s2, size_t __n) 41238fd1498Szrj { 41338fd1498Szrj #if __cplusplus > 201402 41438fd1498Szrj if (__builtin_constant_p(__n) 41538fd1498Szrj && __constant_char_array_p(__s1, __n) 41638fd1498Szrj && __constant_char_array_p(__s2, __n)) 41738fd1498Szrj return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 41838fd1498Szrj #endif 41938fd1498Szrj if (__n == 0) 42038fd1498Szrj return 0; 42138fd1498Szrj else 42238fd1498Szrj return wmemcmp(__s1, __s2, __n); 42338fd1498Szrj } 42438fd1498Szrj 42538fd1498Szrj static _GLIBCXX17_CONSTEXPR size_t 42638fd1498Szrj length(const char_type* __s) 42738fd1498Szrj { 42838fd1498Szrj #if __cplusplus > 201402 42938fd1498Szrj if (__constant_string_p(__s)) 43038fd1498Szrj return __gnu_cxx::char_traits<char_type>::length(__s); 43138fd1498Szrj else 43238fd1498Szrj #endif 43338fd1498Szrj return wcslen(__s); 43438fd1498Szrj } 43538fd1498Szrj 43638fd1498Szrj static _GLIBCXX17_CONSTEXPR const char_type* 43738fd1498Szrj find(const char_type* __s, size_t __n, const char_type& __a) 43838fd1498Szrj { 43938fd1498Szrj #if __cplusplus > 201402 44038fd1498Szrj if (__builtin_constant_p(__n) 44138fd1498Szrj && __builtin_constant_p(__a) 44238fd1498Szrj && __constant_char_array_p(__s, __n)) 44338fd1498Szrj return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 44438fd1498Szrj #endif 44538fd1498Szrj if (__n == 0) 44638fd1498Szrj return 0; 44738fd1498Szrj else 44838fd1498Szrj return wmemchr(__s, __a, __n); 44938fd1498Szrj } 45038fd1498Szrj 45138fd1498Szrj static char_type* 45238fd1498Szrj move(char_type* __s1, const char_type* __s2, size_t __n) 45338fd1498Szrj { 45438fd1498Szrj if (__n == 0) 45538fd1498Szrj return __s1; 45638fd1498Szrj return wmemmove(__s1, __s2, __n); 45738fd1498Szrj } 45838fd1498Szrj 45938fd1498Szrj static char_type* 46038fd1498Szrj copy(char_type* __s1, const char_type* __s2, size_t __n) 46138fd1498Szrj { 46238fd1498Szrj if (__n == 0) 46338fd1498Szrj return __s1; 46438fd1498Szrj return wmemcpy(__s1, __s2, __n); 46538fd1498Szrj } 46638fd1498Szrj 46738fd1498Szrj static char_type* 46838fd1498Szrj assign(char_type* __s, size_t __n, char_type __a) 46938fd1498Szrj { 47038fd1498Szrj if (__n == 0) 47138fd1498Szrj return __s; 47238fd1498Szrj return wmemset(__s, __a, __n); 47338fd1498Szrj } 47438fd1498Szrj 47538fd1498Szrj static _GLIBCXX_CONSTEXPR char_type 47638fd1498Szrj to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 47738fd1498Szrj { return char_type(__c); } 47838fd1498Szrj 47938fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 48038fd1498Szrj to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 48138fd1498Szrj { return int_type(__c); } 48238fd1498Szrj 48338fd1498Szrj static _GLIBCXX_CONSTEXPR bool 48438fd1498Szrj eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 48538fd1498Szrj { return __c1 == __c2; } 48638fd1498Szrj 48738fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 48838fd1498Szrj eof() _GLIBCXX_NOEXCEPT 48938fd1498Szrj { return static_cast<int_type>(WEOF); } 49038fd1498Szrj 49138fd1498Szrj static _GLIBCXX_CONSTEXPR int_type 49238fd1498Szrj not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 49338fd1498Szrj { return eq_int_type(__c, eof()) ? 0 : __c; } 49438fd1498Szrj }; 49538fd1498Szrj #endif //_GLIBCXX_USE_WCHAR_T 49638fd1498Szrj 49738fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 49838fd1498Szrj } // namespace 49938fd1498Szrj 50038fd1498Szrj #if ((__cplusplus >= 201103L) \ 50138fd1498Szrj && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 50238fd1498Szrj 50338fd1498Szrj #include <cstdint> 50438fd1498Szrj 50538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 50638fd1498Szrj { 50738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 50838fd1498Szrj 50938fd1498Szrj template<> 51038fd1498Szrj struct char_traits<char16_t> 51138fd1498Szrj { 51238fd1498Szrj typedef char16_t char_type; 51338fd1498Szrj typedef uint_least16_t int_type; 51438fd1498Szrj typedef streamoff off_type; 51538fd1498Szrj typedef u16streampos pos_type; 51638fd1498Szrj typedef mbstate_t state_type; 51738fd1498Szrj 51838fd1498Szrj static _GLIBCXX17_CONSTEXPR void 51938fd1498Szrj assign(char_type& __c1, const char_type& __c2) noexcept 52038fd1498Szrj { __c1 = __c2; } 52138fd1498Szrj 52238fd1498Szrj static constexpr bool 52338fd1498Szrj eq(const char_type& __c1, const char_type& __c2) noexcept 52438fd1498Szrj { return __c1 == __c2; } 52538fd1498Szrj 52638fd1498Szrj static constexpr bool 52738fd1498Szrj lt(const char_type& __c1, const char_type& __c2) noexcept 52838fd1498Szrj { return __c1 < __c2; } 52938fd1498Szrj 53038fd1498Szrj static _GLIBCXX17_CONSTEXPR int 53138fd1498Szrj compare(const char_type* __s1, const char_type* __s2, size_t __n) 53238fd1498Szrj { 53338fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 53438fd1498Szrj if (lt(__s1[__i], __s2[__i])) 53538fd1498Szrj return -1; 53638fd1498Szrj else if (lt(__s2[__i], __s1[__i])) 53738fd1498Szrj return 1; 53838fd1498Szrj return 0; 53938fd1498Szrj } 54038fd1498Szrj 54138fd1498Szrj static _GLIBCXX17_CONSTEXPR size_t 54238fd1498Szrj length(const char_type* __s) 54338fd1498Szrj { 54438fd1498Szrj size_t __i = 0; 54538fd1498Szrj while (!eq(__s[__i], char_type())) 54638fd1498Szrj ++__i; 54738fd1498Szrj return __i; 54838fd1498Szrj } 54938fd1498Szrj 55038fd1498Szrj static _GLIBCXX17_CONSTEXPR const char_type* 55138fd1498Szrj find(const char_type* __s, size_t __n, const char_type& __a) 55238fd1498Szrj { 55338fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 55438fd1498Szrj if (eq(__s[__i], __a)) 55538fd1498Szrj return __s + __i; 55638fd1498Szrj return 0; 55738fd1498Szrj } 55838fd1498Szrj 55938fd1498Szrj static char_type* 56038fd1498Szrj move(char_type* __s1, const char_type* __s2, size_t __n) 56138fd1498Szrj { 56238fd1498Szrj if (__n == 0) 56338fd1498Szrj return __s1; 56438fd1498Szrj return (static_cast<char_type*> 56538fd1498Szrj (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 56638fd1498Szrj } 56738fd1498Szrj 56838fd1498Szrj static char_type* 56938fd1498Szrj copy(char_type* __s1, const char_type* __s2, size_t __n) 57038fd1498Szrj { 57138fd1498Szrj if (__n == 0) 57238fd1498Szrj return __s1; 57338fd1498Szrj return (static_cast<char_type*> 57438fd1498Szrj (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 57538fd1498Szrj } 57638fd1498Szrj 57738fd1498Szrj static char_type* 57838fd1498Szrj assign(char_type* __s, size_t __n, char_type __a) 57938fd1498Szrj { 58038fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 58138fd1498Szrj assign(__s[__i], __a); 58238fd1498Szrj return __s; 58338fd1498Szrj } 58438fd1498Szrj 58538fd1498Szrj static constexpr char_type 58638fd1498Szrj to_char_type(const int_type& __c) noexcept 58738fd1498Szrj { return char_type(__c); } 58838fd1498Szrj 58938fd1498Szrj static constexpr int_type 59038fd1498Szrj to_int_type(const char_type& __c) noexcept 59138fd1498Szrj { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 59238fd1498Szrj 59338fd1498Szrj static constexpr bool 59438fd1498Szrj eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 59538fd1498Szrj { return __c1 == __c2; } 59638fd1498Szrj 59738fd1498Szrj static constexpr int_type 59838fd1498Szrj eof() noexcept 59938fd1498Szrj { return static_cast<int_type>(-1); } 60038fd1498Szrj 60138fd1498Szrj static constexpr int_type 60238fd1498Szrj not_eof(const int_type& __c) noexcept 60338fd1498Szrj { return eq_int_type(__c, eof()) ? 0 : __c; } 60438fd1498Szrj }; 60538fd1498Szrj 60638fd1498Szrj template<> 60738fd1498Szrj struct char_traits<char32_t> 60838fd1498Szrj { 60938fd1498Szrj typedef char32_t char_type; 61038fd1498Szrj typedef uint_least32_t int_type; 61138fd1498Szrj typedef streamoff off_type; 61238fd1498Szrj typedef u32streampos pos_type; 61338fd1498Szrj typedef mbstate_t state_type; 61438fd1498Szrj 61538fd1498Szrj static _GLIBCXX17_CONSTEXPR void 61638fd1498Szrj assign(char_type& __c1, const char_type& __c2) noexcept 61738fd1498Szrj { __c1 = __c2; } 61838fd1498Szrj 61938fd1498Szrj static constexpr bool 62038fd1498Szrj eq(const char_type& __c1, const char_type& __c2) noexcept 62138fd1498Szrj { return __c1 == __c2; } 62238fd1498Szrj 62338fd1498Szrj static constexpr bool 62438fd1498Szrj lt(const char_type& __c1, const char_type& __c2) noexcept 62538fd1498Szrj { return __c1 < __c2; } 62638fd1498Szrj 62738fd1498Szrj static _GLIBCXX17_CONSTEXPR int 62838fd1498Szrj compare(const char_type* __s1, const char_type* __s2, size_t __n) 62938fd1498Szrj { 63038fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 63138fd1498Szrj if (lt(__s1[__i], __s2[__i])) 63238fd1498Szrj return -1; 63338fd1498Szrj else if (lt(__s2[__i], __s1[__i])) 63438fd1498Szrj return 1; 63538fd1498Szrj return 0; 63638fd1498Szrj } 63738fd1498Szrj 63838fd1498Szrj static _GLIBCXX17_CONSTEXPR size_t 63938fd1498Szrj length(const char_type* __s) 64038fd1498Szrj { 64138fd1498Szrj size_t __i = 0; 64238fd1498Szrj while (!eq(__s[__i], char_type())) 64338fd1498Szrj ++__i; 64438fd1498Szrj return __i; 64538fd1498Szrj } 64638fd1498Szrj 64738fd1498Szrj static _GLIBCXX17_CONSTEXPR const char_type* 64838fd1498Szrj find(const char_type* __s, size_t __n, const char_type& __a) 64938fd1498Szrj { 65038fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 65138fd1498Szrj if (eq(__s[__i], __a)) 65238fd1498Szrj return __s + __i; 65338fd1498Szrj return 0; 65438fd1498Szrj } 65538fd1498Szrj 65638fd1498Szrj static char_type* 65738fd1498Szrj move(char_type* __s1, const char_type* __s2, size_t __n) 65838fd1498Szrj { 65938fd1498Szrj if (__n == 0) 66038fd1498Szrj return __s1; 66138fd1498Szrj return (static_cast<char_type*> 66238fd1498Szrj (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 66338fd1498Szrj } 66438fd1498Szrj 66538fd1498Szrj static char_type* 66638fd1498Szrj copy(char_type* __s1, const char_type* __s2, size_t __n) 66738fd1498Szrj { 66838fd1498Szrj if (__n == 0) 66938fd1498Szrj return __s1; 67038fd1498Szrj return (static_cast<char_type*> 67138fd1498Szrj (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 67238fd1498Szrj } 67338fd1498Szrj 67438fd1498Szrj static char_type* 67538fd1498Szrj assign(char_type* __s, size_t __n, char_type __a) 67638fd1498Szrj { 67738fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 67838fd1498Szrj assign(__s[__i], __a); 67938fd1498Szrj return __s; 68038fd1498Szrj } 68138fd1498Szrj 68238fd1498Szrj static constexpr char_type 68338fd1498Szrj to_char_type(const int_type& __c) noexcept 68438fd1498Szrj { return char_type(__c); } 68538fd1498Szrj 68638fd1498Szrj static constexpr int_type 68738fd1498Szrj to_int_type(const char_type& __c) noexcept 68838fd1498Szrj { return int_type(__c); } 68938fd1498Szrj 69038fd1498Szrj static constexpr bool 69138fd1498Szrj eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 69238fd1498Szrj { return __c1 == __c2; } 69338fd1498Szrj 69438fd1498Szrj static constexpr int_type 69538fd1498Szrj eof() noexcept 69638fd1498Szrj { return static_cast<int_type>(-1); } 69738fd1498Szrj 69838fd1498Szrj static constexpr int_type 69938fd1498Szrj not_eof(const int_type& __c) noexcept 70038fd1498Szrj { return eq_int_type(__c, eof()) ? 0 : __c; } 70138fd1498Szrj }; 70238fd1498Szrj 70338fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 70438fd1498Szrj } // namespace 70538fd1498Szrj 70638fd1498Szrj #endif 70738fd1498Szrj 70838fd1498Szrj #endif // _CHAR_TRAITS_H 709