1// Character Traits for use by standard string and iostream -*- C++ -*-
2
3// Copyright (C) 1997-2018 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>
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
215namespace std _GLIBCXX_VISIBILITY(default)
216{
217_GLIBCXX_BEGIN_NAMESPACE_VERSION
218
219#if __cplusplus > 201402
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 while (__builtin_constant_p(*__s) && *__s)
234 __s++;
235 return __builtin_constant_p(*__s);
236 }
237
238 /**
239 * @brief Determine whether the characters of a character array are
240 * known at compile time.
241 * @param __a The character array.
242 * @param __n Number of characters.
243 *
244 * Assumes that _CharT is a built-in character type.
245 */
246 template<typename _CharT>
247 static _GLIBCXX_ALWAYS_INLINE constexpr bool
248 __constant_char_array_p(const _CharT* __a, size_t __n)
249 {
250 size_t __i = 0;
251 while (__i < __n && __builtin_constant_p(__a[__i]))
252 __i++;
253 return __i == __n;
254 }
255#endif
256
257 // 21.1
258 /**
259 * @brief Basis for explicit traits specializations.
260 *
261 * @note For any given actual character type, this definition is
262 * probably wrong. Since this is just a thin wrapper around
263 * __gnu_cxx::char_traits, it is possible to achieve a more
264 * appropriate definition by specializing __gnu_cxx::char_traits.
265 *
266 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
267 * for advice on how to make use of this class for @a unusual character
268 * types. Also, check out include/ext/pod_char_traits.h.
269 */
270 template<class _CharT>
271 struct char_traits : public __gnu_cxx::char_traits<_CharT>
272 { };
273
274
275 /// 21.1.3.1 char_traits specializations
276 template<>
277 struct char_traits<char>
278 {
279 typedef char char_type;
280 typedef int int_type;
281 typedef streampos pos_type;
282 typedef streamoff off_type;
283 typedef mbstate_t state_type;
284
285 static _GLIBCXX17_CONSTEXPR void
286 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
287 { __c1 = __c2; }
288
289 static _GLIBCXX_CONSTEXPR bool
290 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
291 { return __c1 == __c2; }
292
293 static _GLIBCXX_CONSTEXPR bool
294 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
295 {
296 // LWG 467.
297 return (static_cast<unsigned char>(__c1)
298 < static_cast<unsigned char>(__c2));
299 }
300
301 static _GLIBCXX17_CONSTEXPR int
302 compare(const char_type* __s1, const char_type* __s2, size_t __n)
303 {
304#if __cplusplus > 201402
305 if (__builtin_constant_p(__n)
306 && __constant_char_array_p(__s1, __n)
307 && __constant_char_array_p(__s2, __n))
308 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
309#endif
310 if (__n == 0)
311 return 0;
312 return __builtin_memcmp(__s1, __s2, __n);
313 }
314
315 static _GLIBCXX17_CONSTEXPR size_t
316 length(const char_type* __s)
317 {
318#if __cplusplus > 201402
319 if (__constant_string_p(__s))
320 return __gnu_cxx::char_traits<char_type>::length(__s);
321#endif
322 return __builtin_strlen(__s);
323 }
324
325 static _GLIBCXX17_CONSTEXPR const char_type*
326 find(const char_type* __s, size_t __n, const char_type& __a)
327 {
328#if __cplusplus > 201402
329 if (__builtin_constant_p(__n)
330 && __builtin_constant_p(__a)
331 && __constant_char_array_p(__s, __n))
332 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
333#endif
334 if (__n == 0)
335 return 0;
336 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
337 }
338
339 static char_type*
340 move(char_type* __s1, const char_type* __s2, size_t __n)
341 {
342 if (__n == 0)
343 return __s1;
344 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
345 }
346
347 static char_type*
348 copy(char_type* __s1, const char_type* __s2, size_t __n)
349 {
350 if (__n == 0)
351 return __s1;
352 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
353 }
354
355 static char_type*
356 assign(char_type* __s, size_t __n, char_type __a)
357 {
358 if (__n == 0)
359 return __s;
360 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
361 }
362
363 static _GLIBCXX_CONSTEXPR char_type
364 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
365 { return static_cast<char_type>(__c); }
366
367 // To keep both the byte 0xff and the eof symbol 0xffffffff
368 // from ending up as 0xffffffff.
369 static _GLIBCXX_CONSTEXPR int_type
370 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
371 { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
372
373 static _GLIBCXX_CONSTEXPR bool
374 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
375 { return __c1 == __c2; }
376
377 static _GLIBCXX_CONSTEXPR int_type
378 eof() _GLIBCXX_NOEXCEPT
379 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
380
381 static _GLIBCXX_CONSTEXPR int_type
382 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
383 { return (__c == eof()) ? 0 : __c; }
384 };
385
386
387#ifdef _GLIBCXX_USE_WCHAR_T
388 /// 21.1.3.2 char_traits specializations
389 template<>
390 struct char_traits<wchar_t>
391 {
392 typedef wchar_t char_type;
393 typedef wint_t int_type;
394 typedef streamoff off_type;
395 typedef wstreampos pos_type;
396 typedef mbstate_t state_type;
397
398 static _GLIBCXX17_CONSTEXPR void
399 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
400 { __c1 = __c2; }
401
402 static _GLIBCXX_CONSTEXPR bool
403 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
404 { return __c1 == __c2; }
405
406 static _GLIBCXX_CONSTEXPR bool
407 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
408 { return __c1 < __c2; }
409
410 static _GLIBCXX17_CONSTEXPR int
411 compare(const char_type* __s1, const char_type* __s2, size_t __n)
412 {
413#if __cplusplus > 201402
414 if (__builtin_constant_p(__n)
415 && __constant_char_array_p(__s1, __n)
416 && __constant_char_array_p(__s2, __n))
417 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
418#endif
419 if (__n == 0)
420 return 0;
421 else
422 return wmemcmp(__s1, __s2, __n);
423 }
424
425 static _GLIBCXX17_CONSTEXPR size_t
426 length(const char_type* __s)
427 {
428#if __cplusplus > 201402
429 if (__constant_string_p(__s))
430 return __gnu_cxx::char_traits<char_type>::length(__s);
431 else
432#endif
433 return wcslen(__s);
434 }
435
436 static _GLIBCXX17_CONSTEXPR const char_type*
437 find(const char_type* __s, size_t __n, const char_type& __a)
438 {
439#if __cplusplus > 201402
440 if (__builtin_constant_p(__n)
441 && __builtin_constant_p(__a)
442 && __constant_char_array_p(__s, __n))
443 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
444#endif
445 if (__n == 0)
446 return 0;
447 else
448 return wmemchr(__s, __a, __n);
449 }
450
451 static char_type*
452 move(char_type* __s1, const char_type* __s2, size_t __n)
453 {
454 if (__n == 0)
455 return __s1;
456 return wmemmove(__s1, __s2, __n);
457 }
458
459 static char_type*
460 copy(char_type* __s1, const char_type* __s2, size_t __n)
461 {
462 if (__n == 0)
463 return __s1;
464 return wmemcpy(__s1, __s2, __n);
465 }
466
467 static char_type*
468 assign(char_type* __s, size_t __n, char_type __a)
469 {
470 if (__n == 0)
471 return __s;
472 return wmemset(__s, __a, __n);
473 }
474
475 static _GLIBCXX_CONSTEXPR char_type
476 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
477 { return char_type(__c); }
478
479 static _GLIBCXX_CONSTEXPR int_type
480 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
481 { return int_type(__c); }
482
483 static _GLIBCXX_CONSTEXPR bool
484 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
485 { return __c1 == __c2; }
486
487 static _GLIBCXX_CONSTEXPR int_type
488 eof() _GLIBCXX_NOEXCEPT
489 { return static_cast<int_type>(WEOF); }
490
491 static _GLIBCXX_CONSTEXPR int_type
492 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
493 { return eq_int_type(__c, eof()) ? 0 : __c; }
494 };
495#endif //_GLIBCXX_USE_WCHAR_T
496
497_GLIBCXX_END_NAMESPACE_VERSION
498} // namespace
499
500#if ((__cplusplus >= 201103L) \
501 && defined(_GLIBCXX_USE_C99_STDINT_TR1))
502
503#include <cstdint>
504
505namespace std _GLIBCXX_VISIBILITY(default)
506{
507_GLIBCXX_BEGIN_NAMESPACE_VERSION
508
509 template<>
510 struct char_traits<char16_t>
511 {
512 typedef char16_t char_type;
513 typedef uint_least16_t int_type;
514 typedef streamoff off_type;
515 typedef u16streampos pos_type;
516 typedef mbstate_t state_type;
517
518 static _GLIBCXX17_CONSTEXPR void
519 assign(char_type& __c1, const char_type& __c2) noexcept
520 { __c1 = __c2; }
521
522 static constexpr bool
523 eq(const char_type& __c1, const char_type& __c2) noexcept
524 { return __c1 == __c2; }
525
526 static constexpr bool
527 lt(const char_type& __c1, const char_type& __c2) noexcept
528 { return __c1 < __c2; }
529
530 static _GLIBCXX17_CONSTEXPR int
531 compare(const char_type* __s1, const char_type* __s2, size_t __n)
532 {
533 for (size_t __i = 0; __i < __n; ++__i)
534 if (lt(__s1[__i], __s2[__i]))
535 return -1;
536 else if (lt(__s2[__i], __s1[__i]))
537 return 1;
538 return 0;
539 }
540
541 static _GLIBCXX17_CONSTEXPR size_t
542 length(const char_type* __s)
543 {
544 size_t __i = 0;
545 while (!eq(__s[__i], char_type()))
546 ++__i;
547 return __i;
548 }
549
550 static _GLIBCXX17_CONSTEXPR const char_type*
551 find(const char_type* __s, size_t __n, const char_type& __a)
552 {
553 for (size_t __i = 0; __i < __n; ++__i)
554 if (eq(__s[__i], __a))
555 return __s + __i;
556 return 0;
557 }
558
559 static char_type*
560 move(char_type* __s1, const char_type* __s2, size_t __n)
561 {
562 if (__n == 0)
563 return __s1;
564 return (static_cast<char_type*>
565 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
566 }
567
568 static char_type*
569 copy(char_type* __s1, const char_type* __s2, size_t __n)
570 {
571 if (__n == 0)
572 return __s1;
573 return (static_cast<char_type*>
574 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
575 }
576
577 static char_type*
578 assign(char_type* __s, size_t __n, char_type __a)
579 {
580 for (size_t __i = 0; __i < __n; ++__i)
581 assign(__s[__i], __a);
582 return __s;
583 }
584
585 static constexpr char_type
586 to_char_type(const int_type& __c) noexcept
587 { return char_type(__c); }
588
589 static constexpr int_type
590 to_int_type(const char_type& __c) noexcept
591 { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
592
593 static constexpr bool
594 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
595 { return __c1 == __c2; }
596
597 static constexpr int_type
598 eof() noexcept
599 { return static_cast<int_type>(-1); }
600
601 static constexpr int_type
602 not_eof(const int_type& __c) noexcept
603 { return eq_int_type(__c, eof()) ? 0 : __c; }
604 };
605
606 template<>
607 struct char_traits<char32_t>
608 {
609 typedef char32_t char_type;
610 typedef uint_least32_t int_type;
611 typedef streamoff off_type;
612 typedef u32streampos pos_type;
613 typedef mbstate_t state_type;
614
615 static _GLIBCXX17_CONSTEXPR void
616 assign(char_type& __c1, const char_type& __c2) noexcept
617 { __c1 = __c2; }
618
619 static constexpr bool
620 eq(const char_type& __c1, const char_type& __c2) noexcept
621 { return __c1 == __c2; }
622
623 static constexpr bool
624 lt(const char_type& __c1, const char_type& __c2) noexcept
625 { return __c1 < __c2; }
626
627 static _GLIBCXX17_CONSTEXPR int
628 compare(const char_type* __s1, const char_type* __s2, size_t __n)
629 {
630 for (size_t __i = 0; __i < __n; ++__i)
631 if (lt(__s1[__i], __s2[__i]))
632 return -1;
633 else if (lt(__s2[__i], __s1[__i]))
634 return 1;
635 return 0;
636 }
637
638 static _GLIBCXX17_CONSTEXPR size_t
639 length(const char_type* __s)
640 {
641 size_t __i = 0;
642 while (!eq(__s[__i], char_type()))
643 ++__i;
644 return __i;
645 }
646
647 static _GLIBCXX17_CONSTEXPR const char_type*
648 find(const char_type* __s, size_t __n, const char_type& __a)
649 {
650 for (size_t __i = 0; __i < __n; ++__i)
651 if (eq(__s[__i], __a))
652 return __s + __i;
653 return 0;
654 }
655
656 static char_type*
657 move(char_type* __s1, const char_type* __s2, size_t __n)
658 {
659 if (__n == 0)
660 return __s1;
661 return (static_cast<char_type*>
662 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
663 }
664
665 static char_type*
666 copy(char_type* __s1, const char_type* __s2, size_t __n)
667 {
668 if (__n == 0)
669 return __s1;
670 return (static_cast<char_type*>
671 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
672 }
673
674 static char_type*
675 assign(char_type* __s, size_t __n, char_type __a)
676 {
677 for (size_t __i = 0; __i < __n; ++__i)
678 assign(__s[__i], __a);
679 return __s;
680 }
681
682 static constexpr char_type
683 to_char_type(const int_type& __c) noexcept
684 { return char_type(__c); }
685
686 static constexpr int_type
687 to_int_type(const char_type& __c) noexcept
688 { return int_type(__c); }
689
690 static constexpr bool
691 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
692 { return __c1 == __c2; }
693
694 static constexpr int_type
695 eof() noexcept
696 { return static_cast<int_type>(-1); }
697
698 static constexpr int_type
699 not_eof(const int_type& __c) noexcept
700 { return eq_int_type(__c, eof()) ? 0 : __c; }
701 };
702
703_GLIBCXX_END_NAMESPACE_VERSION
704} // namespace
705
706#endif
707
708#endif // _CHAR_TRAITS_H
709