libstdc++
|
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/char_traits.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{string} 00028 */ 00029 00030 // 00031 // ISO C++ 14882: 21 Strings library 00032 // 00033 00034 #ifndef _CHAR_TRAITS_H 00035 #define _CHAR_TRAITS_H 1 00036 00037 #pragma GCC system_header 00038 00039 #include <bits/stl_algobase.h> // std::copy, std::fill_n 00040 #include <bits/postypes.h> // For streampos 00041 #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 00042 00043 #ifndef _GLIBCXX_ALWAYS_INLINE 00044 # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 00045 #endif 00046 00047 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00048 { 00049 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00050 00051 /** 00052 * @brief Mapping from character type to associated types. 00053 * 00054 * @note This is an implementation class for the generic version 00055 * of char_traits. It defines int_type, off_type, pos_type, and 00056 * state_type. By default these are unsigned long, streamoff, 00057 * streampos, and mbstate_t. Users who need a different set of 00058 * types, but who don't need to change the definitions of any function 00059 * defined in char_traits, can specialize __gnu_cxx::_Char_types 00060 * while leaving __gnu_cxx::char_traits alone. */ 00061 template<typename _CharT> 00062 struct _Char_types 00063 { 00064 typedef unsigned long int_type; 00065 typedef std::streampos pos_type; 00066 typedef std::streamoff off_type; 00067 typedef std::mbstate_t state_type; 00068 }; 00069 00070 00071 /** 00072 * @brief Base class used to implement std::char_traits. 00073 * 00074 * @note For any given actual character type, this definition is 00075 * probably wrong. (Most of the member functions are likely to be 00076 * right, but the int_type and state_type typedefs, and the eof() 00077 * member function, are likely to be wrong.) The reason this class 00078 * exists is so users can specialize it. Classes in namespace std 00079 * may not be specialized for fundamental types, but classes in 00080 * namespace __gnu_cxx may be. 00081 * 00082 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00083 * for advice on how to make use of this class for @a unusual character 00084 * types. Also, check out include/ext/pod_char_traits.h. 00085 */ 00086 template<typename _CharT> 00087 struct char_traits 00088 { 00089 typedef _CharT char_type; 00090 typedef typename _Char_types<_CharT>::int_type int_type; 00091 typedef typename _Char_types<_CharT>::pos_type pos_type; 00092 typedef typename _Char_types<_CharT>::off_type off_type; 00093 typedef typename _Char_types<_CharT>::state_type state_type; 00094 00095 static _GLIBCXX14_CONSTEXPR void 00096 assign(char_type& __c1, const char_type& __c2) 00097 { __c1 = __c2; } 00098 00099 static _GLIBCXX_CONSTEXPR bool 00100 eq(const char_type& __c1, const char_type& __c2) 00101 { return __c1 == __c2; } 00102 00103 static _GLIBCXX_CONSTEXPR bool 00104 lt(const char_type& __c1, const char_type& __c2) 00105 { return __c1 < __c2; } 00106 00107 static _GLIBCXX14_CONSTEXPR int 00108 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00109 00110 static _GLIBCXX14_CONSTEXPR std::size_t 00111 length(const char_type* __s); 00112 00113 static _GLIBCXX14_CONSTEXPR const char_type* 00114 find(const char_type* __s, std::size_t __n, const char_type& __a); 00115 00116 static char_type* 00117 move(char_type* __s1, const char_type* __s2, std::size_t __n); 00118 00119 static char_type* 00120 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 00121 00122 static char_type* 00123 assign(char_type* __s, std::size_t __n, char_type __a); 00124 00125 static _GLIBCXX_CONSTEXPR char_type 00126 to_char_type(const int_type& __c) 00127 { return static_cast<char_type>(__c); } 00128 00129 static _GLIBCXX_CONSTEXPR int_type 00130 to_int_type(const char_type& __c) 00131 { return static_cast<int_type>(__c); } 00132 00133 static _GLIBCXX_CONSTEXPR bool 00134 eq_int_type(const int_type& __c1, const int_type& __c2) 00135 { return __c1 == __c2; } 00136 00137 static _GLIBCXX_CONSTEXPR int_type 00138 eof() 00139 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00140 00141 static _GLIBCXX_CONSTEXPR int_type 00142 not_eof(const int_type& __c) 00143 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 00144 }; 00145 00146 template<typename _CharT> 00147 _GLIBCXX14_CONSTEXPR int 00148 char_traits<_CharT>:: 00149 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00150 { 00151 for (std::size_t __i = 0; __i < __n; ++__i) 00152 if (lt(__s1[__i], __s2[__i])) 00153 return -1; 00154 else if (lt(__s2[__i], __s1[__i])) 00155 return 1; 00156 return 0; 00157 } 00158 00159 template<typename _CharT> 00160 _GLIBCXX14_CONSTEXPR std::size_t 00161 char_traits<_CharT>:: 00162 length(const char_type* __p) 00163 { 00164 std::size_t __i = 0; 00165 while (!eq(__p[__i], char_type())) 00166 ++__i; 00167 return __i; 00168 } 00169 00170 template<typename _CharT> 00171 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 00172 char_traits<_CharT>:: 00173 find(const char_type* __s, std::size_t __n, const char_type& __a) 00174 { 00175 for (std::size_t __i = 0; __i < __n; ++__i) 00176 if (eq(__s[__i], __a)) 00177 return __s + __i; 00178 return 0; 00179 } 00180 00181 template<typename _CharT> 00182 typename char_traits<_CharT>::char_type* 00183 char_traits<_CharT>:: 00184 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00185 { 00186 if (__n == 0) 00187 return __s1; 00188 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00189 __n * sizeof(char_type))); 00190 } 00191 00192 template<typename _CharT> 00193 typename char_traits<_CharT>::char_type* 00194 char_traits<_CharT>:: 00195 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00196 { 00197 // NB: Inline std::copy so no recursive dependencies. 00198 std::copy(__s2, __s2 + __n, __s1); 00199 return __s1; 00200 } 00201 00202 template<typename _CharT> 00203 typename char_traits<_CharT>::char_type* 00204 char_traits<_CharT>:: 00205 assign(char_type* __s, std::size_t __n, char_type __a) 00206 { 00207 // NB: Inline std::fill_n so no recursive dependencies. 00208 std::fill_n(__s, __n, __a); 00209 return __s; 00210 } 00211 00212 _GLIBCXX_END_NAMESPACE_VERSION 00213 } // namespace 00214 00215 namespace std _GLIBCXX_VISIBILITY(default) 00216 { 00217 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00218 00219 #if __cplusplus >= 201703L 00220 #define __cpp_lib_constexpr_char_traits 201611 00221 00222 /** 00223 * @brief Determine whether the characters of a NULL-terminated 00224 * string are known at compile time. 00225 * @param __s The string. 00226 * 00227 * Assumes that _CharT is a built-in character type. 00228 */ 00229 template<typename _CharT> 00230 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00231 __constant_string_p(const _CharT* __s) 00232 { 00233 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 00234 (void) __s; 00235 // In constexpr contexts all strings should be constant. 00236 return __builtin_is_constant_evaluated(); 00237 #else 00238 while (__builtin_constant_p(*__s) && *__s) 00239 __s++; 00240 return __builtin_constant_p(*__s); 00241 #endif 00242 } 00243 00244 /** 00245 * @brief Determine whether the characters of a character array are 00246 * known at compile time. 00247 * @param __a The character array. 00248 * @param __n Number of characters. 00249 * 00250 * Assumes that _CharT is a built-in character type. 00251 */ 00252 template<typename _CharT> 00253 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00254 __constant_char_array_p(const _CharT* __a, size_t __n) 00255 { 00256 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 00257 (void) __a; 00258 (void) __n; 00259 // In constexpr contexts all character arrays should be constant. 00260 return __builtin_is_constant_evaluated(); 00261 #else 00262 size_t __i = 0; 00263 while (__i < __n && __builtin_constant_p(__a[__i])) 00264 __i++; 00265 return __i == __n; 00266 #endif 00267 } 00268 #endif 00269 00270 // 21.1 00271 /** 00272 * @brief Basis for explicit traits specializations. 00273 * 00274 * @note For any given actual character type, this definition is 00275 * probably wrong. Since this is just a thin wrapper around 00276 * __gnu_cxx::char_traits, it is possible to achieve a more 00277 * appropriate definition by specializing __gnu_cxx::char_traits. 00278 * 00279 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00280 * for advice on how to make use of this class for @a unusual character 00281 * types. Also, check out include/ext/pod_char_traits.h. 00282 */ 00283 template<class _CharT> 00284 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00285 { }; 00286 00287 00288 /// 21.1.3.1 char_traits specializations 00289 template<> 00290 struct char_traits<char> 00291 { 00292 typedef char char_type; 00293 typedef int int_type; 00294 typedef streampos pos_type; 00295 typedef streamoff off_type; 00296 typedef mbstate_t state_type; 00297 00298 static _GLIBCXX17_CONSTEXPR void 00299 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00300 { __c1 = __c2; } 00301 00302 static _GLIBCXX_CONSTEXPR bool 00303 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00304 { return __c1 == __c2; } 00305 00306 static _GLIBCXX_CONSTEXPR bool 00307 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00308 { 00309 // LWG 467. 00310 return (static_cast<unsigned char>(__c1) 00311 < static_cast<unsigned char>(__c2)); 00312 } 00313 00314 static _GLIBCXX17_CONSTEXPR int 00315 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00316 { 00317 if (__n == 0) 00318 return 0; 00319 #if __cplusplus >= 201703L 00320 if (__builtin_constant_p(__n) 00321 && __constant_char_array_p(__s1, __n) 00322 && __constant_char_array_p(__s2, __n)) 00323 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00324 #endif 00325 return __builtin_memcmp(__s1, __s2, __n); 00326 } 00327 00328 static _GLIBCXX17_CONSTEXPR size_t 00329 length(const char_type* __s) 00330 { 00331 #if __cplusplus >= 201703L 00332 if (__constant_string_p(__s)) 00333 return __gnu_cxx::char_traits<char_type>::length(__s); 00334 #endif 00335 return __builtin_strlen(__s); 00336 } 00337 00338 static _GLIBCXX17_CONSTEXPR const char_type* 00339 find(const char_type* __s, size_t __n, const char_type& __a) 00340 { 00341 if (__n == 0) 00342 return 0; 00343 #if __cplusplus >= 201703L 00344 if (__builtin_constant_p(__n) 00345 && __builtin_constant_p(__a) 00346 && __constant_char_array_p(__s, __n)) 00347 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00348 #endif 00349 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00350 } 00351 00352 static char_type* 00353 move(char_type* __s1, const char_type* __s2, size_t __n) 00354 { 00355 if (__n == 0) 00356 return __s1; 00357 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00358 } 00359 00360 static char_type* 00361 copy(char_type* __s1, const char_type* __s2, size_t __n) 00362 { 00363 if (__n == 0) 00364 return __s1; 00365 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00366 } 00367 00368 static char_type* 00369 assign(char_type* __s, size_t __n, char_type __a) 00370 { 00371 if (__n == 0) 00372 return __s; 00373 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00374 } 00375 00376 static _GLIBCXX_CONSTEXPR char_type 00377 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00378 { return static_cast<char_type>(__c); } 00379 00380 // To keep both the byte 0xff and the eof symbol 0xffffffff 00381 // from ending up as 0xffffffff. 00382 static _GLIBCXX_CONSTEXPR int_type 00383 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00384 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00385 00386 static _GLIBCXX_CONSTEXPR bool 00387 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00388 { return __c1 == __c2; } 00389 00390 static _GLIBCXX_CONSTEXPR int_type 00391 eof() _GLIBCXX_NOEXCEPT 00392 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00393 00394 static _GLIBCXX_CONSTEXPR int_type 00395 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00396 { return (__c == eof()) ? 0 : __c; } 00397 }; 00398 00399 00400 #ifdef _GLIBCXX_USE_WCHAR_T 00401 /// 21.1.3.2 char_traits specializations 00402 template<> 00403 struct char_traits<wchar_t> 00404 { 00405 typedef wchar_t char_type; 00406 typedef wint_t int_type; 00407 typedef streamoff off_type; 00408 typedef wstreampos pos_type; 00409 typedef mbstate_t state_type; 00410 00411 static _GLIBCXX17_CONSTEXPR void 00412 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00413 { __c1 = __c2; } 00414 00415 static _GLIBCXX_CONSTEXPR bool 00416 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00417 { return __c1 == __c2; } 00418 00419 static _GLIBCXX_CONSTEXPR bool 00420 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00421 { return __c1 < __c2; } 00422 00423 static _GLIBCXX17_CONSTEXPR int 00424 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00425 { 00426 if (__n == 0) 00427 return 0; 00428 #if __cplusplus >= 201703L 00429 if (__builtin_constant_p(__n) 00430 && __constant_char_array_p(__s1, __n) 00431 && __constant_char_array_p(__s2, __n)) 00432 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00433 #endif 00434 return wmemcmp(__s1, __s2, __n); 00435 } 00436 00437 static _GLIBCXX17_CONSTEXPR size_t 00438 length(const char_type* __s) 00439 { 00440 #if __cplusplus >= 201703L 00441 if (__constant_string_p(__s)) 00442 return __gnu_cxx::char_traits<char_type>::length(__s); 00443 #endif 00444 return wcslen(__s); 00445 } 00446 00447 static _GLIBCXX17_CONSTEXPR const char_type* 00448 find(const char_type* __s, size_t __n, const char_type& __a) 00449 { 00450 if (__n == 0) 00451 return 0; 00452 #if __cplusplus >= 201703L 00453 if (__builtin_constant_p(__n) 00454 && __builtin_constant_p(__a) 00455 && __constant_char_array_p(__s, __n)) 00456 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00457 #endif 00458 return wmemchr(__s, __a, __n); 00459 } 00460 00461 static char_type* 00462 move(char_type* __s1, const char_type* __s2, size_t __n) 00463 { 00464 if (__n == 0) 00465 return __s1; 00466 return wmemmove(__s1, __s2, __n); 00467 } 00468 00469 static char_type* 00470 copy(char_type* __s1, const char_type* __s2, size_t __n) 00471 { 00472 if (__n == 0) 00473 return __s1; 00474 return wmemcpy(__s1, __s2, __n); 00475 } 00476 00477 static char_type* 00478 assign(char_type* __s, size_t __n, char_type __a) 00479 { 00480 if (__n == 0) 00481 return __s; 00482 return wmemset(__s, __a, __n); 00483 } 00484 00485 static _GLIBCXX_CONSTEXPR char_type 00486 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00487 { return char_type(__c); } 00488 00489 static _GLIBCXX_CONSTEXPR int_type 00490 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00491 { return int_type(__c); } 00492 00493 static _GLIBCXX_CONSTEXPR bool 00494 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00495 { return __c1 == __c2; } 00496 00497 static _GLIBCXX_CONSTEXPR int_type 00498 eof() _GLIBCXX_NOEXCEPT 00499 { return static_cast<int_type>(WEOF); } 00500 00501 static _GLIBCXX_CONSTEXPR int_type 00502 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00503 { return eq_int_type(__c, eof()) ? 0 : __c; } 00504 }; 00505 #endif //_GLIBCXX_USE_WCHAR_T 00506 00507 #ifdef _GLIBCXX_USE_CHAR8_T 00508 template<> 00509 struct char_traits<char8_t> 00510 { 00511 typedef char8_t char_type; 00512 typedef unsigned int int_type; 00513 typedef u8streampos pos_type; 00514 typedef streamoff off_type; 00515 typedef mbstate_t state_type; 00516 00517 static _GLIBCXX17_CONSTEXPR void 00518 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00519 { __c1 = __c2; } 00520 00521 static _GLIBCXX_CONSTEXPR bool 00522 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00523 { return __c1 == __c2; } 00524 00525 static _GLIBCXX_CONSTEXPR bool 00526 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00527 { return __c1 < __c2; } 00528 00529 static _GLIBCXX17_CONSTEXPR int 00530 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00531 { 00532 if (__n == 0) 00533 return 0; 00534 #if __cplusplus > 201402 00535 if (__builtin_constant_p(__n) 00536 && __constant_char_array_p(__s1, __n) 00537 && __constant_char_array_p(__s2, __n)) 00538 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00539 #endif 00540 return __builtin_memcmp(__s1, __s2, __n); 00541 } 00542 00543 static _GLIBCXX17_CONSTEXPR size_t 00544 length(const char_type* __s) 00545 { 00546 #if __cplusplus > 201402 00547 if (__constant_string_p(__s)) 00548 return __gnu_cxx::char_traits<char_type>::length(__s); 00549 #endif 00550 size_t __i = 0; 00551 while (!eq(__s[__i], char_type())) 00552 ++__i; 00553 return __i; 00554 } 00555 00556 static _GLIBCXX17_CONSTEXPR const char_type* 00557 find(const char_type* __s, size_t __n, const char_type& __a) 00558 { 00559 if (__n == 0) 00560 return 0; 00561 #if __cplusplus > 201402 00562 if (__builtin_constant_p(__n) 00563 && __builtin_constant_p(__a) 00564 && __constant_char_array_p(__s, __n)) 00565 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00566 #endif 00567 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00568 } 00569 00570 static char_type* 00571 move(char_type* __s1, const char_type* __s2, size_t __n) 00572 { 00573 if (__n == 0) 00574 return __s1; 00575 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00576 } 00577 00578 static char_type* 00579 copy(char_type* __s1, const char_type* __s2, size_t __n) 00580 { 00581 if (__n == 0) 00582 return __s1; 00583 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00584 } 00585 00586 static char_type* 00587 assign(char_type* __s, size_t __n, char_type __a) 00588 { 00589 if (__n == 0) 00590 return __s; 00591 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00592 } 00593 00594 static _GLIBCXX_CONSTEXPR char_type 00595 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00596 { return char_type(__c); } 00597 00598 static _GLIBCXX_CONSTEXPR int_type 00599 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00600 { return int_type(__c); } 00601 00602 static _GLIBCXX_CONSTEXPR bool 00603 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00604 { return __c1 == __c2; } 00605 00606 static _GLIBCXX_CONSTEXPR int_type 00607 eof() _GLIBCXX_NOEXCEPT 00608 { return static_cast<int_type>(-1); } 00609 00610 static _GLIBCXX_CONSTEXPR int_type 00611 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00612 { return eq_int_type(__c, eof()) ? 0 : __c; } 00613 }; 00614 #endif //_GLIBCXX_USE_CHAR8_T 00615 00616 _GLIBCXX_END_NAMESPACE_VERSION 00617 } // namespace 00618 00619 #if __cplusplus >= 201103L 00620 00621 #include <cstdint> 00622 00623 namespace std _GLIBCXX_VISIBILITY(default) 00624 { 00625 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00626 00627 template<> 00628 struct char_traits<char16_t> 00629 { 00630 typedef char16_t char_type; 00631 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 00632 typedef uint_least16_t int_type; 00633 #elif defined __UINT_LEAST16_TYPE__ 00634 typedef __UINT_LEAST16_TYPE__ int_type; 00635 #else 00636 typedef make_unsigned<char16_t>::type int_type; 00637 #endif 00638 typedef streamoff off_type; 00639 typedef u16streampos pos_type; 00640 typedef mbstate_t state_type; 00641 00642 static _GLIBCXX17_CONSTEXPR void 00643 assign(char_type& __c1, const char_type& __c2) noexcept 00644 { __c1 = __c2; } 00645 00646 static constexpr bool 00647 eq(const char_type& __c1, const char_type& __c2) noexcept 00648 { return __c1 == __c2; } 00649 00650 static constexpr bool 00651 lt(const char_type& __c1, const char_type& __c2) noexcept 00652 { return __c1 < __c2; } 00653 00654 static _GLIBCXX17_CONSTEXPR int 00655 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00656 { 00657 for (size_t __i = 0; __i < __n; ++__i) 00658 if (lt(__s1[__i], __s2[__i])) 00659 return -1; 00660 else if (lt(__s2[__i], __s1[__i])) 00661 return 1; 00662 return 0; 00663 } 00664 00665 static _GLIBCXX17_CONSTEXPR size_t 00666 length(const char_type* __s) 00667 { 00668 size_t __i = 0; 00669 while (!eq(__s[__i], char_type())) 00670 ++__i; 00671 return __i; 00672 } 00673 00674 static _GLIBCXX17_CONSTEXPR const char_type* 00675 find(const char_type* __s, size_t __n, const char_type& __a) 00676 { 00677 for (size_t __i = 0; __i < __n; ++__i) 00678 if (eq(__s[__i], __a)) 00679 return __s + __i; 00680 return 0; 00681 } 00682 00683 static char_type* 00684 move(char_type* __s1, const char_type* __s2, size_t __n) 00685 { 00686 if (__n == 0) 00687 return __s1; 00688 return (static_cast<char_type*> 00689 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00690 } 00691 00692 static char_type* 00693 copy(char_type* __s1, const char_type* __s2, size_t __n) 00694 { 00695 if (__n == 0) 00696 return __s1; 00697 return (static_cast<char_type*> 00698 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00699 } 00700 00701 static char_type* 00702 assign(char_type* __s, size_t __n, char_type __a) 00703 { 00704 for (size_t __i = 0; __i < __n; ++__i) 00705 assign(__s[__i], __a); 00706 return __s; 00707 } 00708 00709 static constexpr char_type 00710 to_char_type(const int_type& __c) noexcept 00711 { return char_type(__c); } 00712 00713 static constexpr int_type 00714 to_int_type(const char_type& __c) noexcept 00715 { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 00716 00717 static constexpr bool 00718 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00719 { return __c1 == __c2; } 00720 00721 static constexpr int_type 00722 eof() noexcept 00723 { return static_cast<int_type>(-1); } 00724 00725 static constexpr int_type 00726 not_eof(const int_type& __c) noexcept 00727 { return eq_int_type(__c, eof()) ? 0 : __c; } 00728 }; 00729 00730 template<> 00731 struct char_traits<char32_t> 00732 { 00733 typedef char32_t char_type; 00734 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 00735 typedef uint_least32_t int_type; 00736 #elif defined __UINT_LEAST32_TYPE__ 00737 typedef __UINT_LEAST32_TYPE__ int_type; 00738 #else 00739 typedef make_unsigned<char32_t>::type int_type; 00740 #endif 00741 typedef streamoff off_type; 00742 typedef u32streampos pos_type; 00743 typedef mbstate_t state_type; 00744 00745 static _GLIBCXX17_CONSTEXPR void 00746 assign(char_type& __c1, const char_type& __c2) noexcept 00747 { __c1 = __c2; } 00748 00749 static constexpr bool 00750 eq(const char_type& __c1, const char_type& __c2) noexcept 00751 { return __c1 == __c2; } 00752 00753 static constexpr bool 00754 lt(const char_type& __c1, const char_type& __c2) noexcept 00755 { return __c1 < __c2; } 00756 00757 static _GLIBCXX17_CONSTEXPR int 00758 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00759 { 00760 for (size_t __i = 0; __i < __n; ++__i) 00761 if (lt(__s1[__i], __s2[__i])) 00762 return -1; 00763 else if (lt(__s2[__i], __s1[__i])) 00764 return 1; 00765 return 0; 00766 } 00767 00768 static _GLIBCXX17_CONSTEXPR size_t 00769 length(const char_type* __s) 00770 { 00771 size_t __i = 0; 00772 while (!eq(__s[__i], char_type())) 00773 ++__i; 00774 return __i; 00775 } 00776 00777 static _GLIBCXX17_CONSTEXPR const char_type* 00778 find(const char_type* __s, size_t __n, const char_type& __a) 00779 { 00780 for (size_t __i = 0; __i < __n; ++__i) 00781 if (eq(__s[__i], __a)) 00782 return __s + __i; 00783 return 0; 00784 } 00785 00786 static char_type* 00787 move(char_type* __s1, const char_type* __s2, size_t __n) 00788 { 00789 if (__n == 0) 00790 return __s1; 00791 return (static_cast<char_type*> 00792 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00793 } 00794 00795 static char_type* 00796 copy(char_type* __s1, const char_type* __s2, size_t __n) 00797 { 00798 if (__n == 0) 00799 return __s1; 00800 return (static_cast<char_type*> 00801 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00802 } 00803 00804 static char_type* 00805 assign(char_type* __s, size_t __n, char_type __a) 00806 { 00807 for (size_t __i = 0; __i < __n; ++__i) 00808 assign(__s[__i], __a); 00809 return __s; 00810 } 00811 00812 static constexpr char_type 00813 to_char_type(const int_type& __c) noexcept 00814 { return char_type(__c); } 00815 00816 static constexpr int_type 00817 to_int_type(const char_type& __c) noexcept 00818 { return int_type(__c); } 00819 00820 static constexpr bool 00821 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00822 { return __c1 == __c2; } 00823 00824 static constexpr int_type 00825 eof() noexcept 00826 { return static_cast<int_type>(-1); } 00827 00828 static constexpr int_type 00829 not_eof(const int_type& __c) noexcept 00830 { return eq_int_type(__c, eof()) ? 0 : __c; } 00831 }; 00832 00833 _GLIBCXX_END_NAMESPACE_VERSION 00834 } // namespace 00835 00836 #endif // C++11 00837 00838 #endif // _CHAR_TRAITS_H