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-2017 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 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
44 {
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 
47  /**
48  * @brief Mapping from character type to associated types.
49  *
50  * @note This is an implementation class for the generic version
51  * of char_traits. It defines int_type, off_type, pos_type, and
52  * state_type. By default these are unsigned long, streamoff,
53  * streampos, and mbstate_t. Users who need a different set of
54  * types, but who don't need to change the definitions of any function
55  * defined in char_traits, can specialize __gnu_cxx::_Char_types
56  * while leaving __gnu_cxx::char_traits alone. */
57  template<typename _CharT>
58  struct _Char_types
59  {
60  typedef unsigned long int_type;
61  typedef std::streampos pos_type;
62  typedef std::streamoff off_type;
63  typedef std::mbstate_t state_type;
64  };
65 
66 
67  /**
68  * @brief Base class used to implement std::char_traits.
69  *
70  * @note For any given actual character type, this definition is
71  * probably wrong. (Most of the member functions are likely to be
72  * right, but the int_type and state_type typedefs, and the eof()
73  * member function, are likely to be wrong.) The reason this class
74  * exists is so users can specialize it. Classes in namespace std
75  * may not be specialized for fundamental types, but classes in
76  * namespace __gnu_cxx may be.
77  *
78  * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
79  * for advice on how to make use of this class for @a unusual character
80  * types. Also, check out include/ext/pod_char_traits.h.
81  */
82  template<typename _CharT>
83  struct char_traits
84  {
85  typedef _CharT char_type;
86  typedef typename _Char_types<_CharT>::int_type int_type;
87  typedef typename _Char_types<_CharT>::pos_type pos_type;
88  typedef typename _Char_types<_CharT>::off_type off_type;
89  typedef typename _Char_types<_CharT>::state_type state_type;
90 
91  static _GLIBCXX14_CONSTEXPR void
92  assign(char_type& __c1, const char_type& __c2)
93  { __c1 = __c2; }
94 
95  static _GLIBCXX_CONSTEXPR bool
96  eq(const char_type& __c1, const char_type& __c2)
97  { return __c1 == __c2; }
98 
99  static _GLIBCXX_CONSTEXPR bool
100  lt(const char_type& __c1, const char_type& __c2)
101  { return __c1 < __c2; }
102 
103  static _GLIBCXX14_CONSTEXPR int
104  compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
105 
106  static _GLIBCXX14_CONSTEXPR std::size_t
107  length(const char_type* __s);
108 
109  static _GLIBCXX14_CONSTEXPR const char_type*
110  find(const char_type* __s, std::size_t __n, const char_type& __a);
111 
112  static char_type*
113  move(char_type* __s1, const char_type* __s2, std::size_t __n);
114 
115  static char_type*
116  copy(char_type* __s1, const char_type* __s2, std::size_t __n);
117 
118  static char_type*
119  assign(char_type* __s, std::size_t __n, char_type __a);
120 
121  static _GLIBCXX_CONSTEXPR char_type
122  to_char_type(const int_type& __c)
123  { return static_cast<char_type>(__c); }
124 
125  static _GLIBCXX_CONSTEXPR int_type
126  to_int_type(const char_type& __c)
127  { return static_cast<int_type>(__c); }
128 
129  static _GLIBCXX_CONSTEXPR bool
130  eq_int_type(const int_type& __c1, const int_type& __c2)
131  { return __c1 == __c2; }
132 
133  static _GLIBCXX_CONSTEXPR int_type
134  eof()
135  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
136 
137  static _GLIBCXX_CONSTEXPR int_type
138  not_eof(const int_type& __c)
139  { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
140  };
141 
142 // #define __cpp_lib_constexpr_char_traits 201611
143 
144  template<typename _CharT>
145  _GLIBCXX14_CONSTEXPR int
147  compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
148  {
149  for (std::size_t __i = 0; __i < __n; ++__i)
150  if (lt(__s1[__i], __s2[__i]))
151  return -1;
152  else if (lt(__s2[__i], __s1[__i]))
153  return 1;
154  return 0;
155  }
156 
157  template<typename _CharT>
158  _GLIBCXX14_CONSTEXPR std::size_t
160  length(const char_type* __p)
161  {
162  std::size_t __i = 0;
163  while (!eq(__p[__i], char_type()))
164  ++__i;
165  return __i;
166  }
167 
168  template<typename _CharT>
169  _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
171  find(const char_type* __s, std::size_t __n, const char_type& __a)
172  {
173  for (std::size_t __i = 0; __i < __n; ++__i)
174  if (eq(__s[__i], __a))
175  return __s + __i;
176  return 0;
177  }
178 
179  template<typename _CharT>
180  typename char_traits<_CharT>::char_type*
182  move(char_type* __s1, const char_type* __s2, std::size_t __n)
183  {
184  return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
185  __n * sizeof(char_type)));
186  }
187 
188  template<typename _CharT>
189  typename char_traits<_CharT>::char_type*
191  copy(char_type* __s1, const char_type* __s2, std::size_t __n)
192  {
193  // NB: Inline std::copy so no recursive dependencies.
194  std::copy(__s2, __s2 + __n, __s1);
195  return __s1;
196  }
197 
198  template<typename _CharT>
199  typename char_traits<_CharT>::char_type*
201  assign(char_type* __s, std::size_t __n, char_type __a)
202  {
203  // NB: Inline std::fill_n so no recursive dependencies.
204  std::fill_n(__s, __n, __a);
205  return __s;
206  }
207 
208 _GLIBCXX_END_NAMESPACE_VERSION
209 } // namespace
210 
211 namespace std _GLIBCXX_VISIBILITY(default)
212 {
213 _GLIBCXX_BEGIN_NAMESPACE_VERSION
214 
215  // 21.1
216  /**
217  * @brief Basis for explicit traits specializations.
218  *
219  * @note For any given actual character type, this definition is
220  * probably wrong. Since this is just a thin wrapper around
221  * __gnu_cxx::char_traits, it is possible to achieve a more
222  * appropriate definition by specializing __gnu_cxx::char_traits.
223  *
224  * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
225  * for advice on how to make use of this class for @a unusual character
226  * types. Also, check out include/ext/pod_char_traits.h.
227  */
228  template<class _CharT>
229  struct char_traits : public __gnu_cxx::char_traits<_CharT>
230  { };
231 
232 
233  /// 21.1.3.1 char_traits specializations
234  template<>
235  struct char_traits<char>
236  {
237  typedef char char_type;
238  typedef int int_type;
239  typedef streampos pos_type;
240  typedef streamoff off_type;
241  typedef mbstate_t state_type;
242 
243  static _GLIBCXX17_CONSTEXPR void
244  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
245  { __c1 = __c2; }
246 
247  static _GLIBCXX_CONSTEXPR bool
248  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
249  { return __c1 == __c2; }
250 
251  static _GLIBCXX_CONSTEXPR bool
252  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
253  {
254  // LWG 467.
255  return (static_cast<unsigned char>(__c1)
256  < static_cast<unsigned char>(__c2));
257  }
258 
259  static /* _GLIBCXX17_CONSTEXPR */ int
260  compare(const char_type* __s1, const char_type* __s2, size_t __n)
261  {
262  if (__n == 0)
263  return 0;
264  return __builtin_memcmp(__s1, __s2, __n);
265  }
266 
267  static /* _GLIBCXX17_CONSTEXPR */ size_t
268  length(const char_type* __s)
269  { return __builtin_strlen(__s); }
270 
271  static /* _GLIBCXX17_CONSTEXPR */ const char_type*
272  find(const char_type* __s, size_t __n, const char_type& __a)
273  {
274  if (__n == 0)
275  return 0;
276  return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
277  }
278 
279  static char_type*
280  move(char_type* __s1, const char_type* __s2, size_t __n)
281  {
282  if (__n == 0)
283  return __s1;
284  return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
285  }
286 
287  static char_type*
288  copy(char_type* __s1, const char_type* __s2, size_t __n)
289  {
290  if (__n == 0)
291  return __s1;
292  return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
293  }
294 
295  static char_type*
296  assign(char_type* __s, size_t __n, char_type __a)
297  {
298  if (__n == 0)
299  return __s;
300  return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
301  }
302 
303  static _GLIBCXX_CONSTEXPR char_type
304  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
305  { return static_cast<char_type>(__c); }
306 
307  // To keep both the byte 0xff and the eof symbol 0xffffffff
308  // from ending up as 0xffffffff.
309  static _GLIBCXX_CONSTEXPR int_type
310  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
311  { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
312 
313  static _GLIBCXX_CONSTEXPR bool
314  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
315  { return __c1 == __c2; }
316 
317  static _GLIBCXX_CONSTEXPR int_type
318  eof() _GLIBCXX_NOEXCEPT
319  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
320 
321  static _GLIBCXX_CONSTEXPR int_type
322  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
323  { return (__c == eof()) ? 0 : __c; }
324  };
325 
326 
327 #ifdef _GLIBCXX_USE_WCHAR_T
328  /// 21.1.3.2 char_traits specializations
329  template<>
330  struct char_traits<wchar_t>
331  {
332  typedef wchar_t char_type;
333  typedef wint_t int_type;
334  typedef streamoff off_type;
335  typedef wstreampos pos_type;
336  typedef mbstate_t state_type;
337 
338  static _GLIBCXX17_CONSTEXPR void
339  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
340  { __c1 = __c2; }
341 
342  static _GLIBCXX_CONSTEXPR bool
343  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
344  { return __c1 == __c2; }
345 
346  static _GLIBCXX_CONSTEXPR bool
347  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
348  { return __c1 < __c2; }
349 
350  static /* _GLIBCXX17_CONSTEXPR */ int
351  compare(const char_type* __s1, const char_type* __s2, size_t __n)
352  {
353  if (__n == 0)
354  return 0;
355  return wmemcmp(__s1, __s2, __n);
356  }
357 
358  static /* _GLIBCXX17_CONSTEXPR */ size_t
359  length(const char_type* __s)
360  { return wcslen(__s); }
361 
362  static /* _GLIBCXX17_CONSTEXPR */ const char_type*
363  find(const char_type* __s, size_t __n, const char_type& __a)
364  {
365  if (__n == 0)
366  return 0;
367  return wmemchr(__s, __a, __n);
368  }
369 
370  static char_type*
371  move(char_type* __s1, const char_type* __s2, size_t __n)
372  {
373  if (__n == 0)
374  return __s1;
375  return wmemmove(__s1, __s2, __n);
376  }
377 
378  static char_type*
379  copy(char_type* __s1, const char_type* __s2, size_t __n)
380  {
381  if (__n == 0)
382  return __s1;
383  return wmemcpy(__s1, __s2, __n);
384  }
385 
386  static char_type*
387  assign(char_type* __s, size_t __n, char_type __a)
388  {
389  if (__n == 0)
390  return __s;
391  return wmemset(__s, __a, __n);
392  }
393 
394  static _GLIBCXX_CONSTEXPR char_type
395  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
396  { return char_type(__c); }
397 
398  static _GLIBCXX_CONSTEXPR int_type
399  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
400  { return int_type(__c); }
401 
402  static _GLIBCXX_CONSTEXPR bool
403  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
404  { return __c1 == __c2; }
405 
406  static _GLIBCXX_CONSTEXPR int_type
407  eof() _GLIBCXX_NOEXCEPT
408  { return static_cast<int_type>(WEOF); }
409 
410  static _GLIBCXX_CONSTEXPR int_type
411  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
412  { return eq_int_type(__c, eof()) ? 0 : __c; }
413  };
414 #endif //_GLIBCXX_USE_WCHAR_T
415 
416 _GLIBCXX_END_NAMESPACE_VERSION
417 } // namespace
418 
419 #if ((__cplusplus >= 201103L) \
420  && defined(_GLIBCXX_USE_C99_STDINT_TR1))
421 
422 #include <cstdint>
423 
424 namespace std _GLIBCXX_VISIBILITY(default)
425 {
426 _GLIBCXX_BEGIN_NAMESPACE_VERSION
427 
428  template<>
429  struct char_traits<char16_t>
430  {
431  typedef char16_t char_type;
432  typedef uint_least16_t int_type;
433  typedef streamoff off_type;
434  typedef u16streampos pos_type;
435  typedef mbstate_t state_type;
436 
437  static _GLIBCXX17_CONSTEXPR void
438  assign(char_type& __c1, const char_type& __c2) noexcept
439  { __c1 = __c2; }
440 
441  static constexpr bool
442  eq(const char_type& __c1, const char_type& __c2) noexcept
443  { return __c1 == __c2; }
444 
445  static constexpr bool
446  lt(const char_type& __c1, const char_type& __c2) noexcept
447  { return __c1 < __c2; }
448 
449  static _GLIBCXX17_CONSTEXPR int
450  compare(const char_type* __s1, const char_type* __s2, size_t __n)
451  {
452  for (size_t __i = 0; __i < __n; ++__i)
453  if (lt(__s1[__i], __s2[__i]))
454  return -1;
455  else if (lt(__s2[__i], __s1[__i]))
456  return 1;
457  return 0;
458  }
459 
460  static _GLIBCXX17_CONSTEXPR size_t
461  length(const char_type* __s)
462  {
463  size_t __i = 0;
464  while (!eq(__s[__i], char_type()))
465  ++__i;
466  return __i;
467  }
468 
469  static _GLIBCXX17_CONSTEXPR const char_type*
470  find(const char_type* __s, size_t __n, const char_type& __a)
471  {
472  for (size_t __i = 0; __i < __n; ++__i)
473  if (eq(__s[__i], __a))
474  return __s + __i;
475  return 0;
476  }
477 
478  static char_type*
479  move(char_type* __s1, const char_type* __s2, size_t __n)
480  {
481  if (__n == 0)
482  return __s1;
483  return (static_cast<char_type*>
484  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
485  }
486 
487  static char_type*
488  copy(char_type* __s1, const char_type* __s2, size_t __n)
489  {
490  if (__n == 0)
491  return __s1;
492  return (static_cast<char_type*>
493  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
494  }
495 
496  static char_type*
497  assign(char_type* __s, size_t __n, char_type __a)
498  {
499  for (size_t __i = 0; __i < __n; ++__i)
500  assign(__s[__i], __a);
501  return __s;
502  }
503 
504  static constexpr char_type
505  to_char_type(const int_type& __c) noexcept
506  { return char_type(__c); }
507 
508  static constexpr int_type
509  to_int_type(const char_type& __c) noexcept
510  { return int_type(__c); }
511 
512  static constexpr bool
513  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
514  { return __c1 == __c2; }
515 
516  static constexpr int_type
517  eof() noexcept
518  { return static_cast<int_type>(-1); }
519 
520  static constexpr int_type
521  not_eof(const int_type& __c) noexcept
522  { return eq_int_type(__c, eof()) ? 0 : __c; }
523  };
524 
525  template<>
526  struct char_traits<char32_t>
527  {
528  typedef char32_t char_type;
529  typedef uint_least32_t int_type;
530  typedef streamoff off_type;
531  typedef u32streampos pos_type;
532  typedef mbstate_t state_type;
533 
534  static _GLIBCXX17_CONSTEXPR void
535  assign(char_type& __c1, const char_type& __c2) noexcept
536  { __c1 = __c2; }
537 
538  static constexpr bool
539  eq(const char_type& __c1, const char_type& __c2) noexcept
540  { return __c1 == __c2; }
541 
542  static constexpr bool
543  lt(const char_type& __c1, const char_type& __c2) noexcept
544  { return __c1 < __c2; }
545 
546  static _GLIBCXX17_CONSTEXPR int
547  compare(const char_type* __s1, const char_type* __s2, size_t __n)
548  {
549  for (size_t __i = 0; __i < __n; ++__i)
550  if (lt(__s1[__i], __s2[__i]))
551  return -1;
552  else if (lt(__s2[__i], __s1[__i]))
553  return 1;
554  return 0;
555  }
556 
557  static _GLIBCXX17_CONSTEXPR size_t
558  length(const char_type* __s)
559  {
560  size_t __i = 0;
561  while (!eq(__s[__i], char_type()))
562  ++__i;
563  return __i;
564  }
565 
566  static _GLIBCXX17_CONSTEXPR const char_type*
567  find(const char_type* __s, size_t __n, const char_type& __a)
568  {
569  for (size_t __i = 0; __i < __n; ++__i)
570  if (eq(__s[__i], __a))
571  return __s + __i;
572  return 0;
573  }
574 
575  static char_type*
576  move(char_type* __s1, const char_type* __s2, size_t __n)
577  {
578  if (__n == 0)
579  return __s1;
580  return (static_cast<char_type*>
581  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
582  }
583 
584  static char_type*
585  copy(char_type* __s1, const char_type* __s2, size_t __n)
586  {
587  if (__n == 0)
588  return __s1;
589  return (static_cast<char_type*>
590  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
591  }
592 
593  static char_type*
594  assign(char_type* __s, size_t __n, char_type __a)
595  {
596  for (size_t __i = 0; __i < __n; ++__i)
597  assign(__s[__i], __a);
598  return __s;
599  }
600 
601  static constexpr char_type
602  to_char_type(const int_type& __c) noexcept
603  { return char_type(__c); }
604 
605  static constexpr int_type
606  to_int_type(const char_type& __c) noexcept
607  { return int_type(__c); }
608 
609  static constexpr bool
610  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
611  { return __c1 == __c2; }
612 
613  static constexpr int_type
614  eof() noexcept
615  { return static_cast<int_type>(-1); }
616 
617  static constexpr int_type
618  not_eof(const int_type& __c) noexcept
619  { return eq_int_type(__c, eof()) ? 0 : __c; }
620  };
621 
622 _GLIBCXX_END_NAMESPACE_VERSION
623 } // namespace
624 
625 #endif
626 
627 #endif // _CHAR_TRAITS_H
Base class used to implement std::char_traits.
Definition: char_traits.h:83
ISO C++ entities toplevel namespace is std.
GNU extensions for public use.
Mapping from character type to associated types.
Definition: char_traits.h:58
Class representing stream positions.
Definition: postypes.h:112
Basis for explicit traits specializations.
Definition: char_traits.h:229
long long streamoff
Type used by fpos, char_traits<char>, and char_traits<wchar_t>.
Definition: postypes.h:94