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 
47 namespace __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 _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 
228 namespace 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 
672 namespace 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
__gnu_cxx::_Char_types
Mapping from character type to associated types.
Definition: char_traits.h:62
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:1080
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:87
__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
cstdint
postypes.h
std::char_traits
Basis for explicit traits specializations.
Definition: char_traits.h:297