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-2013 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  { return __c1 < __c2; }
252 
253  static int
254  compare(const char_type* __s1, const char_type* __s2, size_t __n)
255  { return __builtin_memcmp(__s1, __s2, __n); }
256 
257  static size_t
258  length(const char_type* __s)
259  { return __builtin_strlen(__s); }
260 
261  static const char_type*
262  find(const char_type* __s, size_t __n, const char_type& __a)
263  { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
264 
265  static char_type*
266  move(char_type* __s1, const char_type* __s2, size_t __n)
267  { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
268 
269  static char_type*
270  copy(char_type* __s1, const char_type* __s2, size_t __n)
271  { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
272 
273  static char_type*
274  assign(char_type* __s, size_t __n, char_type __a)
275  { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
276 
277  static _GLIBCXX_CONSTEXPR char_type
278  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
279  { return static_cast<char_type>(__c); }
280 
281  // To keep both the byte 0xff and the eof symbol 0xffffffff
282  // from ending up as 0xffffffff.
283  static _GLIBCXX_CONSTEXPR int_type
284  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
285  { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
286 
287  static _GLIBCXX_CONSTEXPR bool
288  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
289  { return __c1 == __c2; }
290 
291  static _GLIBCXX_CONSTEXPR int_type
292  eof() _GLIBCXX_NOEXCEPT
293  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
294 
295  static _GLIBCXX_CONSTEXPR int_type
296  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
297  { return (__c == eof()) ? 0 : __c; }
298  };
299 
300 
301 #ifdef _GLIBCXX_USE_WCHAR_T
302  /// 21.1.3.2 char_traits specializations
303  template<>
304  struct char_traits<wchar_t>
305  {
306  typedef wchar_t char_type;
307  typedef wint_t int_type;
308  typedef streamoff off_type;
309  typedef wstreampos pos_type;
310  typedef mbstate_t state_type;
311 
312  static void
313  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
314  { __c1 = __c2; }
315 
316  static _GLIBCXX_CONSTEXPR bool
317  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
318  { return __c1 == __c2; }
319 
320  static _GLIBCXX_CONSTEXPR bool
321  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
322  { return __c1 < __c2; }
323 
324  static int
325  compare(const char_type* __s1, const char_type* __s2, size_t __n)
326  { return wmemcmp(__s1, __s2, __n); }
327 
328  static size_t
329  length(const char_type* __s)
330  { return wcslen(__s); }
331 
332  static const char_type*
333  find(const char_type* __s, size_t __n, const char_type& __a)
334  { return wmemchr(__s, __a, __n); }
335 
336  static char_type*
337  move(char_type* __s1, const char_type* __s2, size_t __n)
338  { return wmemmove(__s1, __s2, __n); }
339 
340  static char_type*
341  copy(char_type* __s1, const char_type* __s2, size_t __n)
342  { return wmemcpy(__s1, __s2, __n); }
343 
344  static char_type*
345  assign(char_type* __s, size_t __n, char_type __a)
346  { return wmemset(__s, __a, __n); }
347 
348  static _GLIBCXX_CONSTEXPR char_type
349  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
350  { return char_type(__c); }
351 
352  static _GLIBCXX_CONSTEXPR int_type
353  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
354  { return int_type(__c); }
355 
356  static _GLIBCXX_CONSTEXPR bool
357  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
358  { return __c1 == __c2; }
359 
360  static _GLIBCXX_CONSTEXPR int_type
361  eof() _GLIBCXX_NOEXCEPT
362  { return static_cast<int_type>(WEOF); }
363 
364  static _GLIBCXX_CONSTEXPR int_type
365  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
366  { return eq_int_type(__c, eof()) ? 0 : __c; }
367  };
368 #endif //_GLIBCXX_USE_WCHAR_T
369 
370 _GLIBCXX_END_NAMESPACE_VERSION
371 } // namespace
372 
373 #if ((__cplusplus >= 201103L) \
374  && defined(_GLIBCXX_USE_C99_STDINT_TR1))
375 
376 #include <cstdint>
377 
378 namespace std _GLIBCXX_VISIBILITY(default)
379 {
380 _GLIBCXX_BEGIN_NAMESPACE_VERSION
381 
382  template<>
383  struct char_traits<char16_t>
384  {
385  typedef char16_t char_type;
386  typedef uint_least16_t int_type;
387  typedef streamoff off_type;
388  typedef u16streampos pos_type;
389  typedef mbstate_t state_type;
390 
391  static void
392  assign(char_type& __c1, const char_type& __c2) noexcept
393  { __c1 = __c2; }
394 
395  static constexpr bool
396  eq(const char_type& __c1, const char_type& __c2) noexcept
397  { return __c1 == __c2; }
398 
399  static constexpr bool
400  lt(const char_type& __c1, const char_type& __c2) noexcept
401  { return __c1 < __c2; }
402 
403  static int
404  compare(const char_type* __s1, const char_type* __s2, size_t __n)
405  {
406  for (size_t __i = 0; __i < __n; ++__i)
407  if (lt(__s1[__i], __s2[__i]))
408  return -1;
409  else if (lt(__s2[__i], __s1[__i]))
410  return 1;
411  return 0;
412  }
413 
414  static size_t
415  length(const char_type* __s)
416  {
417  size_t __i = 0;
418  while (!eq(__s[__i], char_type()))
419  ++__i;
420  return __i;
421  }
422 
423  static const char_type*
424  find(const char_type* __s, size_t __n, const char_type& __a)
425  {
426  for (size_t __i = 0; __i < __n; ++__i)
427  if (eq(__s[__i], __a))
428  return __s + __i;
429  return 0;
430  }
431 
432  static char_type*
433  move(char_type* __s1, const char_type* __s2, size_t __n)
434  {
435  return (static_cast<char_type*>
436  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
437  }
438 
439  static char_type*
440  copy(char_type* __s1, const char_type* __s2, size_t __n)
441  {
442  return (static_cast<char_type*>
443  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
444  }
445 
446  static char_type*
447  assign(char_type* __s, size_t __n, char_type __a)
448  {
449  for (size_t __i = 0; __i < __n; ++__i)
450  assign(__s[__i], __a);
451  return __s;
452  }
453 
454  static constexpr char_type
455  to_char_type(const int_type& __c) noexcept
456  { return char_type(__c); }
457 
458  static constexpr int_type
459  to_int_type(const char_type& __c) noexcept
460  { return int_type(__c); }
461 
462  static constexpr bool
463  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
464  { return __c1 == __c2; }
465 
466  static constexpr int_type
467  eof() noexcept
468  { return static_cast<int_type>(-1); }
469 
470  static constexpr int_type
471  not_eof(const int_type& __c) noexcept
472  { return eq_int_type(__c, eof()) ? 0 : __c; }
473  };
474 
475  template<>
476  struct char_traits<char32_t>
477  {
478  typedef char32_t char_type;
479  typedef uint_least32_t int_type;
480  typedef streamoff off_type;
481  typedef u32streampos pos_type;
482  typedef mbstate_t state_type;
483 
484  static void
485  assign(char_type& __c1, const char_type& __c2) noexcept
486  { __c1 = __c2; }
487 
488  static constexpr bool
489  eq(const char_type& __c1, const char_type& __c2) noexcept
490  { return __c1 == __c2; }
491 
492  static constexpr bool
493  lt(const char_type& __c1, const char_type& __c2) noexcept
494  { return __c1 < __c2; }
495 
496  static int
497  compare(const char_type* __s1, const char_type* __s2, size_t __n)
498  {
499  for (size_t __i = 0; __i < __n; ++__i)
500  if (lt(__s1[__i], __s2[__i]))
501  return -1;
502  else if (lt(__s2[__i], __s1[__i]))
503  return 1;
504  return 0;
505  }
506 
507  static size_t
508  length(const char_type* __s)
509  {
510  size_t __i = 0;
511  while (!eq(__s[__i], char_type()))
512  ++__i;
513  return __i;
514  }
515 
516  static const char_type*
517  find(const char_type* __s, size_t __n, const char_type& __a)
518  {
519  for (size_t __i = 0; __i < __n; ++__i)
520  if (eq(__s[__i], __a))
521  return __s + __i;
522  return 0;
523  }
524 
525  static char_type*
526  move(char_type* __s1, const char_type* __s2, size_t __n)
527  {
528  return (static_cast<char_type*>
529  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
530  }
531 
532  static char_type*
533  copy(char_type* __s1, const char_type* __s2, size_t __n)
534  {
535  return (static_cast<char_type*>
536  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
537  }
538 
539  static char_type*
540  assign(char_type* __s, size_t __n, char_type __a)
541  {
542  for (size_t __i = 0; __i < __n; ++__i)
543  assign(__s[__i], __a);
544  return __s;
545  }
546 
547  static constexpr char_type
548  to_char_type(const int_type& __c) noexcept
549  { return char_type(__c); }
550 
551  static constexpr int_type
552  to_int_type(const char_type& __c) noexcept
553  { return int_type(__c); }
554 
555  static constexpr bool
556  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
557  { return __c1 == __c2; }
558 
559  static constexpr int_type
560  eof() noexcept
561  { return static_cast<int_type>(-1); }
562 
563  static constexpr int_type
564  not_eof(const int_type& __c) noexcept
565  { return eq_int_type(__c, eof()) ? 0 : __c; }
566  };
567 
568 _GLIBCXX_END_NAMESPACE_VERSION
569 } // namespace
570 
571 #endif
572 
573 #endif // _CHAR_TRAITS_H
Mapping from character type to associated types.
Definition: char_traits.h:58
_OI fill_n(_OI __first, _Size __n, const _Tp &__value)
Fills the range [first,first+n) with copies of value.
Definition: stl_algobase.h:781
Class representing stream positions.
Definition: postypes.h:112
Basis for explicit traits specializations.
Definition: char_traits.h:227
long long streamoff
Type used by fpos, char_traits, and char_traits.
Definition: postypes.h:94
GNU extensions for public use.
fpos< mbstate_t > u32streampos
File position for char32_t streams.
Definition: postypes.h:236
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:101
ISO C++ entities toplevel namespace is std.
fpos< mbstate_t > u16streampos
File position for char16_t streams.
Definition: postypes.h:234
Base class used to implement std::char_traits.
Definition: char_traits.h:83