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-2017 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 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046 
00047   /**
00048    *  @brief  Mapping from character type to associated types.
00049    *
00050    *  @note This is an implementation class for the generic version
00051    *  of char_traits.  It defines int_type, off_type, pos_type, and
00052    *  state_type.  By default these are unsigned long, streamoff,
00053    *  streampos, and mbstate_t.  Users who need a different set of
00054    *  types, but who don't need to change the definitions of any function
00055    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
00056    *  while leaving __gnu_cxx::char_traits alone. */
00057   template<typename _CharT>
00058     struct _Char_types
00059     {
00060       typedef unsigned long   int_type;
00061       typedef std::streampos  pos_type;
00062       typedef std::streamoff  off_type;
00063       typedef std::mbstate_t  state_type;
00064     };
00065 
00066 
00067   /**
00068    *  @brief  Base class used to implement std::char_traits.
00069    *
00070    *  @note For any given actual character type, this definition is
00071    *  probably wrong.  (Most of the member functions are likely to be
00072    *  right, but the int_type and state_type typedefs, and the eof()
00073    *  member function, are likely to be wrong.)  The reason this class
00074    *  exists is so users can specialize it.  Classes in namespace std
00075    *  may not be specialized for fundamental types, but classes in
00076    *  namespace __gnu_cxx may be.
00077    *
00078    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
00079    *  for advice on how to make use of this class for @a unusual character
00080    *  types. Also, check out include/ext/pod_char_traits.h.  
00081    */
00082   template<typename _CharT>
00083     struct char_traits
00084     {
00085       typedef _CharT                                    char_type;
00086       typedef typename _Char_types<_CharT>::int_type    int_type;
00087       typedef typename _Char_types<_CharT>::pos_type    pos_type;
00088       typedef typename _Char_types<_CharT>::off_type    off_type;
00089       typedef typename _Char_types<_CharT>::state_type  state_type;
00090 
00091       static _GLIBCXX14_CONSTEXPR void
00092       assign(char_type& __c1, const char_type& __c2)
00093       { __c1 = __c2; }
00094 
00095       static _GLIBCXX_CONSTEXPR bool
00096       eq(const char_type& __c1, const char_type& __c2)
00097       { return __c1 == __c2; }
00098 
00099       static _GLIBCXX_CONSTEXPR bool
00100       lt(const char_type& __c1, const char_type& __c2)
00101       { return __c1 < __c2; }
00102 
00103       static _GLIBCXX14_CONSTEXPR int
00104       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
00105 
00106       static _GLIBCXX14_CONSTEXPR std::size_t
00107       length(const char_type* __s);
00108 
00109       static _GLIBCXX14_CONSTEXPR const char_type*
00110       find(const char_type* __s, std::size_t __n, const char_type& __a);
00111 
00112       static char_type*
00113       move(char_type* __s1, const char_type* __s2, std::size_t __n);
00114 
00115       static char_type*
00116       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
00117 
00118       static char_type*
00119       assign(char_type* __s, std::size_t __n, char_type __a);
00120 
00121       static _GLIBCXX_CONSTEXPR char_type
00122       to_char_type(const int_type& __c)
00123       { return static_cast<char_type>(__c); }
00124 
00125       static _GLIBCXX_CONSTEXPR int_type
00126       to_int_type(const char_type& __c)
00127       { return static_cast<int_type>(__c); }
00128 
00129       static _GLIBCXX_CONSTEXPR bool
00130       eq_int_type(const int_type& __c1, const int_type& __c2)
00131       { return __c1 == __c2; }
00132 
00133       static _GLIBCXX_CONSTEXPR int_type
00134       eof()
00135       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00136 
00137       static _GLIBCXX_CONSTEXPR int_type
00138       not_eof(const int_type& __c)
00139       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
00140     };
00141 
00142 // #define __cpp_lib_constexpr_char_traits 201611
00143 
00144   template<typename _CharT>
00145     _GLIBCXX14_CONSTEXPR int
00146     char_traits<_CharT>::
00147     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
00148     {
00149       for (std::size_t __i = 0; __i < __n; ++__i)
00150         if (lt(__s1[__i], __s2[__i]))
00151           return -1;
00152         else if (lt(__s2[__i], __s1[__i]))
00153           return 1;
00154       return 0;
00155     }
00156 
00157   template<typename _CharT>
00158     _GLIBCXX14_CONSTEXPR std::size_t
00159     char_traits<_CharT>::
00160     length(const char_type* __p)
00161     {
00162       std::size_t __i = 0;
00163       while (!eq(__p[__i], char_type()))
00164         ++__i;
00165       return __i;
00166     }
00167 
00168   template<typename _CharT>
00169     _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
00170     char_traits<_CharT>::
00171     find(const char_type* __s, std::size_t __n, const char_type& __a)
00172     {
00173       for (std::size_t __i = 0; __i < __n; ++__i)
00174         if (eq(__s[__i], __a))
00175           return __s + __i;
00176       return 0;
00177     }
00178 
00179   template<typename _CharT>
00180     typename char_traits<_CharT>::char_type*
00181     char_traits<_CharT>::
00182     move(char_type* __s1, const char_type* __s2, std::size_t __n)
00183     {
00184       return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
00185                                                     __n * sizeof(char_type)));
00186     }
00187 
00188   template<typename _CharT>
00189     typename char_traits<_CharT>::char_type*
00190     char_traits<_CharT>::
00191     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
00192     {
00193       // NB: Inline std::copy so no recursive dependencies.
00194       std::copy(__s2, __s2 + __n, __s1);
00195       return __s1;
00196     }
00197 
00198   template<typename _CharT>
00199     typename char_traits<_CharT>::char_type*
00200     char_traits<_CharT>::
00201     assign(char_type* __s, std::size_t __n, char_type __a)
00202     {
00203       // NB: Inline std::fill_n so no recursive dependencies.
00204       std::fill_n(__s, __n, __a);
00205       return __s;
00206     }
00207 
00208 _GLIBCXX_END_NAMESPACE_VERSION
00209 } // namespace
00210 
00211 namespace std _GLIBCXX_VISIBILITY(default)
00212 {
00213 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00214 
00215   // 21.1
00216   /**
00217    *  @brief  Basis for explicit traits specializations.
00218    *
00219    *  @note  For any given actual character type, this definition is
00220    *  probably wrong.  Since this is just a thin wrapper around
00221    *  __gnu_cxx::char_traits, it is possible to achieve a more
00222    *  appropriate definition by specializing __gnu_cxx::char_traits.
00223    *
00224    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
00225    *  for advice on how to make use of this class for @a unusual character
00226    *  types. Also, check out include/ext/pod_char_traits.h.
00227   */
00228   template<class _CharT>
00229     struct char_traits : public __gnu_cxx::char_traits<_CharT>
00230     { };
00231 
00232 
00233   /// 21.1.3.1  char_traits specializations
00234   template<>
00235     struct char_traits<char>
00236     {
00237       typedef char              char_type;
00238       typedef int               int_type;
00239       typedef streampos         pos_type;
00240       typedef streamoff         off_type;
00241       typedef mbstate_t         state_type;
00242 
00243       static _GLIBCXX17_CONSTEXPR void
00244       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00245       { __c1 = __c2; }
00246 
00247       static _GLIBCXX_CONSTEXPR bool
00248       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00249       { return __c1 == __c2; }
00250 
00251       static _GLIBCXX_CONSTEXPR bool
00252       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00253       {
00254         // LWG 467.
00255         return (static_cast<unsigned char>(__c1)
00256                 < static_cast<unsigned char>(__c2));
00257       }
00258 
00259       static /* _GLIBCXX17_CONSTEXPR */ int
00260       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00261       {
00262         if (__n == 0)
00263           return 0;
00264         return __builtin_memcmp(__s1, __s2, __n);
00265       }
00266 
00267       static /* _GLIBCXX17_CONSTEXPR */ size_t
00268       length(const char_type* __s)
00269       { return __builtin_strlen(__s); }
00270 
00271       static /* _GLIBCXX17_CONSTEXPR */ const char_type*
00272       find(const char_type* __s, size_t __n, const char_type& __a)
00273       {
00274         if (__n == 0)
00275           return 0;
00276         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
00277       }
00278 
00279       static char_type*
00280       move(char_type* __s1, const char_type* __s2, size_t __n)
00281       {
00282         if (__n == 0)
00283           return __s1;
00284         return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
00285       }
00286 
00287       static char_type*
00288       copy(char_type* __s1, const char_type* __s2, size_t __n)
00289       {
00290         if (__n == 0)
00291           return __s1;
00292         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
00293       }
00294 
00295       static char_type*
00296       assign(char_type* __s, size_t __n, char_type __a)
00297       {
00298         if (__n == 0)
00299           return __s;
00300         return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
00301       }
00302 
00303       static _GLIBCXX_CONSTEXPR char_type
00304       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00305       { return static_cast<char_type>(__c); }
00306 
00307       // To keep both the byte 0xff and the eof symbol 0xffffffff
00308       // from ending up as 0xffffffff.
00309       static _GLIBCXX_CONSTEXPR int_type
00310       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00311       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
00312 
00313       static _GLIBCXX_CONSTEXPR bool
00314       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00315       { return __c1 == __c2; }
00316 
00317       static _GLIBCXX_CONSTEXPR int_type
00318       eof() _GLIBCXX_NOEXCEPT
00319       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00320 
00321       static _GLIBCXX_CONSTEXPR int_type
00322       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00323       { return (__c == eof()) ? 0 : __c; }
00324   };
00325 
00326 
00327 #ifdef _GLIBCXX_USE_WCHAR_T
00328   /// 21.1.3.2  char_traits specializations
00329   template<>
00330     struct char_traits<wchar_t>
00331     {
00332       typedef wchar_t           char_type;
00333       typedef wint_t            int_type;
00334       typedef streamoff         off_type;
00335       typedef wstreampos        pos_type;
00336       typedef mbstate_t         state_type;
00337 
00338       static _GLIBCXX17_CONSTEXPR void
00339       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00340       { __c1 = __c2; }
00341 
00342       static _GLIBCXX_CONSTEXPR bool
00343       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00344       { return __c1 == __c2; }
00345 
00346       static _GLIBCXX_CONSTEXPR bool
00347       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00348       { return __c1 < __c2; }
00349 
00350       static /* _GLIBCXX17_CONSTEXPR */ int
00351       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00352       {
00353         if (__n == 0)
00354           return 0;
00355         return wmemcmp(__s1, __s2, __n);
00356       }
00357 
00358       static /* _GLIBCXX17_CONSTEXPR */ size_t
00359       length(const char_type* __s)
00360       { return wcslen(__s); }
00361 
00362       static /* _GLIBCXX17_CONSTEXPR */ const char_type*
00363       find(const char_type* __s, size_t __n, const char_type& __a)
00364       {
00365         if (__n == 0)
00366           return 0;
00367         return wmemchr(__s, __a, __n);
00368       }
00369 
00370       static char_type*
00371       move(char_type* __s1, const char_type* __s2, size_t __n)
00372       {
00373         if (__n == 0)
00374           return __s1;
00375         return wmemmove(__s1, __s2, __n);
00376       }
00377 
00378       static char_type*
00379       copy(char_type* __s1, const char_type* __s2, size_t __n)
00380       {
00381         if (__n == 0)
00382           return __s1;
00383         return wmemcpy(__s1, __s2, __n);
00384       }
00385 
00386       static char_type*
00387       assign(char_type* __s, size_t __n, char_type __a)
00388       {
00389         if (__n == 0)
00390           return __s;
00391         return wmemset(__s, __a, __n);
00392       }
00393 
00394       static _GLIBCXX_CONSTEXPR char_type
00395       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00396       { return char_type(__c); }
00397 
00398       static _GLIBCXX_CONSTEXPR int_type
00399       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00400       { return int_type(__c); }
00401 
00402       static _GLIBCXX_CONSTEXPR bool
00403       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00404       { return __c1 == __c2; }
00405 
00406       static _GLIBCXX_CONSTEXPR int_type
00407       eof() _GLIBCXX_NOEXCEPT
00408       { return static_cast<int_type>(WEOF); }
00409 
00410       static _GLIBCXX_CONSTEXPR int_type
00411       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00412       { return eq_int_type(__c, eof()) ? 0 : __c; }
00413   };
00414 #endif //_GLIBCXX_USE_WCHAR_T
00415 
00416 _GLIBCXX_END_NAMESPACE_VERSION
00417 } // namespace
00418 
00419 #if ((__cplusplus >= 201103L) \
00420      && defined(_GLIBCXX_USE_C99_STDINT_TR1))
00421 
00422 #include <cstdint>
00423 
00424 namespace std _GLIBCXX_VISIBILITY(default)
00425 {
00426 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00427 
00428   template<>
00429     struct char_traits<char16_t>
00430     {
00431       typedef char16_t          char_type;
00432       typedef uint_least16_t    int_type;
00433       typedef streamoff         off_type;
00434       typedef u16streampos      pos_type;
00435       typedef mbstate_t         state_type;
00436 
00437       static _GLIBCXX17_CONSTEXPR void
00438       assign(char_type& __c1, const char_type& __c2) noexcept
00439       { __c1 = __c2; }
00440 
00441       static constexpr bool
00442       eq(const char_type& __c1, const char_type& __c2) noexcept
00443       { return __c1 == __c2; }
00444 
00445       static constexpr bool
00446       lt(const char_type& __c1, const char_type& __c2) noexcept
00447       { return __c1 < __c2; }
00448 
00449       static _GLIBCXX17_CONSTEXPR int
00450       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00451       {
00452         for (size_t __i = 0; __i < __n; ++__i)
00453           if (lt(__s1[__i], __s2[__i]))
00454             return -1;
00455           else if (lt(__s2[__i], __s1[__i]))
00456             return 1;
00457         return 0;
00458       }
00459 
00460       static _GLIBCXX17_CONSTEXPR size_t
00461       length(const char_type* __s)
00462       {
00463         size_t __i = 0;
00464         while (!eq(__s[__i], char_type()))
00465           ++__i;
00466         return __i;
00467       }
00468 
00469       static _GLIBCXX17_CONSTEXPR const char_type*
00470       find(const char_type* __s, size_t __n, const char_type& __a)
00471       {
00472         for (size_t __i = 0; __i < __n; ++__i)
00473           if (eq(__s[__i], __a))
00474             return __s + __i;
00475         return 0;
00476       }
00477 
00478       static char_type*
00479       move(char_type* __s1, const char_type* __s2, size_t __n)
00480       {
00481         if (__n == 0)
00482           return __s1;
00483         return (static_cast<char_type*>
00484                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00485       }
00486 
00487       static char_type*
00488       copy(char_type* __s1, const char_type* __s2, size_t __n)
00489       {
00490         if (__n == 0)
00491           return __s1;
00492         return (static_cast<char_type*>
00493                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00494       }
00495 
00496       static char_type*
00497       assign(char_type* __s, size_t __n, char_type __a)
00498       {
00499         for (size_t __i = 0; __i < __n; ++__i)
00500           assign(__s[__i], __a);
00501         return __s;
00502       }
00503 
00504       static constexpr char_type
00505       to_char_type(const int_type& __c) noexcept
00506       { return char_type(__c); }
00507 
00508       static constexpr int_type
00509       to_int_type(const char_type& __c) noexcept
00510       { return int_type(__c); }
00511 
00512       static constexpr bool
00513       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00514       { return __c1 == __c2; }
00515 
00516       static constexpr int_type
00517       eof() noexcept
00518       { return static_cast<int_type>(-1); }
00519 
00520       static constexpr int_type
00521       not_eof(const int_type& __c) noexcept
00522       { return eq_int_type(__c, eof()) ? 0 : __c; }
00523     };
00524 
00525   template<>
00526     struct char_traits<char32_t>
00527     {
00528       typedef char32_t          char_type;
00529       typedef uint_least32_t    int_type;
00530       typedef streamoff         off_type;
00531       typedef u32streampos      pos_type;
00532       typedef mbstate_t         state_type;
00533 
00534       static _GLIBCXX17_CONSTEXPR void
00535       assign(char_type& __c1, const char_type& __c2) noexcept
00536       { __c1 = __c2; }
00537 
00538       static constexpr bool
00539       eq(const char_type& __c1, const char_type& __c2) noexcept
00540       { return __c1 == __c2; }
00541 
00542       static constexpr bool
00543       lt(const char_type& __c1, const char_type& __c2) noexcept
00544       { return __c1 < __c2; }
00545 
00546       static _GLIBCXX17_CONSTEXPR int
00547       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00548       {
00549         for (size_t __i = 0; __i < __n; ++__i)
00550           if (lt(__s1[__i], __s2[__i]))
00551             return -1;
00552           else if (lt(__s2[__i], __s1[__i]))
00553             return 1;
00554         return 0;
00555       }
00556 
00557       static _GLIBCXX17_CONSTEXPR size_t
00558       length(const char_type* __s)
00559       {
00560         size_t __i = 0;
00561         while (!eq(__s[__i], char_type()))
00562           ++__i;
00563         return __i;
00564       }
00565 
00566       static _GLIBCXX17_CONSTEXPR const char_type*
00567       find(const char_type* __s, size_t __n, const char_type& __a)
00568       {
00569         for (size_t __i = 0; __i < __n; ++__i)
00570           if (eq(__s[__i], __a))
00571             return __s + __i;
00572         return 0;
00573       }
00574 
00575       static char_type*
00576       move(char_type* __s1, const char_type* __s2, size_t __n)
00577       {
00578         if (__n == 0)
00579           return __s1;
00580         return (static_cast<char_type*>
00581                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00582       }
00583 
00584       static char_type*
00585       copy(char_type* __s1, const char_type* __s2, size_t __n)
00586       { 
00587         if (__n == 0)
00588           return __s1;
00589         return (static_cast<char_type*>
00590                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00591       }
00592 
00593       static char_type*
00594       assign(char_type* __s, size_t __n, char_type __a)
00595       {
00596         for (size_t __i = 0; __i < __n; ++__i)
00597           assign(__s[__i], __a);
00598         return __s;
00599       }
00600 
00601       static constexpr char_type
00602       to_char_type(const int_type& __c) noexcept
00603       { return char_type(__c); }
00604 
00605       static constexpr int_type
00606       to_int_type(const char_type& __c) noexcept
00607       { return int_type(__c); }
00608 
00609       static constexpr bool
00610       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00611       { return __c1 == __c2; }
00612 
00613       static constexpr int_type
00614       eof() noexcept
00615       { return static_cast<int_type>(-1); }
00616 
00617       static constexpr int_type
00618       not_eof(const int_type& __c) noexcept
00619       { return eq_int_type(__c, eof()) ? 0 : __c; }
00620     };
00621 
00622 _GLIBCXX_END_NAMESPACE_VERSION
00623 } // namespace
00624 
00625 #endif 
00626 
00627 #endif // _CHAR_TRAITS_H