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