1 // Character Traits for use by standard string and iostream -*- C++ -*- 2 3 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file bits/char_traits.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{string} 28 */ 29 30 // 31 // ISO C++ 14882: 21 Strings library 32 // 33 34 #ifndef _CHAR_TRAITS_H 35 #define _CHAR_TRAITS_H 1 36 37 #pragma GCC system_header 38 39 #include <bits/stl_algobase.h> // std::copy, std::fill_n 40 #include <bits/postypes.h> // For streampos 41 #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 42 43 #ifndef _GLIBCXX_ALWAYS_INLINE 44 # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 45 #endif 46 47 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 48 { 49 _GLIBCXX_BEGIN_NAMESPACE_VERSION 50 51 /** 52 * @brief Mapping from character type to associated types. 53 * 54 * @note This is an implementation class for the generic version 55 * of char_traits. It defines int_type, off_type, pos_type, and 56 * state_type. By default these are unsigned long, streamoff, 57 * streampos, and mbstate_t. Users who need a different set of 58 * types, but who don't need to change the definitions of any function 59 * defined in char_traits, can specialize __gnu_cxx::_Char_types 60 * while leaving __gnu_cxx::char_traits alone. */ 61 template<typename _CharT> 62 struct _Char_types 63 { 64 typedef unsigned long int_type; 65 typedef std::streampos pos_type; 66 typedef std::streamoff off_type; 67 typedef std::mbstate_t state_type; 68 }; 69 70 71 /** 72 * @brief Base class used to implement std::char_traits. 73 * 74 * @note For any given actual character type, this definition is 75 * probably wrong. (Most of the member functions are likely to be 76 * right, but the int_type and state_type typedefs, and the eof() 77 * member function, are likely to be wrong.) The reason this class 78 * exists is so users can specialize it. Classes in namespace std 79 * may not be specialized for fundamental types, but classes in 80 * namespace __gnu_cxx may be. 81 * 82 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 83 * for advice on how to make use of this class for @a unusual character 84 * types. Also, check out include/ext/pod_char_traits.h. 85 */ 86 template<typename _CharT> 87 struct char_traits 88 { 89 typedef _CharT char_type; 90 typedef typename _Char_types<_CharT>::int_type int_type; 91 typedef typename _Char_types<_CharT>::pos_type pos_type; 92 typedef typename _Char_types<_CharT>::off_type off_type; 93 typedef typename _Char_types<_CharT>::state_type state_type; 94 95 static _GLIBCXX14_CONSTEXPR void 96 assign(char_type& __c1, const char_type& __c2) 97 { __c1 = __c2; } 98 99 static _GLIBCXX_CONSTEXPR bool 100 eq(const char_type& __c1, const char_type& __c2) 101 { return __c1 == __c2; } 102 103 static _GLIBCXX_CONSTEXPR bool 104 lt(const char_type& __c1, const char_type& __c2) 105 { return __c1 < __c2; } 106 107 static _GLIBCXX14_CONSTEXPR int 108 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 109 110 static _GLIBCXX14_CONSTEXPR std::size_t 111 length(const char_type* __s); 112 113 static _GLIBCXX14_CONSTEXPR const char_type* 114 find(const char_type* __s, std::size_t __n, const char_type& __a); 115 116 static char_type* 117 move(char_type* __s1, const char_type* __s2, std::size_t __n); 118 119 static char_type* 120 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 121 122 static char_type* 123 assign(char_type* __s, std::size_t __n, char_type __a); 124 125 static _GLIBCXX_CONSTEXPR char_type 126 to_char_type(const int_type& __c) 127 { return static_cast<char_type>(__c); } 128 129 static _GLIBCXX_CONSTEXPR int_type 130 to_int_type(const char_type& __c) 131 { return static_cast<int_type>(__c); } 132 133 static _GLIBCXX_CONSTEXPR bool 134 eq_int_type(const int_type& __c1, const int_type& __c2) 135 { return __c1 == __c2; } 136 137 static _GLIBCXX_CONSTEXPR int_type 138 eof() 139 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 140 141 static _GLIBCXX_CONSTEXPR int_type 142 not_eof(const int_type& __c) 143 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 144 }; 145 146 template<typename _CharT> 147 _GLIBCXX14_CONSTEXPR int 148 char_traits<_CharT>:: 149 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 150 { 151 for (std::size_t __i = 0; __i < __n; ++__i) 152 if (lt(__s1[__i], __s2[__i])) 153 return -1; 154 else if (lt(__s2[__i], __s1[__i])) 155 return 1; 156 return 0; 157 } 158 159 template<typename _CharT> 160 _GLIBCXX14_CONSTEXPR std::size_t 161 char_traits<_CharT>:: 162 length(const char_type* __p) 163 { 164 std::size_t __i = 0; 165 while (!eq(__p[__i], char_type())) 166 ++__i; 167 return __i; 168 } 169 170 template<typename _CharT> 171 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 172 char_traits<_CharT>:: 173 find(const char_type* __s, std::size_t __n, const char_type& __a) 174 { 175 for (std::size_t __i = 0; __i < __n; ++__i) 176 if (eq(__s[__i], __a)) 177 return __s + __i; 178 return 0; 179 } 180 181 template<typename _CharT> 182 typename char_traits<_CharT>::char_type* 183 char_traits<_CharT>:: 184 move(char_type* __s1, const char_type* __s2, std::size_t __n) 185 { 186 if (__n == 0) 187 return __s1; 188 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 189 __n * sizeof(char_type))); 190 } 191 192 template<typename _CharT> 193 typename char_traits<_CharT>::char_type* 194 char_traits<_CharT>:: 195 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 196 { 197 // NB: Inline std::copy so no recursive dependencies. 198 std::copy(__s2, __s2 + __n, __s1); 199 return __s1; 200 } 201 202 template<typename _CharT> 203 typename char_traits<_CharT>::char_type* 204 char_traits<_CharT>:: 205 assign(char_type* __s, std::size_t __n, char_type __a) 206 { 207 // NB: Inline std::fill_n so no recursive dependencies. 208 std::fill_n(__s, __n, __a); 209 return __s; 210 } 211 212 _GLIBCXX_END_NAMESPACE_VERSION 213 } // namespace 214 215 namespace std _GLIBCXX_VISIBILITY(default) 216 { 217 _GLIBCXX_BEGIN_NAMESPACE_VERSION 218 219 #if __cplusplus >= 201703L 220 #define __cpp_lib_constexpr_char_traits 201611 221 222 /** 223 * @brief Determine whether the characters of a NULL-terminated 224 * string are known at compile time. 225 * @param __s The string. 226 * 227 * Assumes that _CharT is a built-in character type. 228 */ 229 template<typename _CharT> 230 static _GLIBCXX_ALWAYS_INLINE constexpr bool 231 __constant_string_p(const _CharT* __s) 232 { 233 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 234 (void) __s; 235 // In constexpr contexts all strings should be constant. 236 return __builtin_is_constant_evaluated(); 237 #else 238 while (__builtin_constant_p(*__s) && *__s) 239 __s++; 240 return __builtin_constant_p(*__s); 241 #endif 242 } 243 244 /** 245 * @brief Determine whether the characters of a character array are 246 * known at compile time. 247 * @param __a The character array. 248 * @param __n Number of characters. 249 * 250 * Assumes that _CharT is a built-in character type. 251 */ 252 template<typename _CharT> 253 static _GLIBCXX_ALWAYS_INLINE constexpr bool 254 __constant_char_array_p(const _CharT* __a, size_t __n) 255 { 256 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 257 (void) __a; 258 (void) __n; 259 // In constexpr contexts all character arrays should be constant. 260 return __builtin_is_constant_evaluated(); 261 #else 262 size_t __i = 0; 263 while (__i < __n && __builtin_constant_p(__a[__i])) 264 __i++; 265 return __i == __n; 266 #endif 267 } 268 #endif 269 270 // 21.1 271 /** 272 * @brief Basis for explicit traits specializations. 273 * 274 * @note For any given actual character type, this definition is 275 * probably wrong. Since this is just a thin wrapper around 276 * __gnu_cxx::char_traits, it is possible to achieve a more 277 * appropriate definition by specializing __gnu_cxx::char_traits. 278 * 279 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 280 * for advice on how to make use of this class for @a unusual character 281 * types. Also, check out include/ext/pod_char_traits.h. 282 */ 283 template<class _CharT> 284 struct char_traits : public __gnu_cxx::char_traits<_CharT> 285 { }; 286 287 288 /// 21.1.3.1 char_traits specializations 289 template<> 290 struct char_traits<char> 291 { 292 typedef char char_type; 293 typedef int int_type; 294 typedef streampos pos_type; 295 typedef streamoff off_type; 296 typedef mbstate_t state_type; 297 298 static _GLIBCXX17_CONSTEXPR void 299 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 300 { __c1 = __c2; } 301 302 static _GLIBCXX_CONSTEXPR bool 303 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 304 { return __c1 == __c2; } 305 306 static _GLIBCXX_CONSTEXPR bool 307 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 308 { 309 // LWG 467. 310 return (static_cast<unsigned char>(__c1) 311 < static_cast<unsigned char>(__c2)); 312 } 313 314 static _GLIBCXX17_CONSTEXPR int 315 compare(const char_type* __s1, const char_type* __s2, size_t __n) 316 { 317 if (__n == 0) 318 return 0; 319 #if __cplusplus >= 201703L 320 if (__builtin_constant_p(__n) 321 && __constant_char_array_p(__s1, __n) 322 && __constant_char_array_p(__s2, __n)) 323 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 324 #endif 325 return __builtin_memcmp(__s1, __s2, __n); 326 } 327 328 static _GLIBCXX17_CONSTEXPR size_t 329 length(const char_type* __s) 330 { 331 #if __cplusplus >= 201703L 332 if (__constant_string_p(__s)) 333 return __gnu_cxx::char_traits<char_type>::length(__s); 334 #endif 335 return __builtin_strlen(__s); 336 } 337 338 static _GLIBCXX17_CONSTEXPR const char_type* 339 find(const char_type* __s, size_t __n, const char_type& __a) 340 { 341 if (__n == 0) 342 return 0; 343 #if __cplusplus >= 201703L 344 if (__builtin_constant_p(__n) 345 && __builtin_constant_p(__a) 346 && __constant_char_array_p(__s, __n)) 347 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 348 #endif 349 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 350 } 351 352 static char_type* 353 move(char_type* __s1, const char_type* __s2, size_t __n) 354 { 355 if (__n == 0) 356 return __s1; 357 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 358 } 359 360 static char_type* 361 copy(char_type* __s1, const char_type* __s2, size_t __n) 362 { 363 if (__n == 0) 364 return __s1; 365 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 366 } 367 368 static char_type* 369 assign(char_type* __s, size_t __n, char_type __a) 370 { 371 if (__n == 0) 372 return __s; 373 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 374 } 375 376 static _GLIBCXX_CONSTEXPR char_type 377 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 378 { return static_cast<char_type>(__c); } 379 380 // To keep both the byte 0xff and the eof symbol 0xffffffff 381 // from ending up as 0xffffffff. 382 static _GLIBCXX_CONSTEXPR int_type 383 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 384 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 385 386 static _GLIBCXX_CONSTEXPR bool 387 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 388 { return __c1 == __c2; } 389 390 static _GLIBCXX_CONSTEXPR int_type 391 eof() _GLIBCXX_NOEXCEPT 392 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 393 394 static _GLIBCXX_CONSTEXPR int_type 395 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 396 { return (__c == eof()) ? 0 : __c; } 397 }; 398 399 400 #ifdef _GLIBCXX_USE_WCHAR_T 401 /// 21.1.3.2 char_traits specializations 402 template<> 403 struct char_traits<wchar_t> 404 { 405 typedef wchar_t char_type; 406 typedef wint_t int_type; 407 typedef streamoff off_type; 408 typedef wstreampos pos_type; 409 typedef mbstate_t state_type; 410 411 static _GLIBCXX17_CONSTEXPR void 412 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 413 { __c1 = __c2; } 414 415 static _GLIBCXX_CONSTEXPR bool 416 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 417 { return __c1 == __c2; } 418 419 static _GLIBCXX_CONSTEXPR bool 420 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 421 { return __c1 < __c2; } 422 423 static _GLIBCXX17_CONSTEXPR int 424 compare(const char_type* __s1, const char_type* __s2, size_t __n) 425 { 426 if (__n == 0) 427 return 0; 428 #if __cplusplus >= 201703L 429 if (__builtin_constant_p(__n) 430 && __constant_char_array_p(__s1, __n) 431 && __constant_char_array_p(__s2, __n)) 432 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 433 #endif 434 return wmemcmp(__s1, __s2, __n); 435 } 436 437 static _GLIBCXX17_CONSTEXPR size_t 438 length(const char_type* __s) 439 { 440 #if __cplusplus >= 201703L 441 if (__constant_string_p(__s)) 442 return __gnu_cxx::char_traits<char_type>::length(__s); 443 #endif 444 return wcslen(__s); 445 } 446 447 static _GLIBCXX17_CONSTEXPR const char_type* 448 find(const char_type* __s, size_t __n, const char_type& __a) 449 { 450 if (__n == 0) 451 return 0; 452 #if __cplusplus >= 201703L 453 if (__builtin_constant_p(__n) 454 && __builtin_constant_p(__a) 455 && __constant_char_array_p(__s, __n)) 456 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 457 #endif 458 return wmemchr(__s, __a, __n); 459 } 460 461 static char_type* 462 move(char_type* __s1, const char_type* __s2, size_t __n) 463 { 464 if (__n == 0) 465 return __s1; 466 return wmemmove(__s1, __s2, __n); 467 } 468 469 static char_type* 470 copy(char_type* __s1, const char_type* __s2, size_t __n) 471 { 472 if (__n == 0) 473 return __s1; 474 return wmemcpy(__s1, __s2, __n); 475 } 476 477 static char_type* 478 assign(char_type* __s, size_t __n, char_type __a) 479 { 480 if (__n == 0) 481 return __s; 482 return wmemset(__s, __a, __n); 483 } 484 485 static _GLIBCXX_CONSTEXPR char_type 486 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 487 { return char_type(__c); } 488 489 static _GLIBCXX_CONSTEXPR int_type 490 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 491 { return int_type(__c); } 492 493 static _GLIBCXX_CONSTEXPR bool 494 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 495 { return __c1 == __c2; } 496 497 static _GLIBCXX_CONSTEXPR int_type 498 eof() _GLIBCXX_NOEXCEPT 499 { return static_cast<int_type>(WEOF); } 500 501 static _GLIBCXX_CONSTEXPR int_type 502 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 503 { return eq_int_type(__c, eof()) ? 0 : __c; } 504 }; 505 #endif //_GLIBCXX_USE_WCHAR_T 506 507 #ifdef _GLIBCXX_USE_CHAR8_T 508 template<> 509 struct char_traits<char8_t> 510 { 511 typedef char8_t char_type; 512 typedef unsigned int int_type; 513 typedef u8streampos pos_type; 514 typedef streamoff off_type; 515 typedef mbstate_t state_type; 516 517 static _GLIBCXX17_CONSTEXPR void 518 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 519 { __c1 = __c2; } 520 521 static _GLIBCXX_CONSTEXPR bool 522 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 523 { return __c1 == __c2; } 524 525 static _GLIBCXX_CONSTEXPR bool 526 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 527 { return __c1 < __c2; } 528 529 static _GLIBCXX17_CONSTEXPR int 530 compare(const char_type* __s1, const char_type* __s2, size_t __n) 531 { 532 if (__n == 0) 533 return 0; 534 #if __cplusplus > 201402 535 if (__builtin_constant_p(__n) 536 && __constant_char_array_p(__s1, __n) 537 && __constant_char_array_p(__s2, __n)) 538 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 539 #endif 540 return __builtin_memcmp(__s1, __s2, __n); 541 } 542 543 static _GLIBCXX17_CONSTEXPR size_t 544 length(const char_type* __s) 545 { 546 #if __cplusplus > 201402 547 if (__constant_string_p(__s)) 548 return __gnu_cxx::char_traits<char_type>::length(__s); 549 #endif 550 size_t __i = 0; 551 while (!eq(__s[__i], char_type())) 552 ++__i; 553 return __i; 554 } 555 556 static _GLIBCXX17_CONSTEXPR const char_type* 557 find(const char_type* __s, size_t __n, const char_type& __a) 558 { 559 if (__n == 0) 560 return 0; 561 #if __cplusplus > 201402 562 if (__builtin_constant_p(__n) 563 && __builtin_constant_p(__a) 564 && __constant_char_array_p(__s, __n)) 565 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 566 #endif 567 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 568 } 569 570 static char_type* 571 move(char_type* __s1, const char_type* __s2, size_t __n) 572 { 573 if (__n == 0) 574 return __s1; 575 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 576 } 577 578 static char_type* 579 copy(char_type* __s1, const char_type* __s2, size_t __n) 580 { 581 if (__n == 0) 582 return __s1; 583 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 584 } 585 586 static char_type* 587 assign(char_type* __s, size_t __n, char_type __a) 588 { 589 if (__n == 0) 590 return __s; 591 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 592 } 593 594 static _GLIBCXX_CONSTEXPR char_type 595 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 596 { return char_type(__c); } 597 598 static _GLIBCXX_CONSTEXPR int_type 599 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 600 { return int_type(__c); } 601 602 static _GLIBCXX_CONSTEXPR bool 603 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 604 { return __c1 == __c2; } 605 606 static _GLIBCXX_CONSTEXPR int_type 607 eof() _GLIBCXX_NOEXCEPT 608 { return static_cast<int_type>(-1); } 609 610 static _GLIBCXX_CONSTEXPR int_type 611 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 612 { return eq_int_type(__c, eof()) ? 0 : __c; } 613 }; 614 #endif //_GLIBCXX_USE_CHAR8_T 615 616 _GLIBCXX_END_NAMESPACE_VERSION 617 } // namespace 618 619 #if __cplusplus >= 201103L 620 621 #include <cstdint> 622 623 namespace std _GLIBCXX_VISIBILITY(default) 624 { 625 _GLIBCXX_BEGIN_NAMESPACE_VERSION 626 627 template<> 628 struct char_traits<char16_t> 629 { 630 typedef char16_t char_type; 631 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 632 typedef uint_least16_t int_type; 633 #elif defined __UINT_LEAST16_TYPE__ 634 typedef __UINT_LEAST16_TYPE__ int_type; 635 #else 636 typedef make_unsigned<char16_t>::type int_type; 637 #endif 638 typedef streamoff off_type; 639 typedef u16streampos pos_type; 640 typedef mbstate_t state_type; 641 642 static _GLIBCXX17_CONSTEXPR void 643 assign(char_type& __c1, const char_type& __c2) noexcept 644 { __c1 = __c2; } 645 646 static constexpr bool 647 eq(const char_type& __c1, const char_type& __c2) noexcept 648 { return __c1 == __c2; } 649 650 static constexpr bool 651 lt(const char_type& __c1, const char_type& __c2) noexcept 652 { return __c1 < __c2; } 653 654 static _GLIBCXX17_CONSTEXPR int 655 compare(const char_type* __s1, const char_type* __s2, size_t __n) 656 { 657 for (size_t __i = 0; __i < __n; ++__i) 658 if (lt(__s1[__i], __s2[__i])) 659 return -1; 660 else if (lt(__s2[__i], __s1[__i])) 661 return 1; 662 return 0; 663 } 664 665 static _GLIBCXX17_CONSTEXPR size_t 666 length(const char_type* __s) 667 { 668 size_t __i = 0; 669 while (!eq(__s[__i], char_type())) 670 ++__i; 671 return __i; 672 } 673 674 static _GLIBCXX17_CONSTEXPR const char_type* 675 find(const char_type* __s, size_t __n, const char_type& __a) 676 { 677 for (size_t __i = 0; __i < __n; ++__i) 678 if (eq(__s[__i], __a)) 679 return __s + __i; 680 return 0; 681 } 682 683 static char_type* 684 move(char_type* __s1, const char_type* __s2, size_t __n) 685 { 686 if (__n == 0) 687 return __s1; 688 return (static_cast<char_type*> 689 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 690 } 691 692 static char_type* 693 copy(char_type* __s1, const char_type* __s2, size_t __n) 694 { 695 if (__n == 0) 696 return __s1; 697 return (static_cast<char_type*> 698 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 699 } 700 701 static char_type* 702 assign(char_type* __s, size_t __n, char_type __a) 703 { 704 for (size_t __i = 0; __i < __n; ++__i) 705 assign(__s[__i], __a); 706 return __s; 707 } 708 709 static constexpr char_type 710 to_char_type(const int_type& __c) noexcept 711 { return char_type(__c); } 712 713 static constexpr int_type 714 to_int_type(const char_type& __c) noexcept 715 { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 716 717 static constexpr bool 718 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 719 { return __c1 == __c2; } 720 721 static constexpr int_type 722 eof() noexcept 723 { return static_cast<int_type>(-1); } 724 725 static constexpr int_type 726 not_eof(const int_type& __c) noexcept 727 { return eq_int_type(__c, eof()) ? 0 : __c; } 728 }; 729 730 template<> 731 struct char_traits<char32_t> 732 { 733 typedef char32_t char_type; 734 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 735 typedef uint_least32_t int_type; 736 #elif defined __UINT_LEAST32_TYPE__ 737 typedef __UINT_LEAST32_TYPE__ int_type; 738 #else 739 typedef make_unsigned<char32_t>::type int_type; 740 #endif 741 typedef streamoff off_type; 742 typedef u32streampos pos_type; 743 typedef mbstate_t state_type; 744 745 static _GLIBCXX17_CONSTEXPR void 746 assign(char_type& __c1, const char_type& __c2) noexcept 747 { __c1 = __c2; } 748 749 static constexpr bool 750 eq(const char_type& __c1, const char_type& __c2) noexcept 751 { return __c1 == __c2; } 752 753 static constexpr bool 754 lt(const char_type& __c1, const char_type& __c2) noexcept 755 { return __c1 < __c2; } 756 757 static _GLIBCXX17_CONSTEXPR int 758 compare(const char_type* __s1, const char_type* __s2, size_t __n) 759 { 760 for (size_t __i = 0; __i < __n; ++__i) 761 if (lt(__s1[__i], __s2[__i])) 762 return -1; 763 else if (lt(__s2[__i], __s1[__i])) 764 return 1; 765 return 0; 766 } 767 768 static _GLIBCXX17_CONSTEXPR size_t 769 length(const char_type* __s) 770 { 771 size_t __i = 0; 772 while (!eq(__s[__i], char_type())) 773 ++__i; 774 return __i; 775 } 776 777 static _GLIBCXX17_CONSTEXPR const char_type* 778 find(const char_type* __s, size_t __n, const char_type& __a) 779 { 780 for (size_t __i = 0; __i < __n; ++__i) 781 if (eq(__s[__i], __a)) 782 return __s + __i; 783 return 0; 784 } 785 786 static char_type* 787 move(char_type* __s1, const char_type* __s2, size_t __n) 788 { 789 if (__n == 0) 790 return __s1; 791 return (static_cast<char_type*> 792 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 793 } 794 795 static char_type* 796 copy(char_type* __s1, const char_type* __s2, size_t __n) 797 { 798 if (__n == 0) 799 return __s1; 800 return (static_cast<char_type*> 801 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 802 } 803 804 static char_type* 805 assign(char_type* __s, size_t __n, char_type __a) 806 { 807 for (size_t __i = 0; __i < __n; ++__i) 808 assign(__s[__i], __a); 809 return __s; 810 } 811 812 static constexpr char_type 813 to_char_type(const int_type& __c) noexcept 814 { return char_type(__c); } 815 816 static constexpr int_type 817 to_int_type(const char_type& __c) noexcept 818 { return int_type(__c); } 819 820 static constexpr bool 821 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 822 { return __c1 == __c2; } 823 824 static constexpr int_type 825 eof() noexcept 826 { return static_cast<int_type>(-1); } 827 828 static constexpr int_type 829 not_eof(const int_type& __c) noexcept 830 { return eq_int_type(__c, eof()) ? 0 : __c; } 831 }; 832 833 _GLIBCXX_END_NAMESPACE_VERSION 834 } // namespace 835 836 #endif // C++11 837 838 #endif // _CHAR_TRAITS_H 839