libstdc++
char_traits.h
Go to the documentation of this file.
00001 // Character Traits for use by standard string and iostream -*- C++ -*-
00002 
00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/char_traits.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{string}
00028  */
00029 
00030 //
00031 // ISO C++ 14882: 21  Strings library
00032 //
00033 
00034 #ifndef _CHAR_TRAITS_H
00035 #define _CHAR_TRAITS_H 1
00036 
00037 #pragma GCC system_header
00038 
00039 #include <bits/stl_algobase.h>  // std::copy, std::fill_n
00040 #include <bits/postypes.h>      // For streampos
00041 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
00042 
00043 #ifndef _GLIBCXX_ALWAYS_INLINE
00044 # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
00045 #endif
00046 
00047 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00048 {
00049 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00050 
00051   /**
00052    *  @brief  Mapping from character type to associated types.
00053    *
00054    *  @note This is an implementation class for the generic version
00055    *  of char_traits.  It defines int_type, off_type, pos_type, and
00056    *  state_type.  By default these are unsigned long, streamoff,
00057    *  streampos, and mbstate_t.  Users who need a different set of
00058    *  types, but who don't need to change the definitions of any function
00059    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
00060    *  while leaving __gnu_cxx::char_traits alone. */
00061   template<typename _CharT>
00062     struct _Char_types
00063     {
00064       typedef unsigned long   int_type;
00065       typedef std::streampos  pos_type;
00066       typedef std::streamoff  off_type;
00067       typedef std::mbstate_t  state_type;
00068     };
00069 
00070 
00071   /**
00072    *  @brief  Base class used to implement std::char_traits.
00073    *
00074    *  @note For any given actual character type, this definition is
00075    *  probably wrong.  (Most of the member functions are likely to be
00076    *  right, but the int_type and state_type typedefs, and the eof()
00077    *  member function, are likely to be wrong.)  The reason this class
00078    *  exists is so users can specialize it.  Classes in namespace std
00079    *  may not be specialized for fundamental types, but classes in
00080    *  namespace __gnu_cxx may be.
00081    *
00082    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
00083    *  for advice on how to make use of this class for @a unusual character
00084    *  types. Also, check out include/ext/pod_char_traits.h.  
00085    */
00086   template<typename _CharT>
00087     struct char_traits
00088     {
00089       typedef _CharT                                    char_type;
00090       typedef typename _Char_types<_CharT>::int_type    int_type;
00091       typedef typename _Char_types<_CharT>::pos_type    pos_type;
00092       typedef typename _Char_types<_CharT>::off_type    off_type;
00093       typedef typename _Char_types<_CharT>::state_type  state_type;
00094 
00095       static _GLIBCXX14_CONSTEXPR void
00096       assign(char_type& __c1, const char_type& __c2)
00097       { __c1 = __c2; }
00098 
00099       static _GLIBCXX_CONSTEXPR bool
00100       eq(const char_type& __c1, const char_type& __c2)
00101       { return __c1 == __c2; }
00102 
00103       static _GLIBCXX_CONSTEXPR bool
00104       lt(const char_type& __c1, const char_type& __c2)
00105       { return __c1 < __c2; }
00106 
00107       static _GLIBCXX14_CONSTEXPR int
00108       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
00109 
00110       static _GLIBCXX14_CONSTEXPR std::size_t
00111       length(const char_type* __s);
00112 
00113       static _GLIBCXX14_CONSTEXPR const char_type*
00114       find(const char_type* __s, std::size_t __n, const char_type& __a);
00115 
00116       static char_type*
00117       move(char_type* __s1, const char_type* __s2, std::size_t __n);
00118 
00119       static char_type*
00120       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
00121 
00122       static char_type*
00123       assign(char_type* __s, std::size_t __n, char_type __a);
00124 
00125       static _GLIBCXX_CONSTEXPR char_type
00126       to_char_type(const int_type& __c)
00127       { return static_cast<char_type>(__c); }
00128 
00129       static _GLIBCXX_CONSTEXPR int_type
00130       to_int_type(const char_type& __c)
00131       { return static_cast<int_type>(__c); }
00132 
00133       static _GLIBCXX_CONSTEXPR bool
00134       eq_int_type(const int_type& __c1, const int_type& __c2)
00135       { return __c1 == __c2; }
00136 
00137       static _GLIBCXX_CONSTEXPR int_type
00138       eof()
00139       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00140 
00141       static _GLIBCXX_CONSTEXPR int_type
00142       not_eof(const int_type& __c)
00143       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
00144     };
00145 
00146   template<typename _CharT>
00147     _GLIBCXX14_CONSTEXPR int
00148     char_traits<_CharT>::
00149     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
00150     {
00151       for (std::size_t __i = 0; __i < __n; ++__i)
00152         if (lt(__s1[__i], __s2[__i]))
00153           return -1;
00154         else if (lt(__s2[__i], __s1[__i]))
00155           return 1;
00156       return 0;
00157     }
00158 
00159   template<typename _CharT>
00160     _GLIBCXX14_CONSTEXPR std::size_t
00161     char_traits<_CharT>::
00162     length(const char_type* __p)
00163     {
00164       std::size_t __i = 0;
00165       while (!eq(__p[__i], char_type()))
00166         ++__i;
00167       return __i;
00168     }
00169 
00170   template<typename _CharT>
00171     _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
00172     char_traits<_CharT>::
00173     find(const char_type* __s, std::size_t __n, const char_type& __a)
00174     {
00175       for (std::size_t __i = 0; __i < __n; ++__i)
00176         if (eq(__s[__i], __a))
00177           return __s + __i;
00178       return 0;
00179     }
00180 
00181   template<typename _CharT>
00182     typename char_traits<_CharT>::char_type*
00183     char_traits<_CharT>::
00184     move(char_type* __s1, const char_type* __s2, std::size_t __n)
00185     {
00186       if (__n == 0)
00187         return __s1;
00188       return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
00189                                                     __n * sizeof(char_type)));
00190     }
00191 
00192   template<typename _CharT>
00193     typename char_traits<_CharT>::char_type*
00194     char_traits<_CharT>::
00195     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
00196     {
00197       // NB: Inline std::copy so no recursive dependencies.
00198       std::copy(__s2, __s2 + __n, __s1);
00199       return __s1;
00200     }
00201 
00202   template<typename _CharT>
00203     typename char_traits<_CharT>::char_type*
00204     char_traits<_CharT>::
00205     assign(char_type* __s, std::size_t __n, char_type __a)
00206     {
00207       // NB: Inline std::fill_n so no recursive dependencies.
00208       std::fill_n(__s, __n, __a);
00209       return __s;
00210     }
00211 
00212 _GLIBCXX_END_NAMESPACE_VERSION
00213 } // namespace
00214 
00215 namespace std _GLIBCXX_VISIBILITY(default)
00216 {
00217 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00218 
00219 #if __cplusplus >= 201703L
00220 #define __cpp_lib_constexpr_char_traits 201611
00221 
00222   /**
00223    *  @brief Determine whether the characters of a NULL-terminated
00224    *  string are known at compile time.
00225    *  @param  __s  The string.
00226    *
00227    *  Assumes that _CharT is a built-in character type.
00228    */
00229   template<typename _CharT>
00230     static _GLIBCXX_ALWAYS_INLINE constexpr bool
00231     __constant_string_p(const _CharT* __s)
00232     {
00233 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
00234       (void) __s;
00235       // In constexpr contexts all strings should be constant.
00236       return __builtin_is_constant_evaluated();
00237 #else
00238       while (__builtin_constant_p(*__s) && *__s)
00239         __s++;
00240       return __builtin_constant_p(*__s);
00241 #endif
00242     }
00243 
00244   /**
00245    *  @brief Determine whether the characters of a character array are
00246    *  known at compile time.
00247    *  @param  __a  The character array.
00248    *  @param  __n  Number of characters.
00249    *
00250    *  Assumes that _CharT is a built-in character type.
00251    */
00252   template<typename _CharT>
00253     static _GLIBCXX_ALWAYS_INLINE constexpr bool
00254     __constant_char_array_p(const _CharT* __a, size_t __n)
00255     {
00256 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
00257       (void) __a;
00258       (void) __n;
00259       // In constexpr contexts all character arrays should be constant.
00260       return __builtin_is_constant_evaluated();
00261 #else
00262       size_t __i = 0;
00263       while (__i < __n && __builtin_constant_p(__a[__i]))
00264         __i++;
00265       return __i == __n;
00266 #endif
00267     }
00268 #endif
00269 
00270   // 21.1
00271   /**
00272    *  @brief  Basis for explicit traits specializations.
00273    *
00274    *  @note  For any given actual character type, this definition is
00275    *  probably wrong.  Since this is just a thin wrapper around
00276    *  __gnu_cxx::char_traits, it is possible to achieve a more
00277    *  appropriate definition by specializing __gnu_cxx::char_traits.
00278    *
00279    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
00280    *  for advice on how to make use of this class for @a unusual character
00281    *  types. Also, check out include/ext/pod_char_traits.h.
00282   */
00283   template<class _CharT>
00284     struct char_traits : public __gnu_cxx::char_traits<_CharT>
00285     { };
00286 
00287 
00288   /// 21.1.3.1  char_traits specializations
00289   template<>
00290     struct char_traits<char>
00291     {
00292       typedef char              char_type;
00293       typedef int               int_type;
00294       typedef streampos         pos_type;
00295       typedef streamoff         off_type;
00296       typedef mbstate_t         state_type;
00297 
00298       static _GLIBCXX17_CONSTEXPR void
00299       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00300       { __c1 = __c2; }
00301 
00302       static _GLIBCXX_CONSTEXPR bool
00303       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00304       { return __c1 == __c2; }
00305 
00306       static _GLIBCXX_CONSTEXPR bool
00307       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00308       {
00309         // LWG 467.
00310         return (static_cast<unsigned char>(__c1)
00311                 < static_cast<unsigned char>(__c2));
00312       }
00313 
00314       static _GLIBCXX17_CONSTEXPR int
00315       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00316       {
00317         if (__n == 0)
00318           return 0;
00319 #if __cplusplus >= 201703L
00320         if (__builtin_constant_p(__n)
00321             && __constant_char_array_p(__s1, __n)
00322             && __constant_char_array_p(__s2, __n))
00323           return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
00324 #endif
00325         return __builtin_memcmp(__s1, __s2, __n);
00326       }
00327 
00328       static _GLIBCXX17_CONSTEXPR size_t
00329       length(const char_type* __s)
00330       {
00331 #if __cplusplus >= 201703L
00332         if (__constant_string_p(__s))
00333           return __gnu_cxx::char_traits<char_type>::length(__s);
00334 #endif
00335         return __builtin_strlen(__s);
00336       }
00337 
00338       static _GLIBCXX17_CONSTEXPR const char_type*
00339       find(const char_type* __s, size_t __n, const char_type& __a)
00340       {
00341         if (__n == 0)
00342           return 0;
00343 #if __cplusplus >= 201703L
00344         if (__builtin_constant_p(__n)
00345             && __builtin_constant_p(__a)
00346             && __constant_char_array_p(__s, __n))
00347           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
00348 #endif
00349         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
00350       }
00351 
00352       static char_type*
00353       move(char_type* __s1, const char_type* __s2, size_t __n)
00354       {
00355         if (__n == 0)
00356           return __s1;
00357         return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
00358       }
00359 
00360       static char_type*
00361       copy(char_type* __s1, const char_type* __s2, size_t __n)
00362       {
00363         if (__n == 0)
00364           return __s1;
00365         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
00366       }
00367 
00368       static char_type*
00369       assign(char_type* __s, size_t __n, char_type __a)
00370       {
00371         if (__n == 0)
00372           return __s;
00373         return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
00374       }
00375 
00376       static _GLIBCXX_CONSTEXPR char_type
00377       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00378       { return static_cast<char_type>(__c); }
00379 
00380       // To keep both the byte 0xff and the eof symbol 0xffffffff
00381       // from ending up as 0xffffffff.
00382       static _GLIBCXX_CONSTEXPR int_type
00383       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00384       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
00385 
00386       static _GLIBCXX_CONSTEXPR bool
00387       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00388       { return __c1 == __c2; }
00389 
00390       static _GLIBCXX_CONSTEXPR int_type
00391       eof() _GLIBCXX_NOEXCEPT
00392       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00393 
00394       static _GLIBCXX_CONSTEXPR int_type
00395       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00396       { return (__c == eof()) ? 0 : __c; }
00397   };
00398 
00399 
00400 #ifdef _GLIBCXX_USE_WCHAR_T
00401   /// 21.1.3.2  char_traits specializations
00402   template<>
00403     struct char_traits<wchar_t>
00404     {
00405       typedef wchar_t           char_type;
00406       typedef wint_t            int_type;
00407       typedef streamoff         off_type;
00408       typedef wstreampos        pos_type;
00409       typedef mbstate_t         state_type;
00410 
00411       static _GLIBCXX17_CONSTEXPR void
00412       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00413       { __c1 = __c2; }
00414 
00415       static _GLIBCXX_CONSTEXPR bool
00416       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00417       { return __c1 == __c2; }
00418 
00419       static _GLIBCXX_CONSTEXPR bool
00420       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00421       { return __c1 < __c2; }
00422 
00423       static _GLIBCXX17_CONSTEXPR int
00424       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00425       {
00426         if (__n == 0)
00427           return 0;
00428 #if __cplusplus >= 201703L
00429         if (__builtin_constant_p(__n)
00430             && __constant_char_array_p(__s1, __n)
00431             && __constant_char_array_p(__s2, __n))
00432           return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
00433 #endif
00434         return wmemcmp(__s1, __s2, __n);
00435       }
00436 
00437       static _GLIBCXX17_CONSTEXPR size_t
00438       length(const char_type* __s)
00439       {
00440 #if __cplusplus >= 201703L
00441         if (__constant_string_p(__s))
00442           return __gnu_cxx::char_traits<char_type>::length(__s);
00443 #endif
00444         return wcslen(__s);
00445       }
00446 
00447       static _GLIBCXX17_CONSTEXPR const char_type*
00448       find(const char_type* __s, size_t __n, const char_type& __a)
00449       {
00450         if (__n == 0)
00451           return 0;
00452 #if __cplusplus >= 201703L
00453         if (__builtin_constant_p(__n)
00454             && __builtin_constant_p(__a)
00455             && __constant_char_array_p(__s, __n))
00456           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
00457 #endif
00458         return wmemchr(__s, __a, __n);
00459       }
00460 
00461       static char_type*
00462       move(char_type* __s1, const char_type* __s2, size_t __n)
00463       {
00464         if (__n == 0)
00465           return __s1;
00466         return wmemmove(__s1, __s2, __n);
00467       }
00468 
00469       static char_type*
00470       copy(char_type* __s1, const char_type* __s2, size_t __n)
00471       {
00472         if (__n == 0)
00473           return __s1;
00474         return wmemcpy(__s1, __s2, __n);
00475       }
00476 
00477       static char_type*
00478       assign(char_type* __s, size_t __n, char_type __a)
00479       {
00480         if (__n == 0)
00481           return __s;
00482         return wmemset(__s, __a, __n);
00483       }
00484 
00485       static _GLIBCXX_CONSTEXPR char_type
00486       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00487       { return char_type(__c); }
00488 
00489       static _GLIBCXX_CONSTEXPR int_type
00490       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00491       { return int_type(__c); }
00492 
00493       static _GLIBCXX_CONSTEXPR bool
00494       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00495       { return __c1 == __c2; }
00496 
00497       static _GLIBCXX_CONSTEXPR int_type
00498       eof() _GLIBCXX_NOEXCEPT
00499       { return static_cast<int_type>(WEOF); }
00500 
00501       static _GLIBCXX_CONSTEXPR int_type
00502       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00503       { return eq_int_type(__c, eof()) ? 0 : __c; }
00504   };
00505 #endif //_GLIBCXX_USE_WCHAR_T
00506 
00507 #ifdef _GLIBCXX_USE_CHAR8_T
00508   template<>
00509     struct char_traits<char8_t>
00510     {
00511       typedef char8_t           char_type;
00512       typedef unsigned int      int_type;
00513       typedef u8streampos       pos_type;
00514       typedef streamoff         off_type;
00515       typedef mbstate_t         state_type;
00516 
00517       static _GLIBCXX17_CONSTEXPR void
00518       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00519       { __c1 = __c2; }
00520 
00521       static _GLIBCXX_CONSTEXPR bool
00522       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00523       { return __c1 == __c2; }
00524 
00525       static _GLIBCXX_CONSTEXPR bool
00526       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00527       { return __c1 < __c2; }
00528 
00529       static _GLIBCXX17_CONSTEXPR int
00530       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00531       {
00532         if (__n == 0)
00533           return 0;
00534 #if __cplusplus > 201402
00535         if (__builtin_constant_p(__n)
00536             && __constant_char_array_p(__s1, __n)
00537             && __constant_char_array_p(__s2, __n))
00538           return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
00539 #endif
00540         return __builtin_memcmp(__s1, __s2, __n);
00541       }
00542 
00543       static _GLIBCXX17_CONSTEXPR size_t
00544       length(const char_type* __s)
00545       {
00546 #if __cplusplus > 201402
00547         if (__constant_string_p(__s))
00548           return __gnu_cxx::char_traits<char_type>::length(__s);
00549 #endif
00550         size_t __i = 0;
00551         while (!eq(__s[__i], char_type()))
00552           ++__i;
00553         return __i;
00554       }
00555 
00556       static _GLIBCXX17_CONSTEXPR const char_type*
00557       find(const char_type* __s, size_t __n, const char_type& __a)
00558       {
00559         if (__n == 0)
00560           return 0;
00561 #if __cplusplus > 201402
00562         if (__builtin_constant_p(__n)
00563             && __builtin_constant_p(__a)
00564             && __constant_char_array_p(__s, __n))
00565           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
00566 #endif
00567         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
00568       }
00569 
00570       static char_type*
00571       move(char_type* __s1, const char_type* __s2, size_t __n)
00572       {
00573         if (__n == 0)
00574           return __s1;
00575         return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
00576       }
00577 
00578       static char_type*
00579       copy(char_type* __s1, const char_type* __s2, size_t __n)
00580       {
00581         if (__n == 0)
00582           return __s1;
00583         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
00584       }
00585 
00586       static char_type*
00587       assign(char_type* __s, size_t __n, char_type __a)
00588       {
00589         if (__n == 0)
00590           return __s;
00591         return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
00592       }
00593 
00594       static _GLIBCXX_CONSTEXPR char_type
00595       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00596       { return char_type(__c); }
00597 
00598       static _GLIBCXX_CONSTEXPR int_type
00599       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00600       { return int_type(__c); }
00601 
00602       static _GLIBCXX_CONSTEXPR bool
00603       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00604       { return __c1 == __c2; }
00605 
00606       static _GLIBCXX_CONSTEXPR int_type
00607       eof() _GLIBCXX_NOEXCEPT
00608       { return static_cast<int_type>(-1); }
00609 
00610       static _GLIBCXX_CONSTEXPR int_type
00611       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00612       { return eq_int_type(__c, eof()) ? 0 : __c; }
00613     };
00614 #endif //_GLIBCXX_USE_CHAR8_T
00615 
00616 _GLIBCXX_END_NAMESPACE_VERSION
00617 } // namespace
00618 
00619 #if __cplusplus >= 201103L
00620 
00621 #include <cstdint>
00622 
00623 namespace std _GLIBCXX_VISIBILITY(default)
00624 {
00625 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00626 
00627   template<>
00628     struct char_traits<char16_t>
00629     {
00630       typedef char16_t          char_type;
00631 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
00632       typedef uint_least16_t    int_type;
00633 #elif defined __UINT_LEAST16_TYPE__
00634       typedef __UINT_LEAST16_TYPE__         int_type;
00635 #else
00636       typedef make_unsigned<char16_t>::type int_type;
00637 #endif
00638       typedef streamoff         off_type;
00639       typedef u16streampos      pos_type;
00640       typedef mbstate_t         state_type;
00641 
00642       static _GLIBCXX17_CONSTEXPR void
00643       assign(char_type& __c1, const char_type& __c2) noexcept
00644       { __c1 = __c2; }
00645 
00646       static constexpr bool
00647       eq(const char_type& __c1, const char_type& __c2) noexcept
00648       { return __c1 == __c2; }
00649 
00650       static constexpr bool
00651       lt(const char_type& __c1, const char_type& __c2) noexcept
00652       { return __c1 < __c2; }
00653 
00654       static _GLIBCXX17_CONSTEXPR int
00655       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00656       {
00657         for (size_t __i = 0; __i < __n; ++__i)
00658           if (lt(__s1[__i], __s2[__i]))
00659             return -1;
00660           else if (lt(__s2[__i], __s1[__i]))
00661             return 1;
00662         return 0;
00663       }
00664 
00665       static _GLIBCXX17_CONSTEXPR size_t
00666       length(const char_type* __s)
00667       {
00668         size_t __i = 0;
00669         while (!eq(__s[__i], char_type()))
00670           ++__i;
00671         return __i;
00672       }
00673 
00674       static _GLIBCXX17_CONSTEXPR const char_type*
00675       find(const char_type* __s, size_t __n, const char_type& __a)
00676       {
00677         for (size_t __i = 0; __i < __n; ++__i)
00678           if (eq(__s[__i], __a))
00679             return __s + __i;
00680         return 0;
00681       }
00682 
00683       static char_type*
00684       move(char_type* __s1, const char_type* __s2, size_t __n)
00685       {
00686         if (__n == 0)
00687           return __s1;
00688         return (static_cast<char_type*>
00689                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00690       }
00691 
00692       static char_type*
00693       copy(char_type* __s1, const char_type* __s2, size_t __n)
00694       {
00695         if (__n == 0)
00696           return __s1;
00697         return (static_cast<char_type*>
00698                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00699       }
00700 
00701       static char_type*
00702       assign(char_type* __s, size_t __n, char_type __a)
00703       {
00704         for (size_t __i = 0; __i < __n; ++__i)
00705           assign(__s[__i], __a);
00706         return __s;
00707       }
00708 
00709       static constexpr char_type
00710       to_char_type(const int_type& __c) noexcept
00711       { return char_type(__c); }
00712 
00713       static constexpr int_type
00714       to_int_type(const char_type& __c) noexcept
00715       { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
00716 
00717       static constexpr bool
00718       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00719       { return __c1 == __c2; }
00720 
00721       static constexpr int_type
00722       eof() noexcept
00723       { return static_cast<int_type>(-1); }
00724 
00725       static constexpr int_type
00726       not_eof(const int_type& __c) noexcept
00727       { return eq_int_type(__c, eof()) ? 0 : __c; }
00728     };
00729 
00730   template<>
00731     struct char_traits<char32_t>
00732     {
00733       typedef char32_t          char_type;
00734 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
00735       typedef uint_least32_t    int_type;
00736 #elif defined __UINT_LEAST32_TYPE__
00737       typedef __UINT_LEAST32_TYPE__         int_type;
00738 #else
00739       typedef make_unsigned<char32_t>::type int_type;
00740 #endif
00741       typedef streamoff         off_type;
00742       typedef u32streampos      pos_type;
00743       typedef mbstate_t         state_type;
00744 
00745       static _GLIBCXX17_CONSTEXPR void
00746       assign(char_type& __c1, const char_type& __c2) noexcept
00747       { __c1 = __c2; }
00748 
00749       static constexpr bool
00750       eq(const char_type& __c1, const char_type& __c2) noexcept
00751       { return __c1 == __c2; }
00752 
00753       static constexpr bool
00754       lt(const char_type& __c1, const char_type& __c2) noexcept
00755       { return __c1 < __c2; }
00756 
00757       static _GLIBCXX17_CONSTEXPR int
00758       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00759       {
00760         for (size_t __i = 0; __i < __n; ++__i)
00761           if (lt(__s1[__i], __s2[__i]))
00762             return -1;
00763           else if (lt(__s2[__i], __s1[__i]))
00764             return 1;
00765         return 0;
00766       }
00767 
00768       static _GLIBCXX17_CONSTEXPR size_t
00769       length(const char_type* __s)
00770       {
00771         size_t __i = 0;
00772         while (!eq(__s[__i], char_type()))
00773           ++__i;
00774         return __i;
00775       }
00776 
00777       static _GLIBCXX17_CONSTEXPR const char_type*
00778       find(const char_type* __s, size_t __n, const char_type& __a)
00779       {
00780         for (size_t __i = 0; __i < __n; ++__i)
00781           if (eq(__s[__i], __a))
00782             return __s + __i;
00783         return 0;
00784       }
00785 
00786       static char_type*
00787       move(char_type* __s1, const char_type* __s2, size_t __n)
00788       {
00789         if (__n == 0)
00790           return __s1;
00791         return (static_cast<char_type*>
00792                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00793       }
00794 
00795       static char_type*
00796       copy(char_type* __s1, const char_type* __s2, size_t __n)
00797       { 
00798         if (__n == 0)
00799           return __s1;
00800         return (static_cast<char_type*>
00801                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00802       }
00803 
00804       static char_type*
00805       assign(char_type* __s, size_t __n, char_type __a)
00806       {
00807         for (size_t __i = 0; __i < __n; ++__i)
00808           assign(__s[__i], __a);
00809         return __s;
00810       }
00811 
00812       static constexpr char_type
00813       to_char_type(const int_type& __c) noexcept
00814       { return char_type(__c); }
00815 
00816       static constexpr int_type
00817       to_int_type(const char_type& __c) noexcept
00818       { return int_type(__c); }
00819 
00820       static constexpr bool
00821       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00822       { return __c1 == __c2; }
00823 
00824       static constexpr int_type
00825       eof() noexcept
00826       { return static_cast<int_type>(-1); }
00827 
00828       static constexpr int_type
00829       not_eof(const int_type& __c) noexcept
00830       { return eq_int_type(__c, eof()) ? 0 : __c; }
00831     };
00832 
00833 _GLIBCXX_END_NAMESPACE_VERSION
00834 } // namespace
00835 
00836 #endif  // C++11
00837 
00838 #endif // _CHAR_TRAITS_H