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

Generated on Tue Apr 21 13:13:26 2009 for libstdc++ by  doxygen 1.5.8