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, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 // 2006, 2007, 2008, 2009, 2010, 2011
5 // Free Software Foundation, Inc.
6 //
7 // This file is part of the GNU ISO C++ Library. This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
11 // any later version.
12 
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 
18 // Under Section 7 of GPL version 3, you are granted additional
19 // permissions described in the GCC Runtime Library Exception, version
20 // 3.1, as published by the Free Software Foundation.
21 
22 // You should have received a copy of the GNU General Public License and
23 // a copy of the GCC Runtime Library Exception along with this program;
24 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 // <http://www.gnu.org/licenses/>.
26 
27 /** @file bits/char_traits.h
28  * This is an internal header file, included by other library headers.
29  * Do not attempt to use it directly. @headername{string}
30  */
31 
32 //
33 // ISO C++ 14882: 21 Strings library
34 //
35 
36 #ifndef _CHAR_TRAITS_H
37 #define _CHAR_TRAITS_H 1
38 
39 #pragma GCC system_header
40 
41 #include <bits/stl_algobase.h> // std::copy, std::fill_n
42 #include <bits/postypes.h> // For streampos
43 #include <cwchar> // For WEOF, wmemmove, wmemset, etc.
44 
45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
46 {
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 
49  /**
50  * @brief Mapping from character type to associated types.
51  *
52  * @note This is an implementation class for the generic version
53  * of char_traits. It defines int_type, off_type, pos_type, and
54  * state_type. By default these are unsigned long, streamoff,
55  * streampos, and mbstate_t. Users who need a different set of
56  * types, but who don't need to change the definitions of any function
57  * defined in char_traits, can specialize __gnu_cxx::_Char_types
58  * while leaving __gnu_cxx::char_traits alone. */
59  template<typename _CharT>
60  struct _Char_types
61  {
62  typedef unsigned long int_type;
63  typedef std::streampos pos_type;
64  typedef std::streamoff off_type;
65  typedef std::mbstate_t state_type;
66  };
67 
68 
69  /**
70  * @brief Base class used to implement std::char_traits.
71  *
72  * @note For any given actual character type, this definition is
73  * probably wrong. (Most of the member functions are likely to be
74  * right, but the int_type and state_type typedefs, and the eof()
75  * member function, are likely to be wrong.) The reason this class
76  * exists is so users can specialize it. Classes in namespace std
77  * may not be specialized for fundamental types, but classes in
78  * namespace __gnu_cxx may be.
79  *
80  * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
81  * for advice on how to make use of this class for @a unusual character
82  * types. Also, check out include/ext/pod_char_traits.h.
83  */
84  template<typename _CharT>
85  struct char_traits
86  {
87  typedef _CharT char_type;
88  typedef typename _Char_types<_CharT>::int_type int_type;
89  typedef typename _Char_types<_CharT>::pos_type pos_type;
90  typedef typename _Char_types<_CharT>::off_type off_type;
91  typedef typename _Char_types<_CharT>::state_type state_type;
92 
93  static void
94  assign(char_type& __c1, const char_type& __c2)
95  { __c1 = __c2; }
96 
97  static _GLIBCXX_CONSTEXPR bool
98  eq(const char_type& __c1, const char_type& __c2)
99  { return __c1 == __c2; }
100 
101  static _GLIBCXX_CONSTEXPR bool
102  lt(const char_type& __c1, const char_type& __c2)
103  { return __c1 < __c2; }
104 
105  static int
106  compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
107 
108  static std::size_t
109  length(const char_type* __s);
110 
111  static const char_type*
112  find(const char_type* __s, std::size_t __n, const char_type& __a);
113 
114  static char_type*
115  move(char_type* __s1, const char_type* __s2, std::size_t __n);
116 
117  static char_type*
118  copy(char_type* __s1, const char_type* __s2, std::size_t __n);
119 
120  static char_type*
121  assign(char_type* __s, std::size_t __n, char_type __a);
122 
123  static _GLIBCXX_CONSTEXPR char_type
124  to_char_type(const int_type& __c)
125  { return static_cast<char_type>(__c); }
126 
127  static _GLIBCXX_CONSTEXPR int_type
128  to_int_type(const char_type& __c)
129  { return static_cast<int_type>(__c); }
130 
131  static _GLIBCXX_CONSTEXPR bool
132  eq_int_type(const int_type& __c1, const int_type& __c2)
133  { return __c1 == __c2; }
134 
135  static _GLIBCXX_CONSTEXPR int_type
136  eof()
137  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
138 
139  static _GLIBCXX_CONSTEXPR int_type
140  not_eof(const int_type& __c)
141  { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
142  };
143 
144  template<typename _CharT>
145  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  std::size_t
159  char_traits<_CharT>::
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  const typename char_traits<_CharT>::char_type*
170  char_traits<_CharT>::
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*
181  char_traits<_CharT>::
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*
190  char_traits<_CharT>::
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*
200  char_traits<_CharT>::
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 http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
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 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  { return __c1 < __c2; }
254 
255  static int
256  compare(const char_type* __s1, const char_type* __s2, size_t __n)
257  { return __builtin_memcmp(__s1, __s2, __n); }
258 
259  static size_t
260  length(const char_type* __s)
261  { return __builtin_strlen(__s); }
262 
263  static const char_type*
264  find(const char_type* __s, size_t __n, const char_type& __a)
265  { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
266 
267  static char_type*
268  move(char_type* __s1, const char_type* __s2, size_t __n)
269  { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
270 
271  static char_type*
272  copy(char_type* __s1, const char_type* __s2, size_t __n)
273  { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
274 
275  static char_type*
276  assign(char_type* __s, size_t __n, char_type __a)
277  { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
278 
279  static _GLIBCXX_CONSTEXPR char_type
280  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
281  { return static_cast<char_type>(__c); }
282 
283  // To keep both the byte 0xff and the eof symbol 0xffffffff
284  // from ending up as 0xffffffff.
285  static _GLIBCXX_CONSTEXPR int_type
286  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
287  { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
288 
289  static _GLIBCXX_CONSTEXPR bool
290  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
291  { return __c1 == __c2; }
292 
293  static _GLIBCXX_CONSTEXPR int_type
294  eof() _GLIBCXX_NOEXCEPT
295  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
296 
297  static _GLIBCXX_CONSTEXPR int_type
298  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
299  { return (__c == eof()) ? 0 : __c; }
300  };
301 
302 
303 #ifdef _GLIBCXX_USE_WCHAR_T
304  /// 21.1.3.2 char_traits specializations
305  template<>
306  struct char_traits<wchar_t>
307  {
308  typedef wchar_t char_type;
309  typedef wint_t int_type;
310  typedef streamoff off_type;
311  typedef wstreampos pos_type;
312  typedef mbstate_t state_type;
313 
314  static void
315  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
316  { __c1 = __c2; }
317 
318  static _GLIBCXX_CONSTEXPR bool
319  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
320  { return __c1 == __c2; }
321 
322  static _GLIBCXX_CONSTEXPR bool
323  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
324  { return __c1 < __c2; }
325 
326  static int
327  compare(const char_type* __s1, const char_type* __s2, size_t __n)
328  { return wmemcmp(__s1, __s2, __n); }
329 
330  static size_t
331  length(const char_type* __s)
332  { return wcslen(__s); }
333 
334  static const char_type*
335  find(const char_type* __s, size_t __n, const char_type& __a)
336  { return wmemchr(__s, __a, __n); }
337 
338  static char_type*
339  move(char_type* __s1, const char_type* __s2, size_t __n)
340  { return wmemmove(__s1, __s2, __n); }
341 
342  static char_type*
343  copy(char_type* __s1, const char_type* __s2, size_t __n)
344  { return wmemcpy(__s1, __s2, __n); }
345 
346  static char_type*
347  assign(char_type* __s, size_t __n, char_type __a)
348  { return wmemset(__s, __a, __n); }
349 
350  static _GLIBCXX_CONSTEXPR char_type
351  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
352  { return char_type(__c); }
353 
354  static _GLIBCXX_CONSTEXPR int_type
355  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
356  { return int_type(__c); }
357 
358  static _GLIBCXX_CONSTEXPR bool
359  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
360  { return __c1 == __c2; }
361 
362  static _GLIBCXX_CONSTEXPR int_type
363  eof() _GLIBCXX_NOEXCEPT
364  { return static_cast<int_type>(WEOF); }
365 
366  static _GLIBCXX_CONSTEXPR int_type
367  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
368  { return eq_int_type(__c, eof()) ? 0 : __c; }
369  };
370 #endif //_GLIBCXX_USE_WCHAR_T
371 
372 _GLIBCXX_END_NAMESPACE_VERSION
373 } // namespace
374 
375 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
376  && defined(_GLIBCXX_USE_C99_STDINT_TR1))
377 
378 #include <cstdint>
379 
380 namespace std _GLIBCXX_VISIBILITY(default)
381 {
382 _GLIBCXX_BEGIN_NAMESPACE_VERSION
383 
384  template<>
385  struct char_traits<char16_t>
386  {
387  typedef char16_t char_type;
388  typedef uint_least16_t int_type;
389  typedef streamoff off_type;
390  typedef u16streampos pos_type;
391  typedef mbstate_t state_type;
392 
393  static void
394  assign(char_type& __c1, const char_type& __c2) noexcept
395  { __c1 = __c2; }
396 
397  static constexpr bool
398  eq(const char_type& __c1, const char_type& __c2) noexcept
399  { return __c1 == __c2; }
400 
401  static constexpr bool
402  lt(const char_type& __c1, const char_type& __c2) noexcept
403  { return __c1 < __c2; }
404 
405  static int
406  compare(const char_type* __s1, const char_type* __s2, size_t __n)
407  {
408  for (size_t __i = 0; __i < __n; ++__i)
409  if (lt(__s1[__i], __s2[__i]))
410  return -1;
411  else if (lt(__s2[__i], __s1[__i]))
412  return 1;
413  return 0;
414  }
415 
416  static size_t
417  length(const char_type* __s)
418  {
419  size_t __i = 0;
420  while (!eq(__s[__i], char_type()))
421  ++__i;
422  return __i;
423  }
424 
425  static const char_type*
426  find(const char_type* __s, size_t __n, const char_type& __a)
427  {
428  for (size_t __i = 0; __i < __n; ++__i)
429  if (eq(__s[__i], __a))
430  return __s + __i;
431  return 0;
432  }
433 
434  static char_type*
435  move(char_type* __s1, const char_type* __s2, size_t __n)
436  {
437  return (static_cast<char_type*>
438  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
439  }
440 
441  static char_type*
442  copy(char_type* __s1, const char_type* __s2, size_t __n)
443  {
444  return (static_cast<char_type*>
445  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
446  }
447 
448  static char_type*
449  assign(char_type* __s, size_t __n, char_type __a)
450  {
451  for (size_t __i = 0; __i < __n; ++__i)
452  assign(__s[__i], __a);
453  return __s;
454  }
455 
456  static constexpr char_type
457  to_char_type(const int_type& __c) noexcept
458  { return char_type(__c); }
459 
460  static constexpr int_type
461  to_int_type(const char_type& __c) noexcept
462  { return int_type(__c); }
463 
464  static constexpr bool
465  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
466  { return __c1 == __c2; }
467 
468  static constexpr int_type
469  eof() noexcept
470  { return static_cast<int_type>(-1); }
471 
472  static constexpr int_type
473  not_eof(const int_type& __c) noexcept
474  { return eq_int_type(__c, eof()) ? 0 : __c; }
475  };
476 
477  template<>
478  struct char_traits<char32_t>
479  {
480  typedef char32_t char_type;
481  typedef uint_least32_t int_type;
482  typedef streamoff off_type;
483  typedef u32streampos pos_type;
484  typedef mbstate_t state_type;
485 
486  static void
487  assign(char_type& __c1, const char_type& __c2) noexcept
488  { __c1 = __c2; }
489 
490  static constexpr bool
491  eq(const char_type& __c1, const char_type& __c2) noexcept
492  { return __c1 == __c2; }
493 
494  static constexpr bool
495  lt(const char_type& __c1, const char_type& __c2) noexcept
496  { return __c1 < __c2; }
497 
498  static int
499  compare(const char_type* __s1, const char_type* __s2, size_t __n)
500  {
501  for (size_t __i = 0; __i < __n; ++__i)
502  if (lt(__s1[__i], __s2[__i]))
503  return -1;
504  else if (lt(__s2[__i], __s1[__i]))
505  return 1;
506  return 0;
507  }
508 
509  static size_t
510  length(const char_type* __s)
511  {
512  size_t __i = 0;
513  while (!eq(__s[__i], char_type()))
514  ++__i;
515  return __i;
516  }
517 
518  static const char_type*
519  find(const char_type* __s, size_t __n, const char_type& __a)
520  {
521  for (size_t __i = 0; __i < __n; ++__i)
522  if (eq(__s[__i], __a))
523  return __s + __i;
524  return 0;
525  }
526 
527  static char_type*
528  move(char_type* __s1, const char_type* __s2, size_t __n)
529  {
530  return (static_cast<char_type*>
531  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
532  }
533 
534  static char_type*
535  copy(char_type* __s1, const char_type* __s2, size_t __n)
536  {
537  return (static_cast<char_type*>
538  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
539  }
540 
541  static char_type*
542  assign(char_type* __s, size_t __n, char_type __a)
543  {
544  for (size_t __i = 0; __i < __n; ++__i)
545  assign(__s[__i], __a);
546  return __s;
547  }
548 
549  static constexpr char_type
550  to_char_type(const int_type& __c) noexcept
551  { return char_type(__c); }
552 
553  static constexpr int_type
554  to_int_type(const char_type& __c) noexcept
555  { return int_type(__c); }
556 
557  static constexpr bool
558  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
559  { return __c1 == __c2; }
560 
561  static constexpr int_type
562  eof() noexcept
563  { return static_cast<int_type>(-1); }
564 
565  static constexpr int_type
566  not_eof(const int_type& __c) noexcept
567  { return eq_int_type(__c, eof()) ? 0 : __c; }
568  };
569 
570 _GLIBCXX_END_NAMESPACE_VERSION
571 } // namespace
572 
573 #endif
574 
575 #endif // _CHAR_TRAITS_H