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-2014 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 http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
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 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 int
104  compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
105 
106  static std::size_t
107  length(const char_type* __s);
108 
109  static 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  template<typename _CharT>
143  int
145  compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
146  {
147  for (std::size_t __i = 0; __i < __n; ++__i)
148  if (lt(__s1[__i], __s2[__i]))
149  return -1;
150  else if (lt(__s2[__i], __s1[__i]))
151  return 1;
152  return 0;
153  }
154 
155  template<typename _CharT>
156  std::size_t
157  char_traits<_CharT>::
158  length(const char_type* __p)
159  {
160  std::size_t __i = 0;
161  while (!eq(__p[__i], char_type()))
162  ++__i;
163  return __i;
164  }
165 
166  template<typename _CharT>
167  const typename char_traits<_CharT>::char_type*
168  char_traits<_CharT>::
169  find(const char_type* __s, std::size_t __n, const char_type& __a)
170  {
171  for (std::size_t __i = 0; __i < __n; ++__i)
172  if (eq(__s[__i], __a))
173  return __s + __i;
174  return 0;
175  }
176 
177  template<typename _CharT>
178  typename char_traits<_CharT>::char_type*
180  move(char_type* __s1, const char_type* __s2, std::size_t __n)
181  {
182  return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
183  __n * sizeof(char_type)));
184  }
185 
186  template<typename _CharT>
187  typename char_traits<_CharT>::char_type*
188  char_traits<_CharT>::
189  copy(char_type* __s1, const char_type* __s2, std::size_t __n)
190  {
191  // NB: Inline std::copy so no recursive dependencies.
192  std::copy(__s2, __s2 + __n, __s1);
193  return __s1;
194  }
195 
196  template<typename _CharT>
197  typename char_traits<_CharT>::char_type*
198  char_traits<_CharT>::
199  assign(char_type* __s, std::size_t __n, char_type __a)
200  {
201  // NB: Inline std::fill_n so no recursive dependencies.
202  std::fill_n(__s, __n, __a);
203  return __s;
204  }
205 
206 _GLIBCXX_END_NAMESPACE_VERSION
207 } // namespace
208 
209 namespace std _GLIBCXX_VISIBILITY(default)
210 {
211 _GLIBCXX_BEGIN_NAMESPACE_VERSION
212 
213  // 21.1
214  /**
215  * @brief Basis for explicit traits specializations.
216  *
217  * @note For any given actual character type, this definition is
218  * probably wrong. Since this is just a thin wrapper around
219  * __gnu_cxx::char_traits, it is possible to achieve a more
220  * appropriate definition by specializing __gnu_cxx::char_traits.
221  *
222  * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
223  * for advice on how to make use of this class for @a unusual character
224  * types. Also, check out include/ext/pod_char_traits.h.
225  */
226  template<class _CharT>
227  struct char_traits : public __gnu_cxx::char_traits<_CharT>
228  { };
229 
230 
231  /// 21.1.3.1 char_traits specializations
232  template<>
233  struct char_traits<char>
234  {
235  typedef char char_type;
236  typedef int int_type;
237  typedef streampos pos_type;
238  typedef streamoff off_type;
239  typedef mbstate_t state_type;
240 
241  static void
242  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
243  { __c1 = __c2; }
244 
245  static _GLIBCXX_CONSTEXPR bool
246  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
247  { return __c1 == __c2; }
248 
249  static _GLIBCXX_CONSTEXPR bool
250  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
251  {
252  // LWG 467.
253  return (static_cast<unsigned char>(__c1)
254  < static_cast<unsigned char>(__c2));
255  }
256 
257  static int
258  compare(const char_type* __s1, const char_type* __s2, size_t __n)
259  { return __builtin_memcmp(__s1, __s2, __n); }
260 
261  static size_t
262  length(const char_type* __s)
263  { return __builtin_strlen(__s); }
264 
265  static const char_type*
266  find(const char_type* __s, size_t __n, const char_type& __a)
267  { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
268 
269  static char_type*
270  move(char_type* __s1, const char_type* __s2, size_t __n)
271  { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
272 
273  static char_type*
274  copy(char_type* __s1, const char_type* __s2, size_t __n)
275  { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
276 
277  static char_type*
278  assign(char_type* __s, size_t __n, char_type __a)
279  { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
280 
281  static _GLIBCXX_CONSTEXPR char_type
282  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
283  { return static_cast<char_type>(__c); }
284 
285  // To keep both the byte 0xff and the eof symbol 0xffffffff
286  // from ending up as 0xffffffff.
287  static _GLIBCXX_CONSTEXPR int_type
288  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
289  { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
290 
291  static _GLIBCXX_CONSTEXPR bool
292  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
293  { return __c1 == __c2; }
294 
295  static _GLIBCXX_CONSTEXPR int_type
296  eof() _GLIBCXX_NOEXCEPT
297  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
298 
299  static _GLIBCXX_CONSTEXPR int_type
300  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
301  { return (__c == eof()) ? 0 : __c; }
302  };
303 
304 
305 #ifdef _GLIBCXX_USE_WCHAR_T
306  /// 21.1.3.2 char_traits specializations
307  template<>
308  struct char_traits<wchar_t>
309  {
310  typedef wchar_t char_type;
311  typedef wint_t int_type;
312  typedef streamoff off_type;
313  typedef wstreampos pos_type;
314  typedef mbstate_t state_type;
315 
316  static void
317  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
318  { __c1 = __c2; }
319 
320  static _GLIBCXX_CONSTEXPR bool
321  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
322  { return __c1 == __c2; }
323 
324  static _GLIBCXX_CONSTEXPR bool
325  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
326  { return __c1 < __c2; }
327 
328  static int
329  compare(const char_type* __s1, const char_type* __s2, size_t __n)
330  { return wmemcmp(__s1, __s2, __n); }
331 
332  static size_t
333  length(const char_type* __s)
334  { return wcslen(__s); }
335 
336  static const char_type*
337  find(const char_type* __s, size_t __n, const char_type& __a)
338  { return wmemchr(__s, __a, __n); }
339 
340  static char_type*
341  move(char_type* __s1, const char_type* __s2, size_t __n)
342  { return wmemmove(__s1, __s2, __n); }
343 
344  static char_type*
345  copy(char_type* __s1, const char_type* __s2, size_t __n)
346  { return wmemcpy(__s1, __s2, __n); }
347 
348  static char_type*
349  assign(char_type* __s, size_t __n, char_type __a)
350  { return wmemset(__s, __a, __n); }
351 
352  static _GLIBCXX_CONSTEXPR char_type
353  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
354  { return char_type(__c); }
355 
356  static _GLIBCXX_CONSTEXPR int_type
357  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
358  { return int_type(__c); }
359 
360  static _GLIBCXX_CONSTEXPR bool
361  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
362  { return __c1 == __c2; }
363 
364  static _GLIBCXX_CONSTEXPR int_type
365  eof() _GLIBCXX_NOEXCEPT
366  { return static_cast<int_type>(WEOF); }
367 
368  static _GLIBCXX_CONSTEXPR int_type
369  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
370  { return eq_int_type(__c, eof()) ? 0 : __c; }
371  };
372 #endif //_GLIBCXX_USE_WCHAR_T
373 
374 _GLIBCXX_END_NAMESPACE_VERSION
375 } // namespace
376 
377 #if ((__cplusplus >= 201103L) \
378  && defined(_GLIBCXX_USE_C99_STDINT_TR1))
379 
380 #include <cstdint>
381 
382 namespace std _GLIBCXX_VISIBILITY(default)
383 {
384 _GLIBCXX_BEGIN_NAMESPACE_VERSION
385 
386  template<>
387  struct char_traits<char16_t>
388  {
389  typedef char16_t char_type;
390  typedef uint_least16_t int_type;
391  typedef streamoff off_type;
392  typedef u16streampos pos_type;
393  typedef mbstate_t state_type;
394 
395  static void
396  assign(char_type& __c1, const char_type& __c2) noexcept
397  { __c1 = __c2; }
398 
399  static constexpr bool
400  eq(const char_type& __c1, const char_type& __c2) noexcept
401  { return __c1 == __c2; }
402 
403  static constexpr bool
404  lt(const char_type& __c1, const char_type& __c2) noexcept
405  { return __c1 < __c2; }
406 
407  static int
408  compare(const char_type* __s1, const char_type* __s2, size_t __n)
409  {
410  for (size_t __i = 0; __i < __n; ++__i)
411  if (lt(__s1[__i], __s2[__i]))
412  return -1;
413  else if (lt(__s2[__i], __s1[__i]))
414  return 1;
415  return 0;
416  }
417 
418  static size_t
419  length(const char_type* __s)
420  {
421  size_t __i = 0;
422  while (!eq(__s[__i], char_type()))
423  ++__i;
424  return __i;
425  }
426 
427  static const char_type*
428  find(const char_type* __s, size_t __n, const char_type& __a)
429  {
430  for (size_t __i = 0; __i < __n; ++__i)
431  if (eq(__s[__i], __a))
432  return __s + __i;
433  return 0;
434  }
435 
436  static char_type*
437  move(char_type* __s1, const char_type* __s2, size_t __n)
438  {
439  return (static_cast<char_type*>
440  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
441  }
442 
443  static char_type*
444  copy(char_type* __s1, const char_type* __s2, size_t __n)
445  {
446  return (static_cast<char_type*>
447  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
448  }
449 
450  static char_type*
451  assign(char_type* __s, size_t __n, char_type __a)
452  {
453  for (size_t __i = 0; __i < __n; ++__i)
454  assign(__s[__i], __a);
455  return __s;
456  }
457 
458  static constexpr char_type
459  to_char_type(const int_type& __c) noexcept
460  { return char_type(__c); }
461 
462  static constexpr int_type
463  to_int_type(const char_type& __c) noexcept
464  { return int_type(__c); }
465 
466  static constexpr bool
467  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
468  { return __c1 == __c2; }
469 
470  static constexpr int_type
471  eof() noexcept
472  { return static_cast<int_type>(-1); }
473 
474  static constexpr int_type
475  not_eof(const int_type& __c) noexcept
476  { return eq_int_type(__c, eof()) ? 0 : __c; }
477  };
478 
479  template<>
480  struct char_traits<char32_t>
481  {
482  typedef char32_t char_type;
483  typedef uint_least32_t int_type;
484  typedef streamoff off_type;
485  typedef u32streampos pos_type;
486  typedef mbstate_t state_type;
487 
488  static void
489  assign(char_type& __c1, const char_type& __c2) noexcept
490  { __c1 = __c2; }
491 
492  static constexpr bool
493  eq(const char_type& __c1, const char_type& __c2) noexcept
494  { return __c1 == __c2; }
495 
496  static constexpr bool
497  lt(const char_type& __c1, const char_type& __c2) noexcept
498  { return __c1 < __c2; }
499 
500  static int
501  compare(const char_type* __s1, const char_type* __s2, size_t __n)
502  {
503  for (size_t __i = 0; __i < __n; ++__i)
504  if (lt(__s1[__i], __s2[__i]))
505  return -1;
506  else if (lt(__s2[__i], __s1[__i]))
507  return 1;
508  return 0;
509  }
510 
511  static size_t
512  length(const char_type* __s)
513  {
514  size_t __i = 0;
515  while (!eq(__s[__i], char_type()))
516  ++__i;
517  return __i;
518  }
519 
520  static const char_type*
521  find(const char_type* __s, size_t __n, const char_type& __a)
522  {
523  for (size_t __i = 0; __i < __n; ++__i)
524  if (eq(__s[__i], __a))
525  return __s + __i;
526  return 0;
527  }
528 
529  static char_type*
530  move(char_type* __s1, const char_type* __s2, size_t __n)
531  {
532  return (static_cast<char_type*>
533  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
534  }
535 
536  static char_type*
537  copy(char_type* __s1, const char_type* __s2, size_t __n)
538  {
539  return (static_cast<char_type*>
540  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
541  }
542 
543  static char_type*
544  assign(char_type* __s, size_t __n, char_type __a)
545  {
546  for (size_t __i = 0; __i < __n; ++__i)
547  assign(__s[__i], __a);
548  return __s;
549  }
550 
551  static constexpr char_type
552  to_char_type(const int_type& __c) noexcept
553  { return char_type(__c); }
554 
555  static constexpr int_type
556  to_int_type(const char_type& __c) noexcept
557  { return int_type(__c); }
558 
559  static constexpr bool
560  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
561  { return __c1 == __c2; }
562 
563  static constexpr int_type
564  eof() noexcept
565  { return static_cast<int_type>(-1); }
566 
567  static constexpr int_type
568  not_eof(const int_type& __c) noexcept
569  { return eq_int_type(__c, eof()) ? 0 : __c; }
570  };
571 
572 _GLIBCXX_END_NAMESPACE_VERSION
573 } // namespace
574 
575 #endif
576 
577 #endif // _CHAR_TRAITS_H
Mapping from character type to associated types.
Definition: char_traits.h:58
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:101
GNU extensions for public use.
long long streamoff
Type used by fpos, char_traits, and char_traits.
Definition: postypes.h:94
ISO C++ entities toplevel namespace is std.
Base class used to implement std::char_traits.
Definition: char_traits.h:83
Basis for explicit traits specializations.
Definition: char_traits.h:227
_OI fill_n(_OI __first, _Size __n, const _Tp &__value)
Fills the range [first,first+n) with copies of value.
Definition: stl_algobase.h:792
Class representing stream positions.
Definition: postypes.h:112
fpos< mbstate_t > u16streampos
File position for char16_t streams.
Definition: postypes.h:234
fpos< mbstate_t > u32streampos
File position for char32_t streams.
Definition: postypes.h:236