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