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
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 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
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 http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
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 bool
00096       eq(const char_type& __c1, const char_type& __c2)
00097       { return __c1 == __c2; }
00098 
00099       static 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 char_type
00122       to_char_type(const int_type& __c)
00123       { return static_cast<char_type>(__c); }
00124 
00125       static int_type
00126       to_int_type(const char_type& __c)
00127       { return static_cast<int_type>(__c); }
00128 
00129       static bool
00130       eq_int_type(const int_type& __c1, const int_type& __c2)
00131       { return __c1 == __c2; }
00132 
00133       static int_type
00134       eof()
00135       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00136 
00137       static 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
00207 
00208 _GLIBCXX_BEGIN_NAMESPACE(std)
00209 
00210   // 21.1
00211   /**
00212    *  @brief  Basis for explicit traits specializations.
00213    *
00214    *  @note  For any given actual character type, this definition is
00215    *  probably wrong.  Since this is just a thin wrapper around
00216    *  __gnu_cxx::char_traits, it is possible to achieve a more
00217    *  appropriate definition by specializing __gnu_cxx::char_traits.
00218    *
00219    *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
00220    *  for advice on how to make use of this class for @a unusual character
00221    *  types. Also, check out include/ext/pod_char_traits.h.
00222   */
00223   template<class _CharT>
00224     struct char_traits : public __gnu_cxx::char_traits<_CharT>
00225     { };
00226 
00227 
00228   /// 21.1.3.1  char_traits specializations
00229   template<>
00230     struct char_traits<char>
00231     {
00232       typedef char              char_type;
00233       typedef int               int_type;
00234       typedef streampos         pos_type;
00235       typedef streamoff         off_type;
00236       typedef mbstate_t         state_type;
00237 
00238       static void
00239       assign(char_type& __c1, const char_type& __c2)
00240       { __c1 = __c2; }
00241 
00242       static bool
00243       eq(const char_type& __c1, const char_type& __c2)
00244       { return __c1 == __c2; }
00245 
00246       static bool
00247       lt(const char_type& __c1, const char_type& __c2)
00248       { return __c1 < __c2; }
00249 
00250       static int
00251       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00252       { return __builtin_memcmp(__s1, __s2, __n); }
00253 
00254       static size_t
00255       length(const char_type* __s)
00256       { return __builtin_strlen(__s); }
00257 
00258       static const char_type*
00259       find(const char_type* __s, size_t __n, const char_type& __a)
00260       { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
00261 
00262       static char_type*
00263       move(char_type* __s1, const char_type* __s2, size_t __n)
00264       { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
00265 
00266       static char_type*
00267       copy(char_type* __s1, const char_type* __s2, size_t __n)
00268       { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
00269 
00270       static char_type*
00271       assign(char_type* __s, size_t __n, char_type __a)
00272       { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
00273 
00274       static char_type
00275       to_char_type(const int_type& __c)
00276       { return static_cast<char_type>(__c); }
00277 
00278       // To keep both the byte 0xff and the eof symbol 0xffffffff
00279       // from ending up as 0xffffffff.
00280       static int_type
00281       to_int_type(const char_type& __c)
00282       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
00283 
00284       static bool
00285       eq_int_type(const int_type& __c1, const int_type& __c2)
00286       { return __c1 == __c2; }
00287 
00288       static int_type
00289       eof()
00290       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
00291 
00292       static int_type
00293       not_eof(const int_type& __c)
00294       { return (__c == eof()) ? 0 : __c; }
00295   };
00296 
00297 
00298 #ifdef _GLIBCXX_USE_WCHAR_T
00299   /// 21.1.3.2  char_traits specializations
00300   template<>
00301     struct char_traits<wchar_t>
00302     {
00303       typedef wchar_t           char_type;
00304       typedef wint_t            int_type;
00305       typedef streamoff         off_type;
00306       typedef wstreampos        pos_type;
00307       typedef mbstate_t         state_type;
00308 
00309       static void
00310       assign(char_type& __c1, const char_type& __c2)
00311       { __c1 = __c2; }
00312 
00313       static bool
00314       eq(const char_type& __c1, const char_type& __c2)
00315       { return __c1 == __c2; }
00316 
00317       static bool
00318       lt(const char_type& __c1, const char_type& __c2)
00319       { return __c1 < __c2; }
00320 
00321       static int
00322       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00323       { return wmemcmp(__s1, __s2, __n); }
00324 
00325       static size_t
00326       length(const char_type* __s)
00327       { return wcslen(__s); }
00328 
00329       static const char_type*
00330       find(const char_type* __s, size_t __n, const char_type& __a)
00331       { return wmemchr(__s, __a, __n); }
00332 
00333       static char_type*
00334       move(char_type* __s1, const char_type* __s2, size_t __n)
00335       { return wmemmove(__s1, __s2, __n); }
00336 
00337       static char_type*
00338       copy(char_type* __s1, const char_type* __s2, size_t __n)
00339       { return wmemcpy(__s1, __s2, __n); }
00340 
00341       static char_type*
00342       assign(char_type* __s, size_t __n, char_type __a)
00343       { return wmemset(__s, __a, __n); }
00344 
00345       static char_type
00346       to_char_type(const int_type& __c)
00347       { return char_type(__c); }
00348 
00349       static int_type
00350       to_int_type(const char_type& __c)
00351       { return int_type(__c); }
00352 
00353       static bool
00354       eq_int_type(const int_type& __c1, const int_type& __c2)
00355       { return __c1 == __c2; }
00356 
00357       static int_type
00358       eof()
00359       { return static_cast<int_type>(WEOF); }
00360 
00361       static int_type
00362       not_eof(const int_type& __c)
00363       { return eq_int_type(__c, eof()) ? 0 : __c; }
00364   };
00365 #endif //_GLIBCXX_USE_WCHAR_T
00366 
00367 _GLIBCXX_END_NAMESPACE
00368 
00369 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
00370      && defined(_GLIBCXX_USE_C99_STDINT_TR1))
00371 
00372 #include <cstdint>
00373 
00374 _GLIBCXX_BEGIN_NAMESPACE(std)
00375 
00376   template<>
00377     struct char_traits<char16_t>
00378     {
00379       typedef char16_t          char_type;
00380       typedef uint_least16_t    int_type;
00381       typedef streamoff         off_type;
00382       typedef u16streampos      pos_type;
00383       typedef mbstate_t         state_type;
00384 
00385       static void
00386       assign(char_type& __c1, const char_type& __c2)
00387       { __c1 = __c2; }
00388 
00389       static bool
00390       eq(const char_type& __c1, const char_type& __c2)
00391       { return __c1 == __c2; }
00392 
00393       static bool
00394       lt(const char_type& __c1, const char_type& __c2)
00395       { return __c1 < __c2; }
00396 
00397       static int
00398       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00399       {
00400     for (size_t __i = 0; __i < __n; ++__i)
00401       if (lt(__s1[__i], __s2[__i]))
00402         return -1;
00403       else if (lt(__s2[__i], __s1[__i]))
00404         return 1;
00405     return 0;
00406       }
00407 
00408       static size_t
00409       length(const char_type* __s)
00410       {
00411     size_t __i = 0;
00412     while (!eq(__s[__i], char_type()))
00413       ++__i;
00414     return __i;
00415       }
00416 
00417       static const char_type*
00418       find(const char_type* __s, size_t __n, const char_type& __a)
00419       {
00420     for (size_t __i = 0; __i < __n; ++__i)
00421       if (eq(__s[__i], __a))
00422         return __s + __i;
00423     return 0;
00424       }
00425 
00426       static char_type*
00427       move(char_type* __s1, const char_type* __s2, size_t __n)
00428       {
00429     return (static_cast<char_type*>
00430         (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00431       }
00432 
00433       static char_type*
00434       copy(char_type* __s1, const char_type* __s2, size_t __n)
00435       {
00436     return (static_cast<char_type*>
00437         (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00438       }
00439 
00440       static char_type*
00441       assign(char_type* __s, size_t __n, char_type __a)
00442       {
00443     for (size_t __i = 0; __i < __n; ++__i)
00444       assign(__s[__i], __a);
00445     return __s;
00446       }
00447 
00448       static char_type
00449       to_char_type(const int_type& __c)
00450       { return char_type(__c); }
00451 
00452       static int_type
00453       to_int_type(const char_type& __c)
00454       { return int_type(__c); }
00455 
00456       static bool
00457       eq_int_type(const int_type& __c1, const int_type& __c2)
00458       { return __c1 == __c2; }
00459 
00460       static int_type
00461       eof()
00462       { return static_cast<int_type>(-1); }
00463 
00464       static int_type
00465       not_eof(const int_type& __c)
00466       { return eq_int_type(__c, eof()) ? 0 : __c; }
00467     };
00468 
00469   template<>
00470     struct char_traits<char32_t>
00471     {
00472       typedef char32_t          char_type;
00473       typedef uint_least32_t    int_type;
00474       typedef streamoff         off_type;
00475       typedef u32streampos      pos_type;
00476       typedef mbstate_t         state_type;
00477 
00478       static void
00479       assign(char_type& __c1, const char_type& __c2)
00480       { __c1 = __c2; }
00481 
00482       static bool
00483       eq(const char_type& __c1, const char_type& __c2)
00484       { return __c1 == __c2; }
00485 
00486       static bool
00487       lt(const char_type& __c1, const char_type& __c2)
00488       { return __c1 < __c2; }
00489 
00490       static int
00491       compare(const char_type* __s1, const char_type* __s2, size_t __n)
00492       {
00493     for (size_t __i = 0; __i < __n; ++__i)
00494       if (lt(__s1[__i], __s2[__i]))
00495         return -1;
00496       else if (lt(__s2[__i], __s1[__i]))
00497         return 1;
00498     return 0;
00499       }
00500 
00501       static size_t
00502       length(const char_type* __s)
00503       {
00504     size_t __i = 0;
00505     while (!eq(__s[__i], char_type()))
00506       ++__i;
00507     return __i;
00508       }
00509 
00510       static const char_type*
00511       find(const char_type* __s, size_t __n, const char_type& __a)
00512       {
00513     for (size_t __i = 0; __i < __n; ++__i)
00514       if (eq(__s[__i], __a))
00515         return __s + __i;
00516     return 0;
00517       }
00518 
00519       static char_type*
00520       move(char_type* __s1, const char_type* __s2, size_t __n)
00521       {
00522     return (static_cast<char_type*>
00523         (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
00524       }
00525 
00526       static char_type*
00527       copy(char_type* __s1, const char_type* __s2, size_t __n)
00528       { 
00529     return (static_cast<char_type*>
00530         (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
00531       }
00532 
00533       static char_type*
00534       assign(char_type* __s, size_t __n, char_type __a)
00535       {
00536     for (size_t __i = 0; __i < __n; ++__i)
00537       assign(__s[__i], __a);
00538     return __s;
00539       }
00540 
00541       static char_type
00542       to_char_type(const int_type& __c)
00543       { return char_type(__c); }
00544 
00545       static int_type
00546       to_int_type(const char_type& __c)
00547       { return int_type(__c); }
00548 
00549       static bool
00550       eq_int_type(const int_type& __c1, const int_type& __c2)
00551       { return __c1 == __c2; }
00552 
00553       static int_type
00554       eof()
00555       { return static_cast<int_type>(-1); }
00556 
00557       static int_type
00558       not_eof(const int_type& __c)
00559       { return eq_int_type(__c, eof()) ? 0 : __c; }
00560     };
00561 
00562 _GLIBCXX_END_NAMESPACE
00563 
00564 #endif 
00565 
00566 #endif // _CHAR_TRAITS_H