197403Sobrien// Character Traits for use by standard string and iostream -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4102782Skan// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/** @file char_traits.h
3297403Sobrien *  This is an internal header file, included by other library headers.
3397403Sobrien *  You should not attempt to use it directly.
3497403Sobrien */
3597403Sobrien
36169691Skan//
37169691Skan// ISO C++ 14882: 21  Strings library
38169691Skan//
39169691Skan
40132720Skan#ifndef _CHAR_TRAITS_H
41132720Skan#define _CHAR_TRAITS_H 1
4297403Sobrien
4397403Sobrien#pragma GCC system_header
4497403Sobrien
45117397Skan#include <cstring>            // For memmove, memset, memchr
46132720Skan#include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n
47132720Skan#include <bits/postypes.h>    // For streampos
4897403Sobrien
49169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
50169691Skan
51117397Skan  /**
52132720Skan   *  @brief  Mapping from character type to associated types.
53117397Skan   *
54132720Skan   *  @note This is an implementation class for the generic version
55132720Skan   *  of char_traits.  It defines int_type, off_type, pos_type, and
56132720Skan   *  state_type.  By default these are unsigned long, streamoff,
57132720Skan   *  streampos, and mbstate_t.  Users who need a different set of
58132720Skan   *  types, but who don't need to change the definitions of any function
59132720Skan   *  defined in char_traits, can specialize __gnu_cxx::_Char_types
60132720Skan   *  while leaving __gnu_cxx::char_traits alone. */
61132720Skan  template <class _CharT>
62132720Skan    struct _Char_types
63132720Skan    {
64132720Skan      typedef unsigned long   int_type;
65132720Skan      typedef std::streampos  pos_type;
66132720Skan      typedef std::streamoff  off_type;
67132720Skan      typedef std::mbstate_t  state_type;
68132720Skan    };
69132720Skan
70132720Skan
71132720Skan  /**
72132720Skan   *  @brief  Base class used to implement std::char_traits.
73132720Skan   *
74132720Skan   *  @note For any given actual character type, this definition is
75132720Skan   *  probably wrong.  (Most of the member functions are likely to be
76132720Skan   *  right, but the int_type and state_type typedefs, and the eof()
77132720Skan   *  member function, are likely to be wrong.)  The reason this class
78132720Skan   *  exists is so users can specialize it.  Classes in namespace std
79132720Skan   *  may not be specialized for fundamentl types, but classes in
80132720Skan   *  namespace __gnu_cxx may be.
81132720Skan   *
82117397Skan   *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
83117397Skan   *  for advice on how to make use of this class for "unusual" character
84169691Skan   *  types. Also, check out include/ext/pod_char_traits.h.
85169691Skan   */
86132720Skan  template<typename _CharT>
8797403Sobrien    struct char_traits
8897403Sobrien    {
89132720Skan      typedef _CharT                                    char_type;
90132720Skan      typedef typename _Char_types<_CharT>::int_type    int_type;
91132720Skan      typedef typename _Char_types<_CharT>::pos_type    pos_type;
92132720Skan      typedef typename _Char_types<_CharT>::off_type    off_type;
93132720Skan      typedef typename _Char_types<_CharT>::state_type  state_type;
9497403Sobrien
95132720Skan      static void
96132720Skan      assign(char_type& __c1, const char_type& __c2)
97132720Skan      { __c1 = __c2; }
9897403Sobrien
99132720Skan      static bool
100132720Skan      eq(const char_type& __c1, const char_type& __c2)
101132720Skan      { return __c1 == __c2; }
10297403Sobrien
103132720Skan      static bool
104132720Skan      lt(const char_type& __c1, const char_type& __c2)
105132720Skan      { return __c1 < __c2; }
10697403Sobrien
107132720Skan      static int
108132720Skan      compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
109132720Skan
110132720Skan      static std::size_t
111102782Skan      length(const char_type* __s);
11297403Sobrien
113132720Skan      static const char_type*
114132720Skan      find(const char_type* __s, std::size_t __n, const char_type& __a);
11597403Sobrien
116132720Skan      static char_type*
117132720Skan      move(char_type* __s1, const char_type* __s2, std::size_t __n);
11897403Sobrien
119132720Skan      static char_type*
120132720Skan      copy(char_type* __s1, const char_type* __s2, std::size_t __n);
12197403Sobrien
122132720Skan      static char_type*
123132720Skan      assign(char_type* __s, std::size_t __n, char_type __a);
12497403Sobrien
125132720Skan      static char_type
126132720Skan      to_char_type(const int_type& __c)
127132720Skan      { return static_cast<char_type>(__c); }
12897403Sobrien
129132720Skan      static int_type
130132720Skan      to_int_type(const char_type& __c)
131132720Skan      { return static_cast<int_type>(__c); }
13297403Sobrien
133132720Skan      static bool
134132720Skan      eq_int_type(const int_type& __c1, const int_type& __c2)
135132720Skan      { return __c1 == __c2; }
13697403Sobrien
137132720Skan      static int_type
138132720Skan      eof()
139132720Skan      { return static_cast<int_type>(EOF); }
14097403Sobrien
141132720Skan      static int_type
142132720Skan      not_eof(const int_type& __c)
143132720Skan      { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
14497403Sobrien    };
14597403Sobrien
146132720Skan  template<typename _CharT>
147132720Skan    int
148132720Skan    char_traits<_CharT>::
149132720Skan    compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
150132720Skan    {
151169691Skan      for (std::size_t __i = 0; __i < __n; ++__i)
152132720Skan	if (lt(__s1[__i], __s2[__i]))
153132720Skan	  return -1;
154132720Skan	else if (lt(__s2[__i], __s1[__i]))
155132720Skan	  return 1;
156132720Skan      return 0;
157132720Skan    }
15897403Sobrien
159132720Skan  template<typename _CharT>
160132720Skan    std::size_t
161132720Skan    char_traits<_CharT>::
162132720Skan    length(const char_type* __p)
163132720Skan    {
164132720Skan      std::size_t __i = 0;
165132720Skan      while (!eq(__p[__i], char_type()))
166132720Skan        ++__i;
167132720Skan      return __i;
168132720Skan    }
169132720Skan
170132720Skan  template<typename _CharT>
171132720Skan    const typename char_traits<_CharT>::char_type*
172132720Skan    char_traits<_CharT>::
173132720Skan    find(const char_type* __s, std::size_t __n, const char_type& __a)
174132720Skan    {
175132720Skan      for (std::size_t __i = 0; __i < __n; ++__i)
176132720Skan        if (eq(__s[__i], __a))
177132720Skan          return __s + __i;
178132720Skan      return 0;
179132720Skan    }
180132720Skan
181132720Skan  template<typename _CharT>
182132720Skan    typename char_traits<_CharT>::char_type*
183132720Skan    char_traits<_CharT>::
184132720Skan    move(char_type* __s1, const char_type* __s2, std::size_t __n)
185132720Skan    {
186132720Skan      return static_cast<_CharT*>(std::memmove(__s1, __s2,
187132720Skan					       __n * sizeof(char_type)));
188132720Skan    }
189132720Skan
190132720Skan  template<typename _CharT>
191132720Skan    typename char_traits<_CharT>::char_type*
192132720Skan    char_traits<_CharT>::
193132720Skan    copy(char_type* __s1, const char_type* __s2, std::size_t __n)
194132720Skan    {
195132720Skan      std::copy(__s2, __s2 + __n, __s1);
196132720Skan      return __s1;
197132720Skan    }
198132720Skan
199132720Skan  template<typename _CharT>
200132720Skan    typename char_traits<_CharT>::char_type*
201132720Skan    char_traits<_CharT>::
202132720Skan    assign(char_type* __s, std::size_t __n, char_type __a)
203132720Skan    {
204132720Skan      std::fill_n(__s, __n, __a);
205132720Skan      return __s;
206132720Skan    }
207132720Skan
208169691Skan_GLIBCXX_END_NAMESPACE
209169691Skan
210169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
211169691Skan
212132720Skan  // 21.1
213132720Skan  /**
214132720Skan   *  @brief  Basis for explicit traits specializations.
215132720Skan   *
216132720Skan   *  @note  For any given actual character type, this definition is
217132720Skan   *  probably wrong.  Since this is just a thin wrapper around
218132720Skan   *  __gnu_cxx::char_traits, it is possible to achieve a more
219132720Skan   *  appropriate definition by specializing __gnu_cxx::char_traits.
220132720Skan   *
221132720Skan   *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
222132720Skan   *  for advice on how to make use of this class for "unusual" character
223132720Skan   *  types. Also, check out include/ext/pod_char_traits.h.
224132720Skan  */
225132720Skan  template<class _CharT>
226169691Skan    struct char_traits : public __gnu_cxx::char_traits<_CharT>
227132720Skan    { };
228132720Skan
229132720Skan
230169691Skan  /// @brief  21.1.3.1  char_traits specializations
23197403Sobrien  template<>
23297403Sobrien    struct char_traits<char>
23397403Sobrien    {
234132720Skan      typedef char              char_type;
235132720Skan      typedef int               int_type;
236132720Skan      typedef streampos         pos_type;
237132720Skan      typedef streamoff         off_type;
238132720Skan      typedef mbstate_t         state_type;
23997403Sobrien
240132720Skan      static void
24197403Sobrien      assign(char_type& __c1, const char_type& __c2)
24297403Sobrien      { __c1 = __c2; }
24397403Sobrien
244132720Skan      static bool
24597403Sobrien      eq(const char_type& __c1, const char_type& __c2)
24697403Sobrien      { return __c1 == __c2; }
24797403Sobrien
248132720Skan      static bool
24997403Sobrien      lt(const char_type& __c1, const char_type& __c2)
25097403Sobrien      { return __c1 < __c2; }
25197403Sobrien
252132720Skan      static int
25397403Sobrien      compare(const char_type* __s1, const char_type* __s2, size_t __n)
25497403Sobrien      { return memcmp(__s1, __s2, __n); }
25597403Sobrien
25697403Sobrien      static size_t
25797403Sobrien      length(const char_type* __s)
25897403Sobrien      { return strlen(__s); }
25997403Sobrien
260132720Skan      static const char_type*
26197403Sobrien      find(const char_type* __s, size_t __n, const char_type& __a)
26297403Sobrien      { return static_cast<const char_type*>(memchr(__s, __a, __n)); }
26397403Sobrien
264132720Skan      static char_type*
26597403Sobrien      move(char_type* __s1, const char_type* __s2, size_t __n)
26697403Sobrien      { return static_cast<char_type*>(memmove(__s1, __s2, __n)); }
26797403Sobrien
268132720Skan      static char_type*
26997403Sobrien      copy(char_type* __s1, const char_type* __s2, size_t __n)
270132720Skan      { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); }
27197403Sobrien
272132720Skan      static char_type*
27397403Sobrien      assign(char_type* __s, size_t __n, char_type __a)
27497403Sobrien      { return static_cast<char_type*>(memset(__s, __a, __n)); }
27597403Sobrien
276132720Skan      static char_type
27797403Sobrien      to_char_type(const int_type& __c)
27897403Sobrien      { return static_cast<char_type>(__c); }
27997403Sobrien
28097403Sobrien      // To keep both the byte 0xff and the eof symbol 0xffffffff
28197403Sobrien      // from ending up as 0xffffffff.
282132720Skan      static int_type
28397403Sobrien      to_int_type(const char_type& __c)
28497403Sobrien      { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
28597403Sobrien
286132720Skan      static bool
28797403Sobrien      eq_int_type(const int_type& __c1, const int_type& __c2)
28897403Sobrien      { return __c1 == __c2; }
28997403Sobrien
290132720Skan      static int_type
29197403Sobrien      eof() { return static_cast<int_type>(EOF); }
29297403Sobrien
293132720Skan      static int_type
29497403Sobrien      not_eof(const int_type& __c)
29597403Sobrien      { return (__c == eof()) ? 0 : __c; }
29697403Sobrien  };
29797403Sobrien
29897403Sobrien
299132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
300169691Skan  /// @brief  21.1.3.2  char_traits specializations
30197403Sobrien  template<>
30297403Sobrien    struct char_traits<wchar_t>
30397403Sobrien    {
304132720Skan      typedef wchar_t           char_type;
305132720Skan      typedef wint_t            int_type;
306132720Skan      typedef streamoff         off_type;
307132720Skan      typedef wstreampos        pos_type;
308132720Skan      typedef mbstate_t         state_type;
309132720Skan
310132720Skan      static void
31197403Sobrien      assign(char_type& __c1, const char_type& __c2)
31297403Sobrien      { __c1 = __c2; }
31397403Sobrien
314132720Skan      static bool
31597403Sobrien      eq(const char_type& __c1, const char_type& __c2)
31697403Sobrien      { return __c1 == __c2; }
31797403Sobrien
318132720Skan      static bool
31997403Sobrien      lt(const char_type& __c1, const char_type& __c2)
32097403Sobrien      { return __c1 < __c2; }
32197403Sobrien
322132720Skan      static int
32397403Sobrien      compare(const char_type* __s1, const char_type* __s2, size_t __n)
32497403Sobrien      { return wmemcmp(__s1, __s2, __n); }
32597403Sobrien
32697403Sobrien      static size_t
32797403Sobrien      length(const char_type* __s)
32897403Sobrien      { return wcslen(__s); }
32997403Sobrien
330132720Skan      static const char_type*
33197403Sobrien      find(const char_type* __s, size_t __n, const char_type& __a)
33297403Sobrien      { return wmemchr(__s, __a, __n); }
33397403Sobrien
334132720Skan      static char_type*
335132720Skan      move(char_type* __s1, const char_type* __s2, size_t __n)
33697403Sobrien      { return wmemmove(__s1, __s2, __n); }
33797403Sobrien
338132720Skan      static char_type*
33997403Sobrien      copy(char_type* __s1, const char_type* __s2, size_t __n)
34097403Sobrien      { return wmemcpy(__s1, __s2, __n); }
34197403Sobrien
342132720Skan      static char_type*
34397403Sobrien      assign(char_type* __s, size_t __n, char_type __a)
34497403Sobrien      { return wmemset(__s, __a, __n); }
34597403Sobrien
346132720Skan      static char_type
34797403Sobrien      to_char_type(const int_type& __c) { return char_type(__c); }
34897403Sobrien
349132720Skan      static int_type
35097403Sobrien      to_int_type(const char_type& __c) { return int_type(__c); }
35197403Sobrien
352132720Skan      static bool
35397403Sobrien      eq_int_type(const int_type& __c1, const int_type& __c2)
35497403Sobrien      { return __c1 == __c2; }
35597403Sobrien
356132720Skan      static int_type
35797403Sobrien      eof() { return static_cast<int_type>(WEOF); }
35897403Sobrien
359132720Skan      static int_type
36097403Sobrien      not_eof(const int_type& __c)
36197403Sobrien      { return eq_int_type(__c, eof()) ? 0 : __c; }
36297403Sobrien  };
363132720Skan#endif //_GLIBCXX_USE_WCHAR_T
36497403Sobrien
365169691Skan_GLIBCXX_END_NAMESPACE
36697403Sobrien
36797403Sobrien#endif
368