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