# 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
    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 2, 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 // You should have received a copy of the GNU General Public License along
    00019 // with this library; see the file COPYING.  If not, write to the Free
    00020 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00021 // USA.
    00022
    00023 // As a special exception, you may use this file as part of a free software
    00024 // library without restriction.  Specifically, if other files instantiate
    00025 // templates or use macros or inline functions from this file, or you compile
    00026 // this file and link it with other files to produce an executable, this
    00027 // file does not by itself cause the resulting executable to be covered by
    00028 // the GNU General Public License.  This exception does not however
    00029 // invalidate any other reasons why the executable file might be covered by
    00030 // the GNU General Public License.
    00031
    00032 /** @file char_traits.h
    00033  *  This is an internal header file, included by other library headers.
    00034  *  You should not attempt to use it directly.
    00035  */
    00036
    00037 //
    00038 // ISO C++ 14882: 21  Strings library
    00039 //
    00040
    00041 #ifndef _CHAR_TRAITS_H
    00042 #define _CHAR_TRAITS_H 1
    00043
    00044 #pragma GCC system_header
    00045
    00046 #include <bits/stl_algobase.h>  // std::copy, std::fill_n
    00047 #include <bits/postypes.h>      // For streampos
    00048 #include <cstdio>               // For EOF
    00049 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
    00050
    00051 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
    00052
    00053   /**
    00054    *  @brief  Mapping from character type to associated types.
    00055    *
    00056    *  @note This is an implementation class for the generic version
    00057    *  of char_traits.  It defines int_type, off_type, pos_type, and
    00058    *  state_type.  By default these are unsigned long, streamoff,
    00059    *  streampos, and mbstate_t.  Users who need a different set of
    00060    *  types, but who don't need to change the definitions of any function
    00061    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
    00062    *  while leaving __gnu_cxx::char_traits alone. */
    00063   template<typename _CharT>
    00064     struct _Char_types
    00065     {
    00066       typedef unsigned long   int_type;
    00067       typedef std::streampos  pos_type;
    00068       typedef std::streamoff  off_type;
    00069       typedef std::mbstate_t  state_type;
    00070     };
    00071
    00072
    00073   /**
    00074    *  @brief  Base class used to implement std::char_traits.
    00075    *
    00076    *  @note For any given actual character type, this definition is
    00077    *  probably wrong.  (Most of the member functions are likely to be
    00078    *  right, but the int_type and state_type typedefs, and the eof()
    00079    *  member function, are likely to be wrong.)  The reason this class
    00080    *  exists is so users can specialize it.  Classes in namespace std
    00081    *  may not be specialized for fundamental types, but classes in
    00082    *  namespace __gnu_cxx may be.
    00083    *
    00084    *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
    00085    *  for advice on how to make use of this class for "unusual" character
    00086    *  types. Also, check out include/ext/pod_char_traits.h.
    00087    */
    00088   template<typename _CharT>
    00089     struct char_traits
    00090     {
    00091       typedef _CharT                                    char_type;
    00092       typedef typename _Char_types<_CharT>::int_type    int_type;
    00093       typedef typename _Char_types<_CharT>::pos_type    pos_type;
    00094       typedef typename _Char_types<_CharT>::off_type    off_type;
    00095       typedef typename _Char_types<_CharT>::state_type  state_type;
    00096
    00097       static void
    00098       assign(char_type& __c1, const char_type& __c2)
    00099       { __c1 = __c2; }
    00100
    00101       static bool
    00102       eq(const char_type& __c1, const char_type& __c2)
    00103       { return __c1 == __c2; }
    00104
    00105       static bool
    00106       lt(const char_type& __c1, const char_type& __c2)
    00107       { return __c1 < __c2; }
    00108
    00109       static int
    00110       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
    00111
    00112       static std::size_t
    00113       length(const char_type* __s);
    00114
    00115       static const char_type*
    00116       find(const char_type* __s, std::size_t __n, const char_type& __a);
    00117
    00118       static char_type*
    00119       move(char_type* __s1, const char_type* __s2, std::size_t __n);
    00120
    00121       static char_type*
    00122       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
    00123
    00124       static char_type*
    00125       assign(char_type* __s, std::size_t __n, char_type __a);
    00126
    00127       static char_type
    00128       to_char_type(const int_type& __c)
    00129       { return static_cast<char_type>(__c); }
    00130
    00131       static int_type
    00132       to_int_type(const char_type& __c)
    00133       { return static_cast<int_type>(__c); }
    00134
    00135       static bool
    00136       eq_int_type(const int_type& __c1, const int_type& __c2)
    00137       { return __c1 == __c2; }
    00138
    00139       static int_type
    00140       eof()
    00141       { return static_cast<int_type>(EOF); }
    00142
    00143       static int_type
    00144       not_eof(const int_type& __c)
    00145       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
    00146     };
    00147
    00148   template<typename _CharT>
    00149     int
    00150     char_traits<_CharT>::
    00151     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
    00152     {
    00153       for (std::size_t __i = 0; __i < __n; ++__i)
    00154     if (lt(__s1[__i], __s2[__i]))
    00155       return -1;
    00156     else if (lt(__s2[__i], __s1[__i]))
    00157       return 1;
    00158       return 0;
    00159     }
    00160
    00161   template<typename _CharT>
    00162     std::size_t
    00163     char_traits<_CharT>::
    00164     length(const char_type* __p)
    00165     {
    00166       std::size_t __i = 0;
    00167       while (!eq(__p[__i], char_type()))
    00168         ++__i;
    00169       return __i;
    00170     }
    00171
    00172   template<typename _CharT>
    00173     const typename char_traits<_CharT>::char_type*
    00174     char_traits<_CharT>::
    00175     find(const char_type* __s, std::size_t __n, const char_type& __a)
    00176     {
    00177       for (std::size_t __i = 0; __i < __n; ++__i)
    00178         if (eq(__s[__i], __a))
    00179           return __s + __i;
    00180       return 0;
    00181     }
    00182
    00183   template<typename _CharT>
    00184     typename char_traits<_CharT>::char_type*
    00185     char_traits<_CharT>::
    00186     move(char_type* __s1, const char_type* __s2, std::size_t __n)
    00187     {
    00188       return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
    00189                             __n * sizeof(char_type)));
    00190     }
    00191
    00192   template<typename _CharT>
    00193     typename char_traits<_CharT>::char_type*
    00194     char_traits<_CharT>::
    00195     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
    00196     {
    00197       // NB: Inline std::copy so no recursive dependencies.
    00198       std::copy(__s2, __s2 + __n, __s1);
    00199       return __s1;
    00200     }
    00201
    00202   template<typename _CharT>
    00203     typename char_traits<_CharT>::char_type*
    00204     char_traits<_CharT>::
    00205     assign(char_type* __s, std::size_t __n, char_type __a)
    00206     {
    00207       // NB: Inline std::fill_n so no recursive dependencies.
    00208       std::fill_n(__s, __n, __a);
    00209       return __s;
    00210     }
    00211
    00212 _GLIBCXX_END_NAMESPACE
    00213
    00214 _GLIBCXX_BEGIN_NAMESPACE(std)
    00215
    00216   // 21.1
    00217   /**
    00218    *  @brief  Basis for explicit traits specializations.
    00219    *
    00220    *  @note  For any given actual character type, this definition is
    00221    *  probably wrong.  Since this is just a thin wrapper around
    00222    *  __gnu_cxx::char_traits, it is possible to achieve a more
    00223    *  appropriate definition by specializing __gnu_cxx::char_traits.
    00224    *
    00225    *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
    00226    *  for advice on how to make use of this class for "unusual" character
    00227    *  types. Also, check out include/ext/pod_char_traits.h.
    00228   */
    00229   template<class _CharT>
    00230     struct char_traits : public __gnu_cxx::char_traits<_CharT>
    00231     { };
    00232
    00233
    00234   /// 21.1.3.1  char_traits specializations
    00235   template<>
    00236     struct char_traits<char>
    00237     {
    00238       typedef char              char_type;
    00239       typedef int               int_type;
    00240       typedef streampos         pos_type;
    00241       typedef streamoff         off_type;
    00242       typedef mbstate_t         state_type;
    00243
    00244       static void
    00245       assign(char_type& __c1, const char_type& __c2)
    00246       { __c1 = __c2; }
    00247
    00248       static bool
    00249       eq(const char_type& __c1, const char_type& __c2)
    00250       { return __c1 == __c2; }
    00251
    00252       static bool
    00253       lt(const char_type& __c1, const char_type& __c2)
    00254       { return __c1 < __c2; }
    00255
    00256       static int
    00257       compare(const char_type* __s1, const char_type* __s2, size_t __n)
    00258       { return __builtin_memcmp(__s1, __s2, __n); }
    00259
    00260       static size_t
    00261       length(const char_type* __s)
    00262       { return __builtin_strlen(__s); }
    00263
    00264       static const char_type*
    00265       find(const char_type* __s, size_t __n, const char_type& __a)
    00266       { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
    00267
    00268       static char_type*
    00269       move(char_type* __s1, const char_type* __s2, size_t __n)
    00270       { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
    00271
    00272       static char_type*
    00273       copy(char_type* __s1, const char_type* __s2, size_t __n)
    00274       { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
    00275
    00276       static char_type*
    00277       assign(char_type* __s, size_t __n, char_type __a)
    00278       { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
    00279
    00280       static char_type
    00281       to_char_type(const int_type& __c)
    00282       { return static_cast<char_type>(__c); }
    00283
    00284       // To keep both the byte 0xff and the eof symbol 0xffffffff
    00285       // from ending up as 0xffffffff.
    00286       static int_type
    00287       to_int_type(const char_type& __c)
    00288       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
    00289
    00290       static bool
    00291       eq_int_type(const int_type& __c1, const int_type& __c2)
    00292       { return __c1 == __c2; }
    00293
    00294       static int_type
    00295       eof() { return static_cast<int_type>(EOF); }
    00296
    00297       static int_type
    00298       not_eof(const int_type& __c)
    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)
    00316       { __c1 = __c2; }
    00317
    00318       static bool
    00319       eq(const char_type& __c1, const char_type& __c2)
    00320       { return __c1 == __c2; }
    00321
    00322       static bool
    00323       lt(const char_type& __c1, const char_type& __c2)
    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 char_type
    00351       to_char_type(const int_type& __c) { return char_type(__c); }
    00352
    00353       static int_type
    00354       to_int_type(const char_type& __c) { return int_type(__c); }
    00355
    00356       static bool
    00357       eq_int_type(const int_type& __c1, const int_type& __c2)
    00358       { return __c1 == __c2; }
    00359
    00360       static int_type
    00361       eof() { return static_cast<int_type>(WEOF); }
    00362
    00363       static int_type
    00364       not_eof(const int_type& __c)
    00365       { return eq_int_type(__c, eof()) ? 0 : __c; }
    00366   };
    00367 #endif //_GLIBCXX_USE_WCHAR_T
    00368
    00369 _GLIBCXX_END_NAMESPACE
    00370
    00371 #endif