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