libstdc++
char_traits.h
Go to the documentation of this file.
1// Character Traits for use by standard string and iostream -*- C++ -*-
2
3// Copyright (C) 1997-2020 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
47namespace __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>
63 {
64 typedef unsigned long int_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>
88 {
89 typedef _CharT char_type;
90 typedef typename _Char_types<_CharT>::int_type int_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 _GLIBCXX20_CONSTEXPR char_type*
117 move(char_type* __s1, const char_type* __s2, std::size_t __n);
118
119 static _GLIBCXX20_CONSTEXPR char_type*
120 copy(char_type* __s1, const char_type* __s2, std::size_t __n);
121
122 static _GLIBCXX20_CONSTEXPR 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
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 _GLIBCXX20_CONSTEXPR
183 typename char_traits<_CharT>::char_type*
184 char_traits<_CharT>::
185 move(char_type* __s1, const char_type* __s2, std::size_t __n)
186 {
187 if (__n == 0)
188 return __s1;
189#ifdef __cpp_lib_is_constant_evaluated
190 if (std::is_constant_evaluated())
191 {
192 if (__s1 > __s2 && __s1 < __s2 + __n)
193 std::copy_backward(__s2, __s2 + __n, __s1);
194 else
195 std::copy(__s2, __s2 + __n, __s1);
196 return __s1;
197 }
198#endif
199 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
200 __n * sizeof(char_type)));
201 }
202
203 template<typename _CharT>
204 _GLIBCXX20_CONSTEXPR
205 typename char_traits<_CharT>::char_type*
206 char_traits<_CharT>::
207 copy(char_type* __s1, const char_type* __s2, std::size_t __n)
208 {
209 // NB: Inline std::copy so no recursive dependencies.
210 std::copy(__s2, __s2 + __n, __s1);
211 return __s1;
212 }
213
214 template<typename _CharT>
215 _GLIBCXX20_CONSTEXPR
216 typename char_traits<_CharT>::char_type*
217 char_traits<_CharT>::
218 assign(char_type* __s, std::size_t __n, char_type __a)
219 {
220 // NB: Inline std::fill_n so no recursive dependencies.
221 std::fill_n(__s, __n, __a);
222 return __s;
223 }
224
225_GLIBCXX_END_NAMESPACE_VERSION
226} // namespace
227
228namespace std _GLIBCXX_VISIBILITY(default)
229{
230_GLIBCXX_BEGIN_NAMESPACE_VERSION
231
232#if __cplusplus >= 201703L
233#define __cpp_lib_constexpr_char_traits 201611
234
235 /**
236 * @brief Determine whether the characters of a NULL-terminated
237 * string are known at compile time.
238 * @param __s The string.
239 *
240 * Assumes that _CharT is a built-in character type.
241 */
242 template<typename _CharT>
243 static _GLIBCXX_ALWAYS_INLINE constexpr bool
244 __constant_string_p(const _CharT* __s)
245 {
246#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
247 (void) __s;
248 // In constexpr contexts all strings should be constant.
249 return __builtin_is_constant_evaluated();
250#else
251 while (__builtin_constant_p(*__s) && *__s)
252 __s++;
253 return __builtin_constant_p(*__s);
254#endif
255 }
256
257 /**
258 * @brief Determine whether the characters of a character array are
259 * known at compile time.
260 * @param __a The character array.
261 * @param __n Number of characters.
262 *
263 * Assumes that _CharT is a built-in character type.
264 */
265 template<typename _CharT>
266 static _GLIBCXX_ALWAYS_INLINE constexpr bool
267 __constant_char_array_p(const _CharT* __a, size_t __n)
268 {
269#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
270 (void) __a;
271 (void) __n;
272 // In constexpr contexts all character arrays should be constant.
273 return __builtin_is_constant_evaluated();
274#else
275 size_t __i = 0;
276 while (__i < __n && __builtin_constant_p(__a[__i]))
277 __i++;
278 return __i == __n;
279#endif
280 }
281#endif
282
283 // 21.1
284 /**
285 * @brief Basis for explicit traits specializations.
286 *
287 * @note For any given actual character type, this definition is
288 * probably wrong. Since this is just a thin wrapper around
289 * __gnu_cxx::char_traits, it is possible to achieve a more
290 * appropriate definition by specializing __gnu_cxx::char_traits.
291 *
292 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
293 * for advice on how to make use of this class for @a unusual character
294 * types. Also, check out include/ext/pod_char_traits.h.
295 */
296 template<class _CharT>
297 struct char_traits : public __gnu_cxx::char_traits<_CharT>
298 { };
299
300
301 /// 21.1.3.1 char_traits specializations
302 template<>
303 struct char_traits<char>
304 {
305 typedef char char_type;
306 typedef int int_type;
307 typedef streampos pos_type;
308 typedef streamoff off_type;
309 typedef mbstate_t state_type;
310
311 static _GLIBCXX17_CONSTEXPR void
312 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
313 { __c1 = __c2; }
314
315 static _GLIBCXX_CONSTEXPR bool
316 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
317 { return __c1 == __c2; }
318
319 static _GLIBCXX_CONSTEXPR bool
320 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
321 {
322 // LWG 467.
323 return (static_cast<unsigned char>(__c1)
324 < static_cast<unsigned char>(__c2));
325 }
326
327 static _GLIBCXX17_CONSTEXPR int
328 compare(const char_type* __s1, const char_type* __s2, size_t __n)
329 {
330 if (__n == 0)
331 return 0;
332#if __cplusplus >= 201703L
333 if (__builtin_constant_p(__n)
334 && __constant_char_array_p(__s1, __n)
335 && __constant_char_array_p(__s2, __n))
336 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
337#endif
338 return __builtin_memcmp(__s1, __s2, __n);
339 }
340
341 static _GLIBCXX17_CONSTEXPR size_t
342 length(const char_type* __s)
343 {
344#if __cplusplus >= 201703L
345 if (__constant_string_p(__s))
347#endif
348 return __builtin_strlen(__s);
349 }
350
351 static _GLIBCXX17_CONSTEXPR const char_type*
352 find(const char_type* __s, size_t __n, const char_type& __a)
353 {
354 if (__n == 0)
355 return 0;
356#if __cplusplus >= 201703L
357 if (__builtin_constant_p(__n)
358 && __builtin_constant_p(__a)
359 && __constant_char_array_p(__s, __n))
360 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
361#endif
362 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
363 }
364
365 static _GLIBCXX20_CONSTEXPR char_type*
366 move(char_type* __s1, const char_type* __s2, size_t __n)
367 {
368 if (__n == 0)
369 return __s1;
370#ifdef __cpp_lib_is_constant_evaluated
371 if (std::is_constant_evaluated())
372 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
373#endif
374 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
375 }
376
377 static _GLIBCXX20_CONSTEXPR char_type*
378 copy(char_type* __s1, const char_type* __s2, size_t __n)
379 {
380 if (__n == 0)
381 return __s1;
382#ifdef __cpp_lib_is_constant_evaluated
383 if (std::is_constant_evaluated())
384 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
385#endif
386 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
387 }
388
389 static _GLIBCXX20_CONSTEXPR char_type*
390 assign(char_type* __s, size_t __n, char_type __a)
391 {
392 if (__n == 0)
393 return __s;
394#ifdef __cpp_lib_is_constant_evaluated
395 if (std::is_constant_evaluated())
396 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
397#endif
398 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
399 }
400
401 static _GLIBCXX_CONSTEXPR char_type
402 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
403 { return static_cast<char_type>(__c); }
404
405 // To keep both the byte 0xff and the eof symbol 0xffffffff
406 // from ending up as 0xffffffff.
407 static _GLIBCXX_CONSTEXPR int_type
408 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
409 { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
410
411 static _GLIBCXX_CONSTEXPR bool
412 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
413 { return __c1 == __c2; }
414
415 static _GLIBCXX_CONSTEXPR int_type
416 eof() _GLIBCXX_NOEXCEPT
417 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
418
419 static _GLIBCXX_CONSTEXPR int_type
420 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
421 { return (__c == eof()) ? 0 : __c; }
422 };
423
424
425#ifdef _GLIBCXX_USE_WCHAR_T
426 /// 21.1.3.2 char_traits specializations
427 template<>
428 struct char_traits<wchar_t>
429 {
430 typedef wchar_t char_type;
431 typedef wint_t int_type;
432 typedef streamoff off_type;
433 typedef wstreampos pos_type;
434 typedef mbstate_t state_type;
435
436 static _GLIBCXX17_CONSTEXPR void
437 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
438 { __c1 = __c2; }
439
440 static _GLIBCXX_CONSTEXPR bool
441 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
442 { return __c1 == __c2; }
443
444 static _GLIBCXX_CONSTEXPR bool
445 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
446 { return __c1 < __c2; }
447
448 static _GLIBCXX17_CONSTEXPR int
449 compare(const char_type* __s1, const char_type* __s2, size_t __n)
450 {
451 if (__n == 0)
452 return 0;
453#if __cplusplus >= 201703L
454 if (__builtin_constant_p(__n)
455 && __constant_char_array_p(__s1, __n)
456 && __constant_char_array_p(__s2, __n))
457 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
458#endif
459 return wmemcmp(__s1, __s2, __n);
460 }
461
462 static _GLIBCXX17_CONSTEXPR size_t
463 length(const char_type* __s)
464 {
465#if __cplusplus >= 201703L
466 if (__constant_string_p(__s))
468#endif
469 return wcslen(__s);
470 }
471
472 static _GLIBCXX17_CONSTEXPR const char_type*
473 find(const char_type* __s, size_t __n, const char_type& __a)
474 {
475 if (__n == 0)
476 return 0;
477#if __cplusplus >= 201703L
478 if (__builtin_constant_p(__n)
479 && __builtin_constant_p(__a)
480 && __constant_char_array_p(__s, __n))
481 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
482#endif
483 return wmemchr(__s, __a, __n);
484 }
485
486 static _GLIBCXX20_CONSTEXPR char_type*
487 move(char_type* __s1, const char_type* __s2, size_t __n)
488 {
489 if (__n == 0)
490 return __s1;
491#ifdef __cpp_lib_is_constant_evaluated
492 if (std::is_constant_evaluated())
493 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
494#endif
495 return wmemmove(__s1, __s2, __n);
496 }
497
498 static _GLIBCXX20_CONSTEXPR char_type*
499 copy(char_type* __s1, const char_type* __s2, size_t __n)
500 {
501 if (__n == 0)
502 return __s1;
503#ifdef __cpp_lib_is_constant_evaluated
504 if (std::is_constant_evaluated())
505 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
506#endif
507 return wmemcpy(__s1, __s2, __n);
508 }
509
510 static _GLIBCXX20_CONSTEXPR char_type*
511 assign(char_type* __s, size_t __n, char_type __a)
512 {
513 if (__n == 0)
514 return __s;
515#ifdef __cpp_lib_is_constant_evaluated
516 if (std::is_constant_evaluated())
517 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
518#endif
519 return wmemset(__s, __a, __n);
520 }
521
522 static _GLIBCXX_CONSTEXPR char_type
523 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
524 { return char_type(__c); }
525
526 static _GLIBCXX_CONSTEXPR int_type
527 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
528 { return int_type(__c); }
529
530 static _GLIBCXX_CONSTEXPR bool
531 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
532 { return __c1 == __c2; }
533
534 static _GLIBCXX_CONSTEXPR int_type
535 eof() _GLIBCXX_NOEXCEPT
536 { return static_cast<int_type>(WEOF); }
537
538 static _GLIBCXX_CONSTEXPR int_type
539 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
540 { return eq_int_type(__c, eof()) ? 0 : __c; }
541 };
542#endif //_GLIBCXX_USE_WCHAR_T
543
544#ifdef _GLIBCXX_USE_CHAR8_T
545 template<>
546 struct char_traits<char8_t>
547 {
548 typedef char8_t char_type;
549 typedef unsigned int int_type;
550 typedef u8streampos pos_type;
551 typedef streamoff off_type;
552 typedef mbstate_t state_type;
553
554 static _GLIBCXX17_CONSTEXPR void
555 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
556 { __c1 = __c2; }
557
558 static _GLIBCXX_CONSTEXPR bool
559 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
560 { return __c1 == __c2; }
561
562 static _GLIBCXX_CONSTEXPR bool
563 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
564 { return __c1 < __c2; }
565
566 static _GLIBCXX17_CONSTEXPR int
567 compare(const char_type* __s1, const char_type* __s2, size_t __n)
568 {
569 if (__n == 0)
570 return 0;
571#if __cplusplus > 201402
572 if (__builtin_constant_p(__n)
573 && __constant_char_array_p(__s1, __n)
574 && __constant_char_array_p(__s2, __n))
575 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
576#endif
577 return __builtin_memcmp(__s1, __s2, __n);
578 }
579
580 static _GLIBCXX17_CONSTEXPR size_t
581 length(const char_type* __s)
582 {
583#if __cplusplus > 201402
584 if (__constant_string_p(__s))
586#endif
587 size_t __i = 0;
588 while (!eq(__s[__i], char_type()))
589 ++__i;
590 return __i;
591 }
592
593 static _GLIBCXX17_CONSTEXPR const char_type*
594 find(const char_type* __s, size_t __n, const char_type& __a)
595 {
596 if (__n == 0)
597 return 0;
598#if __cplusplus > 201402
599 if (__builtin_constant_p(__n)
600 && __builtin_constant_p(__a)
601 && __constant_char_array_p(__s, __n))
602 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
603#endif
604 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
605 }
606
607 static _GLIBCXX20_CONSTEXPR char_type*
608 move(char_type* __s1, const char_type* __s2, size_t __n)
609 {
610 if (__n == 0)
611 return __s1;
612#ifdef __cpp_lib_is_constant_evaluated
613 if (std::is_constant_evaluated())
614 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
615#endif
616 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
617 }
618
619 static _GLIBCXX20_CONSTEXPR char_type*
620 copy(char_type* __s1, const char_type* __s2, size_t __n)
621 {
622 if (__n == 0)
623 return __s1;
624#ifdef __cpp_lib_is_constant_evaluated
625 if (std::is_constant_evaluated())
626 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
627#endif
628 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
629 }
630
631 static _GLIBCXX20_CONSTEXPR char_type*
632 assign(char_type* __s, size_t __n, char_type __a)
633 {
634 if (__n == 0)
635 return __s;
636#ifdef __cpp_lib_is_constant_evaluated
637 if (std::is_constant_evaluated())
638 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
639#endif
640 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
641 }
642
643 static _GLIBCXX_CONSTEXPR char_type
644 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
645 { return char_type(__c); }
646
647 static _GLIBCXX_CONSTEXPR int_type
648 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
649 { return int_type(__c); }
650
651 static _GLIBCXX_CONSTEXPR bool
652 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
653 { return __c1 == __c2; }
654
655 static _GLIBCXX_CONSTEXPR int_type
656 eof() _GLIBCXX_NOEXCEPT
657 { return static_cast<int_type>(-1); }
658
659 static _GLIBCXX_CONSTEXPR int_type
660 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
661 { return eq_int_type(__c, eof()) ? 0 : __c; }
662 };
663#endif //_GLIBCXX_USE_CHAR8_T
664
665_GLIBCXX_END_NAMESPACE_VERSION
666} // namespace
667
668#if __cplusplus >= 201103L
669
670#include <cstdint>
671
672namespace std _GLIBCXX_VISIBILITY(default)
673{
674_GLIBCXX_BEGIN_NAMESPACE_VERSION
675
676 template<>
677 struct char_traits<char16_t>
678 {
679 typedef char16_t char_type;
680#ifdef _GLIBCXX_USE_C99_STDINT_TR1
681 typedef uint_least16_t int_type;
682#elif defined __UINT_LEAST16_TYPE__
683 typedef __UINT_LEAST16_TYPE__ int_type;
684#else
685 typedef make_unsigned<char16_t>::type int_type;
686#endif
687 typedef streamoff off_type;
688 typedef u16streampos pos_type;
689 typedef mbstate_t state_type;
690
691 static _GLIBCXX17_CONSTEXPR void
692 assign(char_type& __c1, const char_type& __c2) noexcept
693 { __c1 = __c2; }
694
695 static constexpr bool
696 eq(const char_type& __c1, const char_type& __c2) noexcept
697 { return __c1 == __c2; }
698
699 static constexpr bool
700 lt(const char_type& __c1, const char_type& __c2) noexcept
701 { return __c1 < __c2; }
702
703 static _GLIBCXX17_CONSTEXPR int
704 compare(const char_type* __s1, const char_type* __s2, size_t __n)
705 {
706 for (size_t __i = 0; __i < __n; ++__i)
707 if (lt(__s1[__i], __s2[__i]))
708 return -1;
709 else if (lt(__s2[__i], __s1[__i]))
710 return 1;
711 return 0;
712 }
713
714 static _GLIBCXX17_CONSTEXPR size_t
715 length(const char_type* __s)
716 {
717 size_t __i = 0;
718 while (!eq(__s[__i], char_type()))
719 ++__i;
720 return __i;
721 }
722
723 static _GLIBCXX17_CONSTEXPR const char_type*
724 find(const char_type* __s, size_t __n, const char_type& __a)
725 {
726 for (size_t __i = 0; __i < __n; ++__i)
727 if (eq(__s[__i], __a))
728 return __s + __i;
729 return 0;
730 }
731
732 static _GLIBCXX20_CONSTEXPR char_type*
733 move(char_type* __s1, const char_type* __s2, size_t __n)
734 {
735 if (__n == 0)
736 return __s1;
737#ifdef __cpp_lib_is_constant_evaluated
738 if (std::is_constant_evaluated())
739 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
740#endif
741 return (static_cast<char_type*>
742 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
743 }
744
745 static _GLIBCXX20_CONSTEXPR char_type*
746 copy(char_type* __s1, const char_type* __s2, size_t __n)
747 {
748 if (__n == 0)
749 return __s1;
750#ifdef __cpp_lib_is_constant_evaluated
751 if (std::is_constant_evaluated())
752 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
753#endif
754 return (static_cast<char_type*>
755 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
756 }
757
758 static _GLIBCXX20_CONSTEXPR char_type*
759 assign(char_type* __s, size_t __n, char_type __a)
760 {
761 for (size_t __i = 0; __i < __n; ++__i)
762 assign(__s[__i], __a);
763 return __s;
764 }
765
766 static constexpr char_type
767 to_char_type(const int_type& __c) noexcept
768 { return char_type(__c); }
769
770 static constexpr int_type
771 to_int_type(const char_type& __c) noexcept
772 { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
773
774 static constexpr bool
775 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
776 { return __c1 == __c2; }
777
778 static constexpr int_type
779 eof() noexcept
780 { return static_cast<int_type>(-1); }
781
782 static constexpr int_type
783 not_eof(const int_type& __c) noexcept
784 { return eq_int_type(__c, eof()) ? 0 : __c; }
785 };
786
787 template<>
788 struct char_traits<char32_t>
789 {
790 typedef char32_t char_type;
791#ifdef _GLIBCXX_USE_C99_STDINT_TR1
792 typedef uint_least32_t int_type;
793#elif defined __UINT_LEAST32_TYPE__
794 typedef __UINT_LEAST32_TYPE__ int_type;
795#else
796 typedef make_unsigned<char32_t>::type int_type;
797#endif
798 typedef streamoff off_type;
799 typedef u32streampos pos_type;
800 typedef mbstate_t state_type;
801
802 static _GLIBCXX17_CONSTEXPR void
803 assign(char_type& __c1, const char_type& __c2) noexcept
804 { __c1 = __c2; }
805
806 static constexpr bool
807 eq(const char_type& __c1, const char_type& __c2) noexcept
808 { return __c1 == __c2; }
809
810 static constexpr bool
811 lt(const char_type& __c1, const char_type& __c2) noexcept
812 { return __c1 < __c2; }
813
814 static _GLIBCXX17_CONSTEXPR int
815 compare(const char_type* __s1, const char_type* __s2, size_t __n)
816 {
817 for (size_t __i = 0; __i < __n; ++__i)
818 if (lt(__s1[__i], __s2[__i]))
819 return -1;
820 else if (lt(__s2[__i], __s1[__i]))
821 return 1;
822 return 0;
823 }
824
825 static _GLIBCXX17_CONSTEXPR size_t
826 length(const char_type* __s)
827 {
828 size_t __i = 0;
829 while (!eq(__s[__i], char_type()))
830 ++__i;
831 return __i;
832 }
833
834 static _GLIBCXX17_CONSTEXPR const char_type*
835 find(const char_type* __s, size_t __n, const char_type& __a)
836 {
837 for (size_t __i = 0; __i < __n; ++__i)
838 if (eq(__s[__i], __a))
839 return __s + __i;
840 return 0;
841 }
842
843 static _GLIBCXX20_CONSTEXPR char_type*
844 move(char_type* __s1, const char_type* __s2, size_t __n)
845 {
846 if (__n == 0)
847 return __s1;
848#ifdef __cpp_lib_is_constant_evaluated
849 if (std::is_constant_evaluated())
850 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
851#endif
852 return (static_cast<char_type*>
853 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
854 }
855
856 static _GLIBCXX20_CONSTEXPR char_type*
857 copy(char_type* __s1, const char_type* __s2, size_t __n)
858 {
859 if (__n == 0)
860 return __s1;
861#ifdef __cpp_lib_is_constant_evaluated
862 if (std::is_constant_evaluated())
863 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
864#endif
865 return (static_cast<char_type*>
866 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
867 }
868
869 static _GLIBCXX20_CONSTEXPR char_type*
870 assign(char_type* __s, size_t __n, char_type __a)
871 {
872 for (size_t __i = 0; __i < __n; ++__i)
873 assign(__s[__i], __a);
874 return __s;
875 }
876
877 static constexpr char_type
878 to_char_type(const int_type& __c) noexcept
879 { return char_type(__c); }
880
881 static constexpr int_type
882 to_int_type(const char_type& __c) noexcept
883 { return int_type(__c); }
884
885 static constexpr bool
886 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
887 { return __c1 == __c2; }
888
889 static constexpr int_type
890 eof() noexcept
891 { return static_cast<int_type>(-1); }
892
893 static constexpr int_type
894 not_eof(const int_type& __c) noexcept
895 { return eq_int_type(__c, eof()) ? 0 : __c; }
896 };
897
898_GLIBCXX_END_NAMESPACE_VERSION
899} // namespace
900
901#endif // C++11
902
903#endif // _CHAR_TRAITS_H
ISO C++ entities toplevel namespace is std.
fpos< mbstate_t > u32streampos
File position for char32_t streams.
Definition: postypes.h:247
long long streamoff
Type used by fpos, char_traits<char>, and char_traits<wchar_t>.
Definition: postypes.h:94
fpos< mbstate_t > u16streampos
File position for char16_t streams.
Definition: postypes.h:245
GNU extensions for public use.
Mapping from character type to associated types.
Definition: char_traits.h:63
Base class used to implement std::char_traits.
Definition: char_traits.h:88
Basis for explicit traits specializations.
Definition: char_traits.h:298
Class representing stream positions.
Definition: postypes.h:113