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