1// Character Traits for use by standard string and iostream -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31//
32// ISO C++ 14882: 21  Strings library
33//
34
35/** @file char_traits.h
36 *  This is an internal header file, included by other library headers.
37 *  You should not attempt to use it directly.
38 */
39
40#ifndef _CPP_BITS_CHAR_TRAITS_H
41#define _CPP_BITS_CHAR_TRAITS_H 1
42
43#pragma GCC system_header
44
45#include <cstring>            // For memmove, memset, memchr
46#include <bits/fpos.h>        // For streampos
47
48namespace __gnu_cxx
49{
50  template<typename _CharT>
51    struct _Char_types
52    {
53      typedef unsigned long   int_type;
54      typedef std::streampos  pos_type;
55      typedef std::streamoff  off_type;
56      typedef std::mbstate_t  state_type;
57    };
58
59  template<typename _CharT>
60    struct char_traits
61    {
62      typedef _CharT                                    char_type;
63      typedef typename _Char_types<_CharT>::int_type    int_type;
64      typedef typename _Char_types<_CharT>::pos_type    pos_type;
65      typedef typename _Char_types<_CharT>::off_type    off_type;
66      typedef typename _Char_types<_CharT>::state_type  state_type;
67
68      static void
69      assign(char_type& __c1, const char_type& __c2)
70      { __c1 = __c2; }
71
72      static bool
73      eq(const char_type& __c1, const char_type& __c2)
74      { return __c1 == __c2; }
75
76      static bool
77      lt(const char_type& __c1, const char_type& __c2)
78      { return __c1 < __c2; }
79
80      static int
81      compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
82
83      static std::size_t
84      length(const char_type* __s);
85
86      static const char_type*
87      find(const char_type* __s, std::size_t __n, const char_type& __a);
88
89      static char_type*
90      move(char_type* __s1, const char_type* __s2, std::size_t __n);
91
92      static char_type*
93      copy(char_type* __s1, const char_type* __s2, std::size_t __n);
94
95      static char_type*
96      assign(char_type* __s, std::size_t __n, char_type __a);
97
98      static char_type
99      to_char_type(const int_type& __c)
100      { return static_cast<char_type>(__c); }
101
102      static int_type
103      to_int_type(const char_type& __c)
104      { return static_cast<int_type>(__c); }
105
106      static bool
107      eq_int_type(const int_type& __c1, const int_type& __c2)
108      { return __c1 == __c2; }
109
110      static int_type
111      eof()
112      { return static_cast<int_type>(EOF); }
113
114      static int_type
115      not_eof(const int_type& __c)
116      { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
117    };
118
119  template<typename _CharT>
120    int
121    char_traits<_CharT>::
122    compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
123    {
124      for (std::size_t __i = 0; __i < __n; ++__i)
125	if (lt(__s1[__i], __s2[__i]))
126	  return -1;
127	else if (lt(__s2[__i], __s1[__i]))
128	  return 1;
129      return 0;
130    }
131
132  template<typename _CharT>
133    std::size_t
134    char_traits<_CharT>::
135    length(const char_type* __p)
136    {
137      std::size_t __i = 0;
138      while (!eq(__p[__i], char_type()))
139        ++__i;
140      return __i;
141    }
142
143  template<typename _CharT>
144    const typename char_traits<_CharT>::char_type*
145    char_traits<_CharT>::
146    find(const char_type* __s, std::size_t __n, const char_type& __a)
147    {
148      for (std::size_t __i = 0; __i < __n; ++__i)
149        if (eq(__s[__i], __a))
150          return __s + __i;
151      return 0;
152    }
153
154  template<typename _CharT>
155    typename char_traits<_CharT>::char_type*
156    char_traits<_CharT>::
157    move(char_type* __s1, const char_type* __s2, std::size_t __n)
158    {
159      return static_cast<_CharT*>(memmove(__s1, __s2,
160						    __n * sizeof(char_type)));
161    }
162
163  template<typename _CharT>
164    typename char_traits<_CharT>::char_type*
165    char_traits<_CharT>::
166    copy(char_type* __s1, const char_type* __s2, std::size_t __n)
167    {
168      // NB: Inline std::copy so no recursive dependencies.
169      std::copy(__s2, __s2 + __n, __s1);
170      return __s1;
171    }
172
173  template<typename _CharT>
174    typename char_traits<_CharT>::char_type*
175    char_traits<_CharT>::
176    assign(char_type* __s, std::size_t __n, char_type __a)
177    {
178      // NB: Inline std::fill_n so no recursive dependencies.
179      std::fill_n(__s, __n, __a);
180      return __s;
181    }
182}
183
184namespace std
185{
186  // 21.1
187  /**
188   *  @brief  Basis for explicit traits specializations.
189   *
190   *  @note  For any given actual character type, this definition is
191   *  probably wrong.
192   *
193   *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
194   *  for advice on how to make use of this class for "unusual" character
195   *  types.
196  */
197  template<class _CharT>
198    struct char_traits: public __gnu_cxx::char_traits<_CharT>
199    {};
200
201  /// 21.1.3.1  char_traits specializations
202  template<>
203    struct char_traits<char>
204    {
205      typedef char 		char_type;
206      typedef int 	        int_type;
207      typedef streampos 	pos_type;
208      typedef streamoff 	off_type;
209      typedef mbstate_t 	state_type;
210
211      static void
212      assign(char_type& __c1, const char_type& __c2)
213      { __c1 = __c2; }
214
215      static bool
216      eq(const char_type& __c1, const char_type& __c2)
217      { return __c1 == __c2; }
218
219      static bool
220      lt(const char_type& __c1, const char_type& __c2)
221      { return __c1 < __c2; }
222
223      static int
224      compare(const char_type* __s1, const char_type* __s2, size_t __n)
225      { return memcmp(__s1, __s2, __n); }
226
227      static size_t
228      length(const char_type* __s)
229      { return strlen(__s); }
230
231      static const char_type*
232      find(const char_type* __s, size_t __n, const char_type& __a)
233      { return static_cast<const char_type*>(memchr(__s, __a, __n)); }
234
235      static char_type*
236      move(char_type* __s1, const char_type* __s2, size_t __n)
237      { return static_cast<char_type*>(memmove(__s1, __s2, __n)); }
238
239      static char_type*
240      copy(char_type* __s1, const char_type* __s2, size_t __n)
241      {  return static_cast<char_type*>(memcpy(__s1, __s2, __n)); }
242
243      static char_type*
244      assign(char_type* __s, size_t __n, char_type __a)
245      { return static_cast<char_type*>(memset(__s, __a, __n)); }
246
247      static char_type
248      to_char_type(const int_type& __c)
249      { return static_cast<char_type>(__c); }
250
251      // To keep both the byte 0xff and the eof symbol 0xffffffff
252      // from ending up as 0xffffffff.
253      static int_type
254      to_int_type(const char_type& __c)
255      { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
256
257      static bool
258      eq_int_type(const int_type& __c1, const int_type& __c2)
259      { return __c1 == __c2; }
260
261      static int_type
262      eof() { return static_cast<int_type>(EOF); }
263
264      static int_type
265      not_eof(const int_type& __c)
266      { return (__c == eof()) ? 0 : __c; }
267  };
268
269
270#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
271  /// 21.1.3.2  char_traits specializations
272  template<>
273    struct char_traits<wchar_t>
274    {
275      typedef wchar_t 		char_type;
276      typedef wint_t 		int_type;
277      typedef streamoff 	off_type;
278      typedef wstreampos 	pos_type;
279      typedef mbstate_t 	state_type;
280
281      static void
282      assign(char_type& __c1, const char_type& __c2)
283      { __c1 = __c2; }
284
285      static bool
286      eq(const char_type& __c1, const char_type& __c2)
287      { return __c1 == __c2; }
288
289      static bool
290      lt(const char_type& __c1, const char_type& __c2)
291      { return __c1 < __c2; }
292
293      static int
294      compare(const char_type* __s1, const char_type* __s2, size_t __n)
295      { return wmemcmp(__s1, __s2, __n); }
296
297      static size_t
298      length(const char_type* __s)
299      { return wcslen(__s); }
300
301      static const char_type*
302      find(const char_type* __s, size_t __n, const char_type& __a)
303      { return wmemchr(__s, __a, __n); }
304
305      static char_type*
306      move(char_type* __s1, const char_type* __s2, int_type __n)
307      { return wmemmove(__s1, __s2, __n); }
308
309      static char_type*
310      copy(char_type* __s1, const char_type* __s2, size_t __n)
311      { return wmemcpy(__s1, __s2, __n); }
312
313      static char_type*
314      assign(char_type* __s, size_t __n, char_type __a)
315      { return wmemset(__s, __a, __n); }
316
317      static char_type
318      to_char_type(const int_type& __c) { return char_type(__c); }
319
320      static int_type
321      to_int_type(const char_type& __c) { return int_type(__c); }
322
323      static bool
324      eq_int_type(const int_type& __c1, const int_type& __c2)
325      { return __c1 == __c2; }
326
327      static int_type
328      eof() { return static_cast<int_type>(WEOF); }
329
330      static int_type
331      not_eof(const int_type& __c)
332      { return eq_int_type(__c, eof()) ? 0 : __c; }
333  };
334#endif //_GLIBCPP_USE_WCHAR_T
335
336  template<typename _CharT, typename _Traits>
337    struct _Char_traits_match
338    {
339      _CharT _M_c;
340      _Char_traits_match(_CharT const& __c) : _M_c(__c) { }
341
342      bool
343      operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); }
344    };
345} // namespace std
346
347#endif
348