Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/char_traits.h
1 // Character Traits for use by standard string and iostream -*- C++ -*- 2 3 // Copyright (C) 1997-2025 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 #ifdef _GLIBCXX_SYSHDR 38 #pragma GCC system_header 39 #endif 40 41 #include <bits/c++config.h> 42 43 #if _GLIBCXX_HOSTED 44 # include <bits/postypes.h> // For streampos 45 #endif // HOSTED 46 47 #ifdef _GLIBCXX_USE_WCHAR_T 48 # include <cwchar> // For WEOF, wmemmove, wmemset, etc. 49 #endif // USE_WCHAR_T 50 51 #if __cplusplus >= 201103L 52 # include <type_traits> 53 #if !defined __UINT_LEAST16_TYPE__ || !defined __UINT_LEAST32_TYPE__ 54 # include <cstdint> 55 #endif 56 #endif 57 #if __cplusplus >= 202002L 58 # include <compare> 59 # include <bits/stl_construct.h> 60 #endif 61 62 #ifndef _GLIBCXX_ALWAYS_INLINE 63 # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 64 #endif 65 66 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 67 { 68 _GLIBCXX_BEGIN_NAMESPACE_VERSION 69 70 #pragma GCC diagnostic push 71 #pragma GCC diagnostic ignored "-Wstringop-overflow" 72 #pragma GCC diagnostic ignored "-Wstringop-overread" 73 #pragma GCC diagnostic ignored "-Warray-bounds" 74 75 /** 76 * @brief Mapping from character type to associated types. 77 * 78 * @note This is an implementation class for the generic version 79 * of char_traits. It defines int_type, off_type, pos_type, and 80 * state_type. By default these are unsigned long, streamoff, 81 * streampos, and mbstate_t. Users who need a different set of 82 * types, but who don't need to change the definitions of any function 83 * defined in char_traits, can specialize __gnu_cxx::_Char_types 84 * while leaving __gnu_cxx::char_traits alone. */ 85 template<typename _CharT> 86 struct _Char_types 87 { 88 typedef unsigned long int_type; 89 #if _GLIBCXX_HOSTED 90 typedef std::streampos pos_type; 91 typedef std::streamoff off_type; 92 typedef std::mbstate_t state_type; 93 #endif // HOSTED 94 }; 95 96 97 /** 98 * @brief Base class used to implement std::char_traits. 99 * 100 * @note For any given actual character type, this definition is 101 * probably wrong. (Most of the member functions are likely to be 102 * right, but the int_type and state_type typedefs, and the eof() 103 * member function, are likely to be wrong.) The reason this class 104 * exists is so users can specialize it. Classes in namespace std 105 * may not be specialized for fundamental types, but classes in 106 * namespace __gnu_cxx may be. 107 * 108 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 109 * for advice on how to make use of this class for @a unusual character 110 * types. Also, check out include/ext/pod_char_traits.h. 111 */ 112 template<typename _CharT> 113 struct char_traits 114 { 115 typedef _CharT char_type; 116 typedef typename _Char_types<_CharT>::int_type int_type; 117 #if _GLIBCXX_HOSTED 118 typedef typename _Char_types<_CharT>::pos_type pos_type; 119 typedef typename _Char_types<_CharT>::off_type off_type; 120 typedef typename _Char_types<_CharT>::state_type state_type; 121 #endif // HOSTED 122 #if __cpp_lib_three_way_comparison 123 using comparison_category = std::strong_ordering; 124 #endif 125 126 static _GLIBCXX14_CONSTEXPR void 127 assign(char_type& __c1, const char_type& __c2) 128 { 129 #if __cpp_constexpr_dynamic_alloc 130 if (std::__is_constant_evaluated()) 131 std::construct_at(__builtin_addressof(__c1), __c2); 132 else 133 #endif 134 __c1 = __c2; 135 } 136 137 static _GLIBCXX_CONSTEXPR bool 138 eq(const char_type& __c1, const char_type& __c2) 139 { return __c1 == __c2; } 140 141 static _GLIBCXX_CONSTEXPR bool 142 lt(const char_type& __c1, const char_type& __c2) 143 { return __c1 < __c2; } 144 145 static _GLIBCXX14_CONSTEXPR int 146 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 147 148 static _GLIBCXX14_CONSTEXPR std::size_t 149 length(const char_type* __s); 150 151 static _GLIBCXX14_CONSTEXPR const char_type* 152 find(const char_type* __s, std::size_t __n, const char_type& __a); 153 154 static _GLIBCXX20_CONSTEXPR char_type* 155 move(char_type* __s1, const char_type* __s2, std::size_t __n); 156 157 static _GLIBCXX20_CONSTEXPR char_type* 158 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 159 160 static _GLIBCXX20_CONSTEXPR char_type* 161 assign(char_type* __s, std::size_t __n, char_type __a); 162 163 static _GLIBCXX_CONSTEXPR char_type 164 to_char_type(const int_type& __c) 165 { return static_cast<char_type>(__c); } 166 167 static _GLIBCXX_CONSTEXPR int_type 168 to_int_type(const char_type& __c) 169 { return static_cast<int_type>(__c); } 170 171 static _GLIBCXX_CONSTEXPR bool 172 eq_int_type(const int_type& __c1, const int_type& __c2) 173 { return __c1 == __c2; } 174 175 #ifdef _GLIBCXX_STDIO_EOF 176 static _GLIBCXX_CONSTEXPR int_type 177 eof() 178 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 179 180 static _GLIBCXX_CONSTEXPR int_type 181 not_eof(const int_type& __c) 182 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 183 #endif // defined(_GLIBCXX_STDIO_EOF) 184 }; 185 186 template<typename _CharT> 187 _GLIBCXX14_CONSTEXPR int 188 char_traits<_CharT>:: 189 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 190 { 191 for (std::size_t __i = 0; __i < __n; ++__i) 192 if (lt(__s1[__i], __s2[__i])) 193 return -1; 194 else if (lt(__s2[__i], __s1[__i])) 195 return 1; 196 return 0; 197 } 198 199 template<typename _CharT> 200 _GLIBCXX14_CONSTEXPR std::size_t 201 char_traits<_CharT>:: 202 length(const char_type* __p) 203 { 204 std::size_t __i = 0; 205 while (!eq(__p[__i], char_type())) 206 ++__i; 207 return __i; 208 } 209 210 template<typename _CharT> 211 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 212 char_traits<_CharT>:: 213 find(const char_type* __s, std::size_t __n, const char_type& __a) 214 { 215 for (std::size_t __i = 0; __i < __n; ++__i) 216 if (eq(__s[__i], __a)) 217 return __s + __i; 218 return 0; 219 } 220 221 template<typename _CharT> 222 _GLIBCXX20_CONSTEXPR 223 typename char_traits<_CharT>::char_type* 224 char_traits<_CharT>:: 225 move(char_type* __s1, const char_type* __s2, std::size_t __n) 226 { 227 if (__n == 0) 228 return __s1; 229 #if __cplusplus >= 202002L 230 if (std::__is_constant_evaluated()) 231 { 232 // Use __builtin_constant_p to avoid comparing unrelated pointers. 233 if (__builtin_constant_p(__s2 < __s1) 234 && __s1 > __s2 && __s1 < (__s2 + __n)) 235 { 236 do 237 { 238 --__n; 239 assign(__s1[__n], __s2[__n]); 240 } 241 while (__n > 0); 242 } 243 else 244 copy(__s1, __s2, __n); 245 return __s1; 246 } 247 #endif 248 __builtin_memmove(__s1, __s2, __n * sizeof(char_type)); 249 return __s1; 250 } 251 252 template<typename _CharT> 253 _GLIBCXX20_CONSTEXPR 254 typename char_traits<_CharT>::char_type* 255 char_traits<_CharT>:: 256 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 257 { 258 if (__n == 0) 259 return __s1; 260 #if __cplusplus >= 202002L 261 if (std::__is_constant_evaluated()) 262 { 263 for (std::size_t __i = 0; __i < __n; ++__i) 264 std::construct_at(__s1 + __i, __s2[__i]); 265 return __s1; 266 } 267 #endif 268 __builtin_memcpy(__s1, __s2, __n * sizeof(char_type)); 269 return __s1; 270 } 271 272 template<typename _CharT> 273 _GLIBCXX20_CONSTEXPR 274 typename char_traits<_CharT>::char_type* 275 char_traits<_CharT>:: 276 assign(char_type* __s, std::size_t __n, char_type __a) 277 { 278 #if __cplusplus >= 202002L 279 if (std::__is_constant_evaluated()) 280 { 281 for (std::size_t __i = 0; __i < __n; ++__i) 282 std::construct_at(__s + __i, __a); 283 return __s; 284 } 285 #endif 286 287 if _GLIBCXX17_CONSTEXPR (sizeof(_CharT) == 1 && __is_trivial(_CharT)) 288 { 289 if (__n) 290 { 291 unsigned char __c; 292 __builtin_memcpy(&__c, __builtin_addressof(__a), 1); 293 __builtin_memset(__s, __c, __n); 294 } 295 } 296 else 297 { 298 for (std::size_t __i = 0; __i < __n; ++__i) 299 __s[__i] = __a; 300 } 301 return __s; 302 } 303 304 _GLIBCXX_END_NAMESPACE_VERSION 305 } // namespace 306 307 namespace std _GLIBCXX_VISIBILITY(default) 308 { 309 _GLIBCXX_BEGIN_NAMESPACE_VERSION 310 311 // 21.1 312 /** 313 * @brief Basis for explicit traits specializations. 314 * 315 * @note For any given actual character type, this definition is 316 * probably wrong. Since this is just a thin wrapper around 317 * __gnu_cxx::char_traits, it is possible to achieve a more 318 * appropriate definition by specializing __gnu_cxx::char_traits. 319 * 320 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 321 * for advice on how to make use of this class for @a unusual character 322 * types. Also, check out include/ext/pod_char_traits.h. 323 */ 324 template<typename _CharT> 325 struct char_traits : public __gnu_cxx::char_traits<_CharT> 326 { }; 327 328 329 /// 21.1.3.1 char_traits specializations 330 template<> 331 struct char_traits<char> 332 { 333 typedef char char_type; 334 typedef int int_type; 335 #if _GLIBCXX_HOSTED 336 typedef streampos pos_type; 337 typedef streamoff off_type; 338 typedef mbstate_t state_type; 339 #endif // HOSTED 340 #if __cpp_lib_three_way_comparison 341 using comparison_category = strong_ordering; 342 #endif 343 344 static _GLIBCXX17_CONSTEXPR void 345 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 346 { 347 #if __cpp_constexpr_dynamic_alloc 348 if (std::__is_constant_evaluated()) 349 std::construct_at(__builtin_addressof(__c1), __c2); 350 else 351 #endif 352 __c1 = __c2; 353 } 354 355 static _GLIBCXX_CONSTEXPR bool 356 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 357 { return __c1 == __c2; } 358 359 static _GLIBCXX_CONSTEXPR bool 360 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 361 { 362 // LWG 467. 363 return (static_cast<unsigned char>(__c1) 364 < static_cast<unsigned char>(__c2)); 365 } 366 367 static _GLIBCXX17_CONSTEXPR int 368 compare(const char_type* __s1, const char_type* __s2, size_t __n) 369 { 370 if (__n == 0) 371 return 0; 372 #if __cplusplus >= 201703L 373 if (std::__is_constant_evaluated()) 374 { 375 for (size_t __i = 0; __i < __n; ++__i) 376 if (lt(__s1[__i], __s2[__i])) 377 return -1; 378 else if (lt(__s2[__i], __s1[__i])) 379 return 1; 380 return 0; 381 } 382 #endif 383 return __builtin_memcmp(__s1, __s2, __n); 384 } 385 386 static _GLIBCXX17_CONSTEXPR size_t 387 length(const char_type* __s) 388 { 389 #if __cplusplus >= 201703L 390 if (std::__is_constant_evaluated()) 391 return __gnu_cxx::char_traits<char_type>::length(__s); 392 #endif 393 return __builtin_strlen(__s); 394 } 395 396 static _GLIBCXX17_CONSTEXPR const char_type* 397 find(const char_type* __s, size_t __n, const char_type& __a) 398 { 399 if (__n == 0) 400 return 0; 401 #if __cplusplus >= 201703L 402 if (std::__is_constant_evaluated()) 403 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 404 #endif 405 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 406 } 407 408 static _GLIBCXX20_CONSTEXPR char_type* 409 move(char_type* __s1, const char_type* __s2, size_t __n) 410 { 411 if (__n == 0) 412 return __s1; 413 #if __cplusplus >= 202002L 414 if (std::__is_constant_evaluated()) 415 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); 416 #endif 417 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 418 } 419 420 static _GLIBCXX20_CONSTEXPR char_type* 421 copy(char_type* __s1, const char_type* __s2, size_t __n) 422 { 423 if (__n == 0) 424 return __s1; 425 #if __cplusplus >= 202002L 426 if (std::__is_constant_evaluated()) 427 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); 428 #endif 429 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 430 } 431 432 static _GLIBCXX20_CONSTEXPR char_type* 433 assign(char_type* __s, size_t __n, char_type __a) 434 { 435 if (__n == 0) 436 return __s; 437 #if __cplusplus >= 202002L 438 if (std::__is_constant_evaluated()) 439 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); 440 #endif 441 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 442 } 443 444 static _GLIBCXX_CONSTEXPR char_type 445 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 446 { return static_cast<char_type>(__c); } 447 448 // To keep both the byte 0xff and the eof symbol 0xffffffff 449 // from ending up as 0xffffffff. 450 static _GLIBCXX_CONSTEXPR int_type 451 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 452 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 453 454 static _GLIBCXX_CONSTEXPR bool 455 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 456 { return __c1 == __c2; } 457 458 #ifdef _GLIBCXX_STDIO_EOF 459 static _GLIBCXX_CONSTEXPR int_type 460 eof() _GLIBCXX_NOEXCEPT 461 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 462 463 static _GLIBCXX_CONSTEXPR int_type 464 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 465 { return (__c == eof()) ? 0 : __c; } 466 #endif // defined(_GLIBCXX_STDIO_EOF) 467 }; 468 469 470 #ifdef _GLIBCXX_USE_WCHAR_T 471 /// 21.1.3.2 char_traits specializations 472 template<> 473 struct char_traits<wchar_t> 474 { 475 typedef wchar_t char_type; 476 typedef wint_t int_type; 477 #if _GLIBCXX_HOSTED 478 typedef streamoff off_type; 479 typedef wstreampos pos_type; 480 typedef mbstate_t state_type; 481 #endif // HOSTED 482 #if __cpp_lib_three_way_comparison 483 using comparison_category = strong_ordering; 484 #endif 485 486 static _GLIBCXX17_CONSTEXPR void 487 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 488 { 489 #if __cpp_constexpr_dynamic_alloc 490 if (std::__is_constant_evaluated()) 491 std::construct_at(__builtin_addressof(__c1), __c2); 492 else 493 #endif 494 __c1 = __c2; 495 } 496 497 static _GLIBCXX_CONSTEXPR bool 498 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 499 { return __c1 == __c2; } 500 501 static _GLIBCXX_CONSTEXPR bool 502 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 503 { return __c1 < __c2; } 504 505 static _GLIBCXX17_CONSTEXPR int 506 compare(const char_type* __s1, const char_type* __s2, size_t __n) 507 { 508 if (__n == 0) 509 return 0; 510 #if __cplusplus >= 201703L 511 if (std::__is_constant_evaluated()) 512 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 513 #endif 514 return wmemcmp(__s1, __s2, __n); 515 } 516 517 static _GLIBCXX17_CONSTEXPR size_t 518 length(const char_type* __s) 519 { 520 #if __cplusplus >= 201703L 521 if (std::__is_constant_evaluated()) 522 return __gnu_cxx::char_traits<char_type>::length(__s); 523 #endif 524 return wcslen(__s); 525 } 526 527 static _GLIBCXX17_CONSTEXPR const char_type* 528 find(const char_type* __s, size_t __n, const char_type& __a) 529 { 530 if (__n == 0) 531 return 0; 532 #if __cplusplus >= 201703L 533 if (std::__is_constant_evaluated()) 534 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 535 #endif 536 return wmemchr(__s, __a, __n); 537 } 538 539 static _GLIBCXX20_CONSTEXPR char_type* 540 move(char_type* __s1, const char_type* __s2, size_t __n) 541 { 542 if (__n == 0) 543 return __s1; 544 #if __cplusplus >= 202002L 545 if (std::__is_constant_evaluated()) 546 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); 547 #endif 548 return wmemmove(__s1, __s2, __n); 549 } 550 551 static _GLIBCXX20_CONSTEXPR char_type* 552 copy(char_type* __s1, const char_type* __s2, size_t __n) 553 { 554 if (__n == 0) 555 return __s1; 556 #if __cplusplus >= 202002L 557 if (std::__is_constant_evaluated()) 558 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); 559 #endif 560 return wmemcpy(__s1, __s2, __n); 561 } 562 563 static _GLIBCXX20_CONSTEXPR char_type* 564 assign(char_type* __s, size_t __n, char_type __a) 565 { 566 if (__n == 0) 567 return __s; 568 #if __cplusplus >= 202002L 569 if (std::__is_constant_evaluated()) 570 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); 571 #endif 572 return wmemset(__s, __a, __n); 573 } 574 575 static _GLIBCXX_CONSTEXPR char_type 576 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 577 { return char_type(__c); } 578 579 static _GLIBCXX_CONSTEXPR int_type 580 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 581 { return int_type(__c); } 582 583 static _GLIBCXX_CONSTEXPR bool 584 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 585 { return __c1 == __c2; } 586 587 #if _GLIBCXX_HOSTED 588 static _GLIBCXX_CONSTEXPR int_type 589 eof() _GLIBCXX_NOEXCEPT 590 { return static_cast<int_type>(WEOF); } 591 592 static _GLIBCXX_CONSTEXPR int_type 593 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 594 { return eq_int_type(__c, eof()) ? 0 : __c; } 595 #endif // HOSTED 596 }; 597 #else // _GLIBCXX_USE_WCHAR_T 598 template<> 599 struct char_traits<wchar_t> : public __gnu_cxx::char_traits<wchar_t> 600 { }; 601 #endif //_GLIBCXX_USE_WCHAR_T 602 603 #ifdef _GLIBCXX_USE_CHAR8_T 604 template<> 605 struct char_traits<char8_t> 606 { 607 typedef char8_t char_type; 608 typedef unsigned int int_type; 609 #if _GLIBCXX_HOSTED 610 typedef u8streampos pos_type; 611 typedef streamoff off_type; 612 typedef mbstate_t state_type; 613 #endif // HOSTED 614 #if __cpp_lib_three_way_comparison 615 using comparison_category = strong_ordering; 616 #endif 617 618 static _GLIBCXX17_CONSTEXPR void 619 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 620 { 621 #if __cpp_constexpr_dynamic_alloc 622 if (std::__is_constant_evaluated()) 623 std::construct_at(__builtin_addressof(__c1), __c2); 624 else 625 #endif 626 __c1 = __c2; 627 } 628 629 static _GLIBCXX_CONSTEXPR bool 630 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 631 { return __c1 == __c2; } 632 633 static _GLIBCXX_CONSTEXPR bool 634 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 635 { return __c1 < __c2; } 636 637 static _GLIBCXX17_CONSTEXPR int 638 compare(const char_type* __s1, const char_type* __s2, size_t __n) 639 { 640 if (__n == 0) 641 return 0; 642 #if __cplusplus >= 201703L 643 if (std::__is_constant_evaluated()) 644 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 645 #endif 646 return __builtin_memcmp(__s1, __s2, __n); 647 } 648 649 static _GLIBCXX17_CONSTEXPR size_t 650 length(const char_type* __s) 651 { 652 #if __cplusplus >= 201703L 653 if (std::__is_constant_evaluated()) 654 return __gnu_cxx::char_traits<char_type>::length(__s); 655 #endif 656 return __builtin_strlen((const char*)__s); 657 } 658 659 static _GLIBCXX17_CONSTEXPR const char_type* 660 find(const char_type* __s, size_t __n, const char_type& __a) 661 { 662 if (__n == 0) 663 return 0; 664 #if __cplusplus >= 201703L 665 if (std::__is_constant_evaluated()) 666 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 667 #endif 668 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 669 } 670 671 static _GLIBCXX20_CONSTEXPR char_type* 672 move(char_type* __s1, const char_type* __s2, size_t __n) 673 { 674 if (__n == 0) 675 return __s1; 676 #if __cplusplus >= 202002L 677 if (std::__is_constant_evaluated()) 678 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); 679 #endif 680 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 681 } 682 683 static _GLIBCXX20_CONSTEXPR char_type* 684 copy(char_type* __s1, const char_type* __s2, size_t __n) 685 { 686 if (__n == 0) 687 return __s1; 688 #if __cplusplus >= 202002L 689 if (std::__is_constant_evaluated()) 690 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); 691 #endif 692 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 693 } 694 695 static _GLIBCXX20_CONSTEXPR char_type* 696 assign(char_type* __s, size_t __n, char_type __a) 697 { 698 if (__n == 0) 699 return __s; 700 #if __cplusplus >= 202002L 701 if (std::__is_constant_evaluated()) 702 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a); 703 #endif 704 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 705 } 706 707 static _GLIBCXX_CONSTEXPR char_type 708 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 709 { return char_type(__c); } 710 711 static _GLIBCXX_CONSTEXPR int_type 712 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 713 { return int_type(__c); } 714 715 static _GLIBCXX_CONSTEXPR bool 716 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 717 { return __c1 == __c2; } 718 719 #if _GLIBCXX_HOSTED 720 static _GLIBCXX_CONSTEXPR int_type 721 eof() _GLIBCXX_NOEXCEPT 722 { return static_cast<int_type>(-1); } 723 724 static _GLIBCXX_CONSTEXPR int_type 725 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 726 { return eq_int_type(__c, eof()) ? 0 : __c; } 727 #endif // HOSTED 728 }; 729 #endif //_GLIBCXX_USE_CHAR8_T 730 731 _GLIBCXX_END_NAMESPACE_VERSION 732 } // namespace 733 734 #if __cplusplus >= 201103L 735 736 namespace std _GLIBCXX_VISIBILITY(default) 737 { 738 _GLIBCXX_BEGIN_NAMESPACE_VERSION 739 740 template<> 741 struct char_traits<char16_t> 742 { 743 typedef char16_t char_type; 744 #ifdef __UINT_LEAST16_TYPE__ 745 typedef __UINT_LEAST16_TYPE__ int_type; 746 #else 747 typedef uint_least16_t int_type; 748 #endif 749 #if _GLIBCXX_HOSTED 750 typedef streamoff off_type; 751 typedef u16streampos pos_type; 752 typedef mbstate_t state_type; 753 #endif // HOSTED 754 #if __cpp_lib_three_way_comparison 755 using comparison_category = strong_ordering; 756 #endif 757 758 static _GLIBCXX17_CONSTEXPR void 759 assign(char_type& __c1, const char_type& __c2) noexcept 760 { 761 #if __cpp_constexpr_dynamic_alloc 762 if (std::__is_constant_evaluated()) 763 std::construct_at(__builtin_addressof(__c1), __c2); 764 else 765 #endif 766 __c1 = __c2; 767 } 768 769 static constexpr bool 770 eq(const char_type& __c1, const char_type& __c2) noexcept 771 { return __c1 == __c2; } 772 773 static constexpr bool 774 lt(const char_type& __c1, const char_type& __c2) noexcept 775 { return __c1 < __c2; } 776 777 static _GLIBCXX17_CONSTEXPR int 778 compare(const char_type* __s1, const char_type* __s2, size_t __n) 779 { 780 for (size_t __i = 0; __i < __n; ++__i) 781 if (lt(__s1[__i], __s2[__i])) 782 return -1; 783 else if (lt(__s2[__i], __s1[__i])) 784 return 1; 785 return 0; 786 } 787 788 static _GLIBCXX17_CONSTEXPR size_t 789 length(const char_type* __s) 790 { 791 size_t __i = 0; 792 while (!eq(__s[__i], char_type())) 793 ++__i; 794 return __i; 795 } 796 797 static _GLIBCXX17_CONSTEXPR const char_type* 798 find(const char_type* __s, size_t __n, const char_type& __a) 799 { 800 for (size_t __i = 0; __i < __n; ++__i) 801 if (eq(__s[__i], __a)) 802 return __s + __i; 803 return 0; 804 } 805 806 static _GLIBCXX20_CONSTEXPR char_type* 807 move(char_type* __s1, const char_type* __s2, size_t __n) 808 { 809 if (__n == 0) 810 return __s1; 811 #if __cplusplus >= 202002L 812 if (std::__is_constant_evaluated()) 813 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); 814 #endif 815 return (static_cast<char_type*> 816 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 817 } 818 819 static _GLIBCXX20_CONSTEXPR char_type* 820 copy(char_type* __s1, const char_type* __s2, size_t __n) 821 { 822 if (__n == 0) 823 return __s1; 824 #if __cplusplus >= 202002L 825 if (std::__is_constant_evaluated()) 826 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); 827 #endif 828 return (static_cast<char_type*> 829 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 830 } 831 832 static _GLIBCXX20_CONSTEXPR char_type* 833 assign(char_type* __s, size_t __n, char_type __a) 834 { 835 for (size_t __i = 0; __i < __n; ++__i) 836 assign(__s[__i], __a); 837 return __s; 838 } 839 840 static constexpr char_type 841 to_char_type(const int_type& __c) noexcept 842 { return char_type(__c); } 843 844 static constexpr bool 845 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 846 { return __c1 == __c2; } 847 848 #if _GLIBCXX_HOSTED 849 static constexpr int_type 850 to_int_type(const char_type& __c) noexcept 851 { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 852 853 static constexpr int_type 854 eof() noexcept 855 { return static_cast<int_type>(-1); } 856 857 static constexpr int_type 858 not_eof(const int_type& __c) noexcept 859 { return eq_int_type(__c, eof()) ? 0 : __c; } 860 #else // !HOSTED 861 static constexpr int_type 862 to_int_type(const char_type& __c) noexcept 863 { return int_type(__c); } 864 #endif // !HOSTED 865 }; 866 867 template<> 868 struct char_traits<char32_t> 869 { 870 typedef char32_t char_type; 871 #ifdef __UINT_LEAST32_TYPE__ 872 typedef __UINT_LEAST32_TYPE__ int_type; 873 #else 874 typedef uint_least32_t int_type; 875 #endif 876 #if _GLIBCXX_HOSTED 877 typedef streamoff off_type; 878 typedef u32streampos pos_type; 879 typedef mbstate_t state_type; 880 #endif // HOSTED 881 #if __cpp_lib_three_way_comparison 882 using comparison_category = strong_ordering; 883 #endif 884 885 static _GLIBCXX17_CONSTEXPR void 886 assign(char_type& __c1, const char_type& __c2) noexcept 887 { 888 #if __cpp_constexpr_dynamic_alloc 889 if (std::__is_constant_evaluated()) 890 std::construct_at(__builtin_addressof(__c1), __c2); 891 else 892 #endif 893 __c1 = __c2; 894 } 895 896 static constexpr bool 897 eq(const char_type& __c1, const char_type& __c2) noexcept 898 { return __c1 == __c2; } 899 900 static constexpr bool 901 lt(const char_type& __c1, const char_type& __c2) noexcept 902 { return __c1 < __c2; } 903 904 static _GLIBCXX17_CONSTEXPR int 905 compare(const char_type* __s1, const char_type* __s2, size_t __n) 906 { 907 for (size_t __i = 0; __i < __n; ++__i) 908 if (lt(__s1[__i], __s2[__i])) 909 return -1; 910 else if (lt(__s2[__i], __s1[__i])) 911 return 1; 912 return 0; 913 } 914 915 static _GLIBCXX17_CONSTEXPR size_t 916 length(const char_type* __s) 917 { 918 size_t __i = 0; 919 while (!eq(__s[__i], char_type())) 920 ++__i; 921 return __i; 922 } 923 924 static _GLIBCXX17_CONSTEXPR const char_type* 925 find(const char_type* __s, size_t __n, const char_type& __a) 926 { 927 for (size_t __i = 0; __i < __n; ++__i) 928 if (eq(__s[__i], __a)) 929 return __s + __i; 930 return 0; 931 } 932 933 static _GLIBCXX20_CONSTEXPR char_type* 934 move(char_type* __s1, const char_type* __s2, size_t __n) 935 { 936 if (__n == 0) 937 return __s1; 938 #if __cplusplus >= 202002L 939 if (std::__is_constant_evaluated()) 940 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n); 941 #endif 942 return (static_cast<char_type*> 943 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 944 } 945 946 static _GLIBCXX20_CONSTEXPR char_type* 947 copy(char_type* __s1, const char_type* __s2, size_t __n) 948 { 949 if (__n == 0) 950 return __s1; 951 #if __cplusplus >= 202002L 952 if (std::__is_constant_evaluated()) 953 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n); 954 #endif 955 return (static_cast<char_type*> 956 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 957 } 958 959 static _GLIBCXX20_CONSTEXPR char_type* 960 assign(char_type* __s, size_t __n, char_type __a) 961 { 962 for (size_t __i = 0; __i < __n; ++__i) 963 assign(__s[__i], __a); 964 return __s; 965 } 966 967 static constexpr char_type 968 to_char_type(const int_type& __c) noexcept 969 { return char_type(__c); } 970 971 static constexpr int_type 972 to_int_type(const char_type& __c) noexcept 973 { return int_type(__c); } 974 975 static constexpr bool 976 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 977 { return __c1 == __c2; } 978 979 #if _GLIBCXX_HOSTED 980 static constexpr int_type 981 eof() noexcept 982 { return static_cast<int_type>(-1); } 983 984 static constexpr int_type 985 not_eof(const int_type& __c) noexcept 986 { return eq_int_type(__c, eof()) ? 0 : __c; } 987 #endif // HOSTED 988 }; 989 990 #if __cpp_lib_three_way_comparison 991 namespace __detail 992 { 993 template<typename _ChTraits> 994 constexpr auto 995 __char_traits_cmp_cat(int __cmp) noexcept 996 { 997 if constexpr (requires { typename _ChTraits::comparison_category; }) 998 { 999 using _Cat = typename _ChTraits::comparison_category; 1000 static_assert( !is_void_v<common_comparison_category_t<_Cat>> ); 1001 return static_cast<_Cat>(__cmp <=> 0); 1002 } 1003 else 1004 return static_cast<weak_ordering>(__cmp <=> 0); 1005 } 1006 } // namespace __detail 1007 #endif // C++20 1008 1009 #pragma GCC diagnostic pop 1010 1011 _GLIBCXX_END_NAMESPACE_VERSION 1012 } // namespace 1013 1014 #endif // C++11 1015 1016 #endif // _CHAR_TRAITS_H