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
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*
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*
184  move(char_type* __s1, const char_type* __s2, std::size_t __n)
185  {
186  return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
187  __n * sizeof(char_type)));
188  }
189 
190  template<typename _CharT>
191  typename char_traits<_CharT>::char_type*
193  copy(char_type* __s1, const char_type* __s2, std::size_t __n)
194  {
195  // NB: Inline std::copy so no recursive dependencies.
196  std::copy(__s2, __s2 + __n, __s1);
197  return __s1;
198  }
199 
200  template<typename _CharT>
201  typename char_traits<_CharT>::char_type*
203  assign(char_type* __s, std::size_t __n, char_type __a)
204  {
205  // NB: Inline std::fill_n so no recursive dependencies.
206  std::fill_n(__s, __n, __a);
207  return __s;
208  }
209 
210 _GLIBCXX_END_NAMESPACE_VERSION
211 } // namespace
212 
213 namespace std _GLIBCXX_VISIBILITY(default)
214 {
215 _GLIBCXX_BEGIN_NAMESPACE_VERSION
216 
217 #if __cplusplus >= 201703L
218 #define __cpp_lib_constexpr_char_traits 201611
219 
220  /**
221  * @brief Determine whether the characters of a NULL-terminated
222  * string are known at compile time.
223  * @param __s The string.
224  *
225  * Assumes that _CharT is a built-in character type.
226  */
227  template<typename _CharT>
228  static _GLIBCXX_ALWAYS_INLINE constexpr bool
229  __constant_string_p(const _CharT* __s)
230  {
231  while (__builtin_constant_p(*__s) && *__s)
232  __s++;
233  return __builtin_constant_p(*__s);
234  }
235 
236  /**
237  * @brief Determine whether the characters of a character array are
238  * known at compile time.
239  * @param __a The character array.
240  * @param __n Number of characters.
241  *
242  * Assumes that _CharT is a built-in character type.
243  */
244  template<typename _CharT>
245  static _GLIBCXX_ALWAYS_INLINE constexpr bool
246  __constant_char_array_p(const _CharT* __a, size_t __n)
247  {
248  size_t __i = 0;
249  while (__builtin_constant_p(__a[__i]) && __i < __n)
250  __i++;
251  return __i == __n;
252  }
253 #endif
254 
255  // 21.1
256  /**
257  * @brief Basis for explicit traits specializations.
258  *
259  * @note For any given actual character type, this definition is
260  * probably wrong. Since this is just a thin wrapper around
261  * __gnu_cxx::char_traits, it is possible to achieve a more
262  * appropriate definition by specializing __gnu_cxx::char_traits.
263  *
264  * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
265  * for advice on how to make use of this class for @a unusual character
266  * types. Also, check out include/ext/pod_char_traits.h.
267  */
268  template<class _CharT>
269  struct char_traits : public __gnu_cxx::char_traits<_CharT>
270  { };
271 
272 
273  /// 21.1.3.1 char_traits specializations
274  template<>
275  struct char_traits<char>
276  {
277  typedef char char_type;
278  typedef int int_type;
279  typedef streampos pos_type;
280  typedef streamoff off_type;
281  typedef mbstate_t state_type;
282 
283  static _GLIBCXX17_CONSTEXPR void
284  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
285  { __c1 = __c2; }
286 
287  static _GLIBCXX_CONSTEXPR bool
288  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
289  { return __c1 == __c2; }
290 
291  static _GLIBCXX_CONSTEXPR bool
292  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
293  {
294  // LWG 467.
295  return (static_cast<unsigned char>(__c1)
296  < static_cast<unsigned char>(__c2));
297  }
298 
299  static _GLIBCXX17_CONSTEXPR int
300  compare(const char_type* __s1, const char_type* __s2, size_t __n)
301  {
302 #if __cplusplus >= 201703L
303  if (__builtin_constant_p(__n)
304  && __constant_char_array_p(__s1, __n)
305  && __constant_char_array_p(__s2, __n))
306  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
307 #endif
308  if (__n == 0)
309  return 0;
310  return __builtin_memcmp(__s1, __s2, __n);
311  }
312 
313  static _GLIBCXX17_CONSTEXPR size_t
314  length(const char_type* __s)
315  {
316 #if __cplusplus >= 201703L
317  if (__constant_string_p(__s))
319 #endif
320  return __builtin_strlen(__s);
321  }
322 
323  static _GLIBCXX17_CONSTEXPR const char_type*
324  find(const char_type* __s, size_t __n, const char_type& __a)
325  {
326 #if __cplusplus >= 201703L
327  if (__builtin_constant_p(__n)
328  && __builtin_constant_p(__a)
329  && __constant_char_array_p(__s, __n))
330  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
331 #endif
332  if (__n == 0)
333  return 0;
334  return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
335  }
336 
337  static char_type*
338  move(char_type* __s1, const char_type* __s2, size_t __n)
339  {
340  if (__n == 0)
341  return __s1;
342  return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
343  }
344 
345  static char_type*
346  copy(char_type* __s1, const char_type* __s2, size_t __n)
347  {
348  if (__n == 0)
349  return __s1;
350  return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
351  }
352 
353  static char_type*
354  assign(char_type* __s, size_t __n, char_type __a)
355  {
356  if (__n == 0)
357  return __s;
358  return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
359  }
360 
361  static _GLIBCXX_CONSTEXPR char_type
362  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
363  { return static_cast<char_type>(__c); }
364 
365  // To keep both the byte 0xff and the eof symbol 0xffffffff
366  // from ending up as 0xffffffff.
367  static _GLIBCXX_CONSTEXPR int_type
368  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
369  { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
370 
371  static _GLIBCXX_CONSTEXPR bool
372  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
373  { return __c1 == __c2; }
374 
375  static _GLIBCXX_CONSTEXPR int_type
376  eof() _GLIBCXX_NOEXCEPT
377  { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
378 
379  static _GLIBCXX_CONSTEXPR int_type
380  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
381  { return (__c == eof()) ? 0 : __c; }
382  };
383 
384 
385 #ifdef _GLIBCXX_USE_WCHAR_T
386  /// 21.1.3.2 char_traits specializations
387  template<>
388  struct char_traits<wchar_t>
389  {
390  typedef wchar_t char_type;
391  typedef wint_t int_type;
392  typedef streamoff off_type;
393  typedef wstreampos pos_type;
394  typedef mbstate_t state_type;
395 
396  static _GLIBCXX17_CONSTEXPR void
397  assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
398  { __c1 = __c2; }
399 
400  static _GLIBCXX_CONSTEXPR bool
401  eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
402  { return __c1 == __c2; }
403 
404  static _GLIBCXX_CONSTEXPR bool
405  lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
406  { return __c1 < __c2; }
407 
408  static _GLIBCXX17_CONSTEXPR int
409  compare(const char_type* __s1, const char_type* __s2, size_t __n)
410  {
411 #if __cplusplus >= 201703L
412  if (__builtin_constant_p(__n)
413  && __constant_char_array_p(__s1, __n)
414  && __constant_char_array_p(__s2, __n))
415  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
416 #endif
417  if (__n == 0)
418  return 0;
419  else
420  return wmemcmp(__s1, __s2, __n);
421  }
422 
423  static _GLIBCXX17_CONSTEXPR size_t
424  length(const char_type* __s)
425  {
426 #if __cplusplus >= 201703L
427  if (__constant_string_p(__s))
429  else
430 #endif
431  return wcslen(__s);
432  }
433 
434  static _GLIBCXX17_CONSTEXPR const char_type*
435  find(const char_type* __s, size_t __n, const char_type& __a)
436  {
437 #if __cplusplus >= 201703L
438  if (__builtin_constant_p(__n)
439  && __builtin_constant_p(__a)
440  && __constant_char_array_p(__s, __n))
441  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
442 #endif
443  if (__n == 0)
444  return 0;
445  else
446  return wmemchr(__s, __a, __n);
447  }
448 
449  static char_type*
450  move(char_type* __s1, const char_type* __s2, size_t __n)
451  {
452  if (__n == 0)
453  return __s1;
454  return wmemmove(__s1, __s2, __n);
455  }
456 
457  static char_type*
458  copy(char_type* __s1, const char_type* __s2, size_t __n)
459  {
460  if (__n == 0)
461  return __s1;
462  return wmemcpy(__s1, __s2, __n);
463  }
464 
465  static char_type*
466  assign(char_type* __s, size_t __n, char_type __a)
467  {
468  if (__n == 0)
469  return __s;
470  return wmemset(__s, __a, __n);
471  }
472 
473  static _GLIBCXX_CONSTEXPR char_type
474  to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
475  { return char_type(__c); }
476 
477  static _GLIBCXX_CONSTEXPR int_type
478  to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
479  { return int_type(__c); }
480 
481  static _GLIBCXX_CONSTEXPR bool
482  eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
483  { return __c1 == __c2; }
484 
485  static _GLIBCXX_CONSTEXPR int_type
486  eof() _GLIBCXX_NOEXCEPT
487  { return static_cast<int_type>(WEOF); }
488 
489  static _GLIBCXX_CONSTEXPR int_type
490  not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
491  { return eq_int_type(__c, eof()) ? 0 : __c; }
492  };
493 #endif //_GLIBCXX_USE_WCHAR_T
494 
495 _GLIBCXX_END_NAMESPACE_VERSION
496 } // namespace
497 
498 #if __cplusplus >= 201103L
499 
500 #include <cstdint>
501 
502 namespace std _GLIBCXX_VISIBILITY(default)
503 {
504 _GLIBCXX_BEGIN_NAMESPACE_VERSION
505 
506  template<>
507  struct char_traits<char16_t>
508  {
509  typedef char16_t char_type;
510 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
511  typedef uint_least16_t int_type;
512 #elif defined __UINT_LEAST16_TYPE__
513  typedef __UINT_LEAST16_TYPE__ int_type;
514 #else
515  typedef make_unsigned<char16_t>::type int_type;
516 #endif
517  typedef streamoff off_type;
518  typedef u16streampos pos_type;
519  typedef mbstate_t state_type;
520 
521  static _GLIBCXX17_CONSTEXPR void
522  assign(char_type& __c1, const char_type& __c2) noexcept
523  { __c1 = __c2; }
524 
525  static constexpr bool
526  eq(const char_type& __c1, const char_type& __c2) noexcept
527  { return __c1 == __c2; }
528 
529  static constexpr bool
530  lt(const char_type& __c1, const char_type& __c2) noexcept
531  { return __c1 < __c2; }
532 
533  static _GLIBCXX17_CONSTEXPR int
534  compare(const char_type* __s1, const char_type* __s2, size_t __n)
535  {
536  for (size_t __i = 0; __i < __n; ++__i)
537  if (lt(__s1[__i], __s2[__i]))
538  return -1;
539  else if (lt(__s2[__i], __s1[__i]))
540  return 1;
541  return 0;
542  }
543 
544  static _GLIBCXX17_CONSTEXPR size_t
545  length(const char_type* __s)
546  {
547  size_t __i = 0;
548  while (!eq(__s[__i], char_type()))
549  ++__i;
550  return __i;
551  }
552 
553  static _GLIBCXX17_CONSTEXPR const char_type*
554  find(const char_type* __s, size_t __n, const char_type& __a)
555  {
556  for (size_t __i = 0; __i < __n; ++__i)
557  if (eq(__s[__i], __a))
558  return __s + __i;
559  return 0;
560  }
561 
562  static char_type*
563  move(char_type* __s1, const char_type* __s2, size_t __n)
564  {
565  if (__n == 0)
566  return __s1;
567  return (static_cast<char_type*>
568  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
569  }
570 
571  static char_type*
572  copy(char_type* __s1, const char_type* __s2, size_t __n)
573  {
574  if (__n == 0)
575  return __s1;
576  return (static_cast<char_type*>
577  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
578  }
579 
580  static char_type*
581  assign(char_type* __s, size_t __n, char_type __a)
582  {
583  for (size_t __i = 0; __i < __n; ++__i)
584  assign(__s[__i], __a);
585  return __s;
586  }
587 
588  static constexpr char_type
589  to_char_type(const int_type& __c) noexcept
590  { return char_type(__c); }
591 
592  static constexpr int_type
593  to_int_type(const char_type& __c) noexcept
594  { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
595 
596  static constexpr bool
597  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
598  { return __c1 == __c2; }
599 
600  static constexpr int_type
601  eof() noexcept
602  { return static_cast<int_type>(-1); }
603 
604  static constexpr int_type
605  not_eof(const int_type& __c) noexcept
606  { return eq_int_type(__c, eof()) ? 0 : __c; }
607  };
608 
609  template<>
610  struct char_traits<char32_t>
611  {
612  typedef char32_t char_type;
613 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
614  typedef uint_least32_t int_type;
615 #elif defined __UINT_LEAST32_TYPE__
616  typedef __UINT_LEAST32_TYPE__ int_type;
617 #else
618  typedef make_unsigned<char32_t>::type int_type;
619 #endif
620  typedef streamoff off_type;
621  typedef u32streampos pos_type;
622  typedef mbstate_t state_type;
623 
624  static _GLIBCXX17_CONSTEXPR void
625  assign(char_type& __c1, const char_type& __c2) noexcept
626  { __c1 = __c2; }
627 
628  static constexpr bool
629  eq(const char_type& __c1, const char_type& __c2) noexcept
630  { return __c1 == __c2; }
631 
632  static constexpr bool
633  lt(const char_type& __c1, const char_type& __c2) noexcept
634  { return __c1 < __c2; }
635 
636  static _GLIBCXX17_CONSTEXPR int
637  compare(const char_type* __s1, const char_type* __s2, size_t __n)
638  {
639  for (size_t __i = 0; __i < __n; ++__i)
640  if (lt(__s1[__i], __s2[__i]))
641  return -1;
642  else if (lt(__s2[__i], __s1[__i]))
643  return 1;
644  return 0;
645  }
646 
647  static _GLIBCXX17_CONSTEXPR size_t
648  length(const char_type* __s)
649  {
650  size_t __i = 0;
651  while (!eq(__s[__i], char_type()))
652  ++__i;
653  return __i;
654  }
655 
656  static _GLIBCXX17_CONSTEXPR const char_type*
657  find(const char_type* __s, size_t __n, const char_type& __a)
658  {
659  for (size_t __i = 0; __i < __n; ++__i)
660  if (eq(__s[__i], __a))
661  return __s + __i;
662  return 0;
663  }
664 
665  static char_type*
666  move(char_type* __s1, const char_type* __s2, size_t __n)
667  {
668  if (__n == 0)
669  return __s1;
670  return (static_cast<char_type*>
671  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
672  }
673 
674  static char_type*
675  copy(char_type* __s1, const char_type* __s2, size_t __n)
676  {
677  if (__n == 0)
678  return __s1;
679  return (static_cast<char_type*>
680  (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
681  }
682 
683  static char_type*
684  assign(char_type* __s, size_t __n, char_type __a)
685  {
686  for (size_t __i = 0; __i < __n; ++__i)
687  assign(__s[__i], __a);
688  return __s;
689  }
690 
691  static constexpr char_type
692  to_char_type(const int_type& __c) noexcept
693  { return char_type(__c); }
694 
695  static constexpr int_type
696  to_int_type(const char_type& __c) noexcept
697  { return int_type(__c); }
698 
699  static constexpr bool
700  eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
701  { return __c1 == __c2; }
702 
703  static constexpr int_type
704  eof() noexcept
705  { return static_cast<int_type>(-1); }
706 
707  static constexpr int_type
708  not_eof(const int_type& __c) noexcept
709  { return eq_int_type(__c, eof()) ? 0 : __c; }
710  };
711 
712 _GLIBCXX_END_NAMESPACE_VERSION
713 } // namespace
714 
715 #endif // C++11
716 
717 #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:269
ISO C++ entities toplevel namespace is std.
GNU extensions for public use.
long long streamoff
Type used by fpos, char_traits<char>, and char_traits<wchar_t>.
Definition: postypes.h:94
Class representing stream positions.
Definition: postypes.h:112
Base class used to implement std::char_traits.
Definition: char_traits.h:87