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, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00004 // 2006, 2007, 2008, 2009, 2010, 2011
00005 // Free Software Foundation, Inc.
00006 //
00007 // This file is part of the GNU ISO C++ Library.  This library is free
00008 // software; you can redistribute it and/or modify it under the
00009 // terms of the GNU General Public License as published by the
00010 // Free Software Foundation; either version 3, or (at your option)
00011 // any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 
00018 // Under Section 7 of GPL version 3, you are granted additional
00019 // permissions described in the GCC Runtime Library Exception, version
00020 // 3.1, as published by the Free Software Foundation.
00021 
00022 // You should have received a copy of the GNU General Public License and
00023 // a copy of the GCC Runtime Library Exception along with this program;
00024 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00025 // <http://www.gnu.org/licenses/>.
00026 
00027 /** @file bits/char_traits.h
00028  *  This is an internal header file, included by other library headers.
00029  *  Do not attempt to use it directly. @headername{string}
00030  */
00031 
00032 //
00033 // ISO C++ 14882: 21  Strings library
00034 //
00035 
00036 #ifndef _CHAR_TRAITS_H
00037 #define _CHAR_TRAITS_H 1
00038 
00039 #pragma GCC system_header
00040 
00041 #include <bits/stl_algobase.h>  // std::copy, std::fill_n
00042 #include <bits/postypes.h>      // For streampos
00043 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
00044 
00045 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00046 {
00047 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00048 
00049   /**
00050    *  @brief  Mapping from character type to associated types.
00051    *
00052    *  @note This is an implementation class for the generic version
00053    *  of char_traits.  It defines int_type, off_type, pos_type, and
00054    *  state_type.  By default these are unsigned long, streamoff,
00055    *  streampos, and mbstate_t.  Users who need a different set of
00056    *  types, but who don't need to change the definitions of any function
00057    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
00058    *  while leaving __gnu_cxx::char_traits alone. */
00059   template<typename _CharT>
00060     struct _Char_types
00061     {
00062       typedef unsigned long   int_type;
00063       typedef std::streampos  pos_type;
00064       typedef std::streamoff  off_type;
00065       typedef std::mbstate_t  state_type;
00066     };
00067 
00068 
00069   /**
00070    *  @brief  Base class used to implement std::char_traits.
00071    *
00072    *  @note For any given actual character type, this definition is
00073    *  probably wrong.  (Most of the member functions are likely to be
00074    *  right, but the int_type and state_type typedefs, and the eof()
00075    *  member function, are likely to be wrong.)  The reason this class
00076    *  exists is so users can specialize it.  Classes in namespace std
00077    *  may not be specialized for fundamental types, but classes in
00078    *  namespace __gnu_cxx may be.
00079    *
00080    *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
00081    *  for advice on how to make use of this class for @a unusual character
00082    *  types. Also, check out include/ext/pod_char_traits.h.  
00083    */
00084   template<typename _CharT>
00085     struct char_traits
00086     {
00087       typedef _CharT                                    char_type;
00088       typedef typename _Char_types<_CharT>::int_type    int_type;
00089       typedef typename _Char_types<_CharT>::pos_type    pos_type;
00090       typedef typename _Char_types<_CharT>::off_type    off_type;
00091       typedef typename _Char_types<_CharT>::state_type  state_type;
00092 
00093       static void
00094       assign(char_type& __c1, const char_type& __c2)
00095       { __c1 = __c2; }
00096 
00097       static _GLIBCXX_CONSTEXPR bool
00098       eq(const char_type& __c1, const char_type& __c2)
00099       { return __c1 == __c2; }
00100 
00101       static _GLIBCXX_CONSTEXPR bool
00102       lt(const char_type& __c1, const char_type& __c2)
00103       { return __c1 < __c2; }
00104 
00105       static int
00106       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
00107 
00108       static std::size_t
00109       length(const char_type* __s);
00110 
00111       static const char_type*
00112       find(const char_type* __s, std::size_t __n, const char_type& __a);
00113 
00114       static char_type*
00115       move(char_type* __s1, const char_type* __s2, std::size_t __n);
00116 
00117       static char_type*
00118       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
00119 
00120       static char_type*
00121       assign(char_type* __s, std::size_t __n, char_type __a);
00122 
00123       static _GLIBCXX_CONSTEXPR char_type
00124       to_char_type(const int_type& __c)
00125       { return static_cast<char_type>(__c); }
00126 
00127       static _GLIBCXX_CONSTEXPR int_type
00128       to_int_type(const char_type& __c)
00129       { return static_cast<int_type>(__c); }
00130 
00131       static _GLIBCXX_CONSTEXPR bool
00132       eq_int_type(const int_type& __c1, const int_type& __c2)
00133       { return __c1 == __c2; }
00134 
00135       static _GLIBCXX_CONSTEXPR int_type
00136       eof()
00137       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00138 
00139       static _GLIBCXX_CONSTEXPR int_type
00140       not_eof(const int_type& __c)
00141       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
00142     };
00143 
00144   template<typename _CharT>
00145     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     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     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 http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
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 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       { return __c1 < __c2; }
00254 
00255       static int
00256       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00257       { return __builtin_memcmp(__s1, __s2, __n); }
00258 
00259       static size_t
00260       length(const char_type* __s)
00261       { return __builtin_strlen(__s); }
00262 
00263       static const char_type*
00264       find(const char_type* __s, size_t __n, const char_type& __a)
00265       { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
00266 
00267       static char_type*
00268       move(char_type* __s1, const char_type* __s2, size_t __n)
00269       { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
00270 
00271       static char_type*
00272       copy(char_type* __s1, const char_type* __s2, size_t __n)
00273       { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
00274 
00275       static char_type*
00276       assign(char_type* __s, size_t __n, char_type __a)
00277       { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
00278 
00279       static _GLIBCXX_CONSTEXPR char_type
00280       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00281       { return static_cast<char_type>(__c); }
00282 
00283       // To keep both the byte 0xff and the eof symbol 0xffffffff
00284       // from ending up as 0xffffffff.
00285       static _GLIBCXX_CONSTEXPR int_type
00286       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00287       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
00288 
00289       static _GLIBCXX_CONSTEXPR bool
00290       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00291       { return __c1 == __c2; }
00292 
00293       static _GLIBCXX_CONSTEXPR int_type
00294       eof() _GLIBCXX_NOEXCEPT
00295       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00296 
00297       static _GLIBCXX_CONSTEXPR int_type
00298       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00299       { return (__c == eof()) ? 0 : __c; }
00300   };
00301 
00302 
00303 #ifdef _GLIBCXX_USE_WCHAR_T
00304   /// 21.1.3.2  char_traits specializations
00305   template<>
00306     struct char_traits<wchar_t>
00307     {
00308       typedef wchar_t           char_type;
00309       typedef wint_t            int_type;
00310       typedef streamoff         off_type;
00311       typedef wstreampos        pos_type;
00312       typedef mbstate_t         state_type;
00313 
00314       static void
00315       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00316       { __c1 = __c2; }
00317 
00318       static _GLIBCXX_CONSTEXPR bool
00319       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00320       { return __c1 == __c2; }
00321 
00322       static _GLIBCXX_CONSTEXPR bool
00323       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
00324       { return __c1 < __c2; }
00325 
00326       static int
00327       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00328       { return wmemcmp(__s1, __s2, __n); }
00329 
00330       static size_t
00331       length(const char_type* __s)
00332       { return wcslen(__s); }
00333 
00334       static const char_type*
00335       find(const char_type* __s, size_t __n, const char_type& __a)
00336       { return wmemchr(__s, __a, __n); }
00337 
00338       static char_type*
00339       move(char_type* __s1, const char_type* __s2, size_t __n)
00340       { return wmemmove(__s1, __s2, __n); }
00341 
00342       static char_type*
00343       copy(char_type* __s1, const char_type* __s2, size_t __n)
00344       { return wmemcpy(__s1, __s2, __n); }
00345 
00346       static char_type*
00347       assign(char_type* __s, size_t __n, char_type __a)
00348       { return wmemset(__s, __a, __n); }
00349 
00350       static _GLIBCXX_CONSTEXPR char_type
00351       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
00352       { return char_type(__c); }
00353 
00354       static _GLIBCXX_CONSTEXPR int_type
00355       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
00356       { return int_type(__c); }
00357 
00358       static _GLIBCXX_CONSTEXPR bool
00359       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
00360       { return __c1 == __c2; }
00361 
00362       static _GLIBCXX_CONSTEXPR int_type
00363       eof() _GLIBCXX_NOEXCEPT
00364       { return static_cast<int_type>(WEOF); }
00365 
00366       static _GLIBCXX_CONSTEXPR int_type
00367       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
00368       { return eq_int_type(__c, eof()) ? 0 : __c; }
00369   };
00370 #endif //_GLIBCXX_USE_WCHAR_T
00371 
00372 _GLIBCXX_END_NAMESPACE_VERSION
00373 } // namespace
00374 
00375 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
00376      && defined(_GLIBCXX_USE_C99_STDINT_TR1))
00377 
00378 #include <cstdint>
00379 
00380 namespace std _GLIBCXX_VISIBILITY(default)
00381 {
00382 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00383 
00384   template<>
00385     struct char_traits<char16_t>
00386     {
00387       typedef char16_t          char_type;
00388       typedef uint_least16_t    int_type;
00389       typedef streamoff         off_type;
00390       typedef u16streampos      pos_type;
00391       typedef mbstate_t         state_type;
00392 
00393       static void
00394       assign(char_type& __c1, const char_type& __c2) noexcept
00395       { __c1 = __c2; }
00396 
00397       static constexpr bool
00398       eq(const char_type& __c1, const char_type& __c2) noexcept
00399       { return __c1 == __c2; }
00400 
00401       static constexpr bool
00402       lt(const char_type& __c1, const char_type& __c2) noexcept
00403       { return __c1 < __c2; }
00404 
00405       static int
00406       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00407       {
00408     for (size_t __i = 0; __i < __n; ++__i)
00409       if (lt(__s1[__i], __s2[__i]))
00410         return -1;
00411       else if (lt(__s2[__i], __s1[__i]))
00412         return 1;
00413     return 0;
00414       }
00415 
00416       static size_t
00417       length(const char_type* __s)
00418       {
00419     size_t __i = 0;
00420     while (!eq(__s[__i], char_type()))
00421       ++__i;
00422     return __i;
00423       }
00424 
00425       static const char_type*
00426       find(const char_type* __s, size_t __n, const char_type& __a)
00427       {
00428     for (size_t __i = 0; __i < __n; ++__i)
00429       if (eq(__s[__i], __a))
00430         return __s + __i;
00431     return 0;
00432       }
00433 
00434       static char_type*
00435       move(char_type* __s1, const char_type* __s2, size_t __n)
00436       {
00437     return (static_cast<char_type*>
00438         (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00439       }
00440 
00441       static char_type*
00442       copy(char_type* __s1, const char_type* __s2, size_t __n)
00443       {
00444     return (static_cast<char_type*>
00445         (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00446       }
00447 
00448       static char_type*
00449       assign(char_type* __s, size_t __n, char_type __a)
00450       {
00451     for (size_t __i = 0; __i < __n; ++__i)
00452       assign(__s[__i], __a);
00453     return __s;
00454       }
00455 
00456       static constexpr char_type
00457       to_char_type(const int_type& __c) noexcept
00458       { return char_type(__c); }
00459 
00460       static constexpr int_type
00461       to_int_type(const char_type& __c) noexcept
00462       { return int_type(__c); }
00463 
00464       static constexpr bool
00465       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00466       { return __c1 == __c2; }
00467 
00468       static constexpr int_type
00469       eof() noexcept
00470       { return static_cast<int_type>(-1); }
00471 
00472       static constexpr int_type
00473       not_eof(const int_type& __c) noexcept
00474       { return eq_int_type(__c, eof()) ? 0 : __c; }
00475     };
00476 
00477   template<>
00478     struct char_traits<char32_t>
00479     {
00480       typedef char32_t          char_type;
00481       typedef uint_least32_t    int_type;
00482       typedef streamoff         off_type;
00483       typedef u32streampos      pos_type;
00484       typedef mbstate_t         state_type;
00485 
00486       static void
00487       assign(char_type& __c1, const char_type& __c2) noexcept
00488       { __c1 = __c2; }
00489 
00490       static constexpr bool
00491       eq(const char_type& __c1, const char_type& __c2) noexcept
00492       { return __c1 == __c2; }
00493 
00494       static constexpr bool
00495       lt(const char_type& __c1, const char_type& __c2) noexcept
00496       { return __c1 < __c2; }
00497 
00498       static int
00499       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00500       {
00501     for (size_t __i = 0; __i < __n; ++__i)
00502       if (lt(__s1[__i], __s2[__i]))
00503         return -1;
00504       else if (lt(__s2[__i], __s1[__i]))
00505         return 1;
00506     return 0;
00507       }
00508 
00509       static size_t
00510       length(const char_type* __s)
00511       {
00512     size_t __i = 0;
00513     while (!eq(__s[__i], char_type()))
00514       ++__i;
00515     return __i;
00516       }
00517 
00518       static const char_type*
00519       find(const char_type* __s, size_t __n, const char_type& __a)
00520       {
00521     for (size_t __i = 0; __i < __n; ++__i)
00522       if (eq(__s[__i], __a))
00523         return __s + __i;
00524     return 0;
00525       }
00526 
00527       static char_type*
00528       move(char_type* __s1, const char_type* __s2, size_t __n)
00529       {
00530     return (static_cast<char_type*>
00531         (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00532       }
00533 
00534       static char_type*
00535       copy(char_type* __s1, const char_type* __s2, size_t __n)
00536       { 
00537     return (static_cast<char_type*>
00538         (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00539       }
00540 
00541       static char_type*
00542       assign(char_type* __s, size_t __n, char_type __a)
00543       {
00544     for (size_t __i = 0; __i < __n; ++__i)
00545       assign(__s[__i], __a);
00546     return __s;
00547       }
00548 
00549       static constexpr char_type
00550       to_char_type(const int_type& __c) noexcept
00551       { return char_type(__c); }
00552 
00553       static constexpr int_type
00554       to_int_type(const char_type& __c) noexcept
00555       { return int_type(__c); }
00556 
00557       static constexpr bool
00558       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
00559       { return __c1 == __c2; }
00560 
00561       static constexpr int_type
00562       eof() noexcept
00563       { return static_cast<int_type>(-1); }
00564 
00565       static constexpr int_type
00566       not_eof(const int_type& __c) noexcept
00567       { return eq_int_type(__c, eof()) ? 0 : __c; }
00568     };
00569 
00570 _GLIBCXX_END_NAMESPACE_VERSION
00571 } // namespace
00572 
00573 #endif 
00574 
00575 #endif // _CHAR_TRAITS_H