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