1/*
2 * Copyright (c) 1999
3 * Silicon Graphics Computer Systems, Inc.
4 *
5 * Copyright (c) 1999
6 * Boris Fomitchev
7 *
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
10 *
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
16 *
17 */
18
19#include "stlport_prefix.h"
20
21#include <algorithm>
22#include <locale>
23#include <functional>
24
25#include "c_locale.h"
26
27_STLP_BEGIN_NAMESPACE
28
29//----------------------------------------------------------------------
30// ctype<char>
31
32// The classic table: static data members.
33
34#if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
35//*TY 02/25/2000 - added workaround for MPW compilers; they confuse on in-class static const
36const size_t ctype<char>::table_size;
37#endif
38
39// This macro is specifically for platforms where isprint() relies
40// on separate flag
41
42const ctype_base::mask*
43ctype<char>::classic_table() _STLP_NOTHROW {
44  /* Ctype table for the ASCII character set. */
45  static const ctype_base::mask _S_classic_table[table_size] = {
46    cntrl /* null */,
47    cntrl /* ^A */,
48    cntrl /* ^B */,
49    cntrl /* ^C */,
50    cntrl /* ^D */,
51    cntrl /* ^E */,
52    cntrl /* ^F */,
53    cntrl /* ^G */,
54    cntrl /* ^H */,
55    ctype_base::mask(space | cntrl) /* tab */,
56    ctype_base::mask(space | cntrl) /* LF */,
57    ctype_base::mask(space | cntrl) /* ^K */,
58    ctype_base::mask(space | cntrl) /* FF */,
59    ctype_base::mask(space | cntrl) /* ^M */,
60    cntrl /* ^N */,
61    cntrl /* ^O */,
62    cntrl /* ^P */,
63    cntrl /* ^Q */,
64    cntrl /* ^R */,
65    cntrl /* ^S */,
66    cntrl /* ^T */,
67    cntrl /* ^U */,
68    cntrl /* ^V */,
69    cntrl /* ^W */,
70    cntrl /* ^X */,
71    cntrl /* ^Y */,
72    cntrl /* ^Z */,
73    cntrl /* esc */,
74    cntrl /* ^\ */,
75    cntrl /* ^] */,
76    cntrl /* ^^ */,
77    cntrl /* ^_ */,
78    ctype_base::mask(space | print) /*  */,
79    ctype_base::mask(punct | print) /* ! */,
80    ctype_base::mask(punct | print) /* " */,
81    ctype_base::mask(punct | print) /* # */,
82    ctype_base::mask(punct | print) /* $ */,
83    ctype_base::mask(punct | print) /* % */,
84    ctype_base::mask(punct | print) /* & */,
85    ctype_base::mask(punct | print) /* ' */,
86    ctype_base::mask(punct | print) /* ( */,
87    ctype_base::mask(punct | print) /* ) */,
88    ctype_base::mask(punct | print) /* * */,
89    ctype_base::mask(punct | print) /* + */,
90    ctype_base::mask(punct | print) /* , */,
91    ctype_base::mask(punct | print) /* - */,
92    ctype_base::mask(punct | print) /* . */,
93    ctype_base::mask(punct | print) /* / */,
94    ctype_base::mask(digit | print | xdigit) /* 0 */,
95    ctype_base::mask(digit | print | xdigit) /* 1 */,
96    ctype_base::mask(digit | print | xdigit) /* 2 */,
97    ctype_base::mask(digit | print | xdigit) /* 3 */,
98    ctype_base::mask(digit | print | xdigit) /* 4 */,
99    ctype_base::mask(digit | print | xdigit) /* 5 */,
100    ctype_base::mask(digit | print | xdigit) /* 6 */,
101    ctype_base::mask(digit | print | xdigit) /* 7 */,
102    ctype_base::mask(digit | print | xdigit) /* 8 */,
103    ctype_base::mask(digit | print | xdigit) /* 9 */,
104    ctype_base::mask(punct | print) /* : */,
105    ctype_base::mask(punct | print) /* ; */,
106    ctype_base::mask(punct | print) /* < */,
107    ctype_base::mask(punct | print) /* = */,
108    ctype_base::mask(punct | print) /* > */,
109    ctype_base::mask(punct | print) /* ? */,
110    ctype_base::mask(punct | print) /* ! */,
111    ctype_base::mask(alpha | print | upper | xdigit) /* A */,
112    ctype_base::mask(alpha | print | upper | xdigit) /* B */,
113    ctype_base::mask(alpha | print | upper | xdigit) /* C */,
114    ctype_base::mask(alpha | print | upper | xdigit) /* D */,
115    ctype_base::mask(alpha | print | upper | xdigit) /* E */,
116    ctype_base::mask(alpha | print | upper | xdigit) /* F */,
117    ctype_base::mask(alpha | print | upper) /* G */,
118    ctype_base::mask(alpha | print | upper) /* H */,
119    ctype_base::mask(alpha | print | upper) /* I */,
120    ctype_base::mask(alpha | print | upper) /* J */,
121    ctype_base::mask(alpha | print | upper) /* K */,
122    ctype_base::mask(alpha | print | upper) /* L */,
123    ctype_base::mask(alpha | print | upper) /* M */,
124    ctype_base::mask(alpha | print | upper) /* N */,
125    ctype_base::mask(alpha | print | upper) /* O */,
126    ctype_base::mask(alpha | print | upper) /* P */,
127    ctype_base::mask(alpha | print | upper) /* Q */,
128    ctype_base::mask(alpha | print | upper) /* R */,
129    ctype_base::mask(alpha | print | upper) /* S */,
130    ctype_base::mask(alpha | print | upper) /* T */,
131    ctype_base::mask(alpha | print | upper) /* U */,
132    ctype_base::mask(alpha | print | upper) /* V */,
133    ctype_base::mask(alpha | print | upper) /* W */,
134    ctype_base::mask(alpha | print | upper) /* X */,
135    ctype_base::mask(alpha | print | upper) /* Y */,
136    ctype_base::mask(alpha | print | upper) /* Z */,
137    ctype_base::mask(punct | print) /* [ */,
138    ctype_base::mask(punct | print) /* \ */,
139    ctype_base::mask(punct | print) /* ] */,
140    ctype_base::mask(punct | print) /* ^ */,
141    ctype_base::mask(punct | print) /* _ */,
142    ctype_base::mask(punct | print) /* ` */,
143    ctype_base::mask(alpha | print | lower | xdigit) /* a */,
144    ctype_base::mask(alpha | print | lower | xdigit) /* b */,
145    ctype_base::mask(alpha | print | lower | xdigit) /* c */,
146    ctype_base::mask(alpha | print | lower | xdigit) /* d */,
147    ctype_base::mask(alpha | print | lower | xdigit) /* e */,
148    ctype_base::mask(alpha | print | lower | xdigit) /* f */,
149    ctype_base::mask(alpha | print | lower) /* g */,
150    ctype_base::mask(alpha | print | lower) /* h */,
151    ctype_base::mask(alpha | print | lower) /* i */,
152    ctype_base::mask(alpha | print | lower) /* j */,
153    ctype_base::mask(alpha | print | lower) /* k */,
154    ctype_base::mask(alpha | print | lower) /* l */,
155    ctype_base::mask(alpha | print | lower) /* m */,
156    ctype_base::mask(alpha | print | lower) /* n */,
157    ctype_base::mask(alpha | print | lower) /* o */,
158    ctype_base::mask(alpha | print | lower) /* p */,
159    ctype_base::mask(alpha | print | lower) /* q */,
160    ctype_base::mask(alpha | print | lower) /* r */,
161    ctype_base::mask(alpha | print | lower) /* s */,
162    ctype_base::mask(alpha | print | lower) /* t */,
163    ctype_base::mask(alpha | print | lower) /* u */,
164    ctype_base::mask(alpha | print | lower) /* v */,
165    ctype_base::mask(alpha | print | lower) /* w */,
166    ctype_base::mask(alpha | print | lower) /* x */,
167    ctype_base::mask(alpha | print | lower) /* y */,
168    ctype_base::mask(alpha | print | lower) /* z */,
169    ctype_base::mask(punct | print) /* { */,
170    ctype_base::mask(punct | print) /* | */,
171    ctype_base::mask(punct | print) /* } */,
172    ctype_base::mask(punct | print) /* ~ */,
173    cntrl /* del (0x7f)*/,
174    /* ASCII is a 7-bit code, so everything else is non-ASCII */
175    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
176    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
177    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
178    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
179    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
180    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
181    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
182    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
183    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
184    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
185    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
186    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
187    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
188    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
189    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
190    ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0)
191  };
192  return _S_classic_table;
193}
194
195// For every c in the range 0 <= c < 256, _S_upper[c] is the
196// uppercased version of c and _S_lower[c] is the lowercased
197// version.  As before, these two tables assume the ASCII character
198// set.
199
200const unsigned char _S_upper[ctype<char>::table_size] =
201{
202  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
203  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
204  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
205  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
206  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
207  0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
208  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
209  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
210  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
211  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
212  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
213  0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
214  0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
215  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
216  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
217  0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
218  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
219  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
220  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
221  0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
222  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
223  0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
224  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
225  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
226  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
227  0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
228  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
229  0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
230  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
231  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
232  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
233  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
234};
235
236const unsigned char _S_lower[ctype<char>::table_size] =
237{
238  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
239  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
240  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
241  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
242  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
243  0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
244  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
245  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
246  0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
247  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
248  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
249  0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
250  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
251  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
252  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
253  0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
254  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
255  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
256  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
257  0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
258  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
259  0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
260  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
261  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
262  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
263  0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
264  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
265  0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
266  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
267  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
268  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
269  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
270};
271
272//An helper struct to check wchar_t index without generating warnings
273//under some compilers (gcc) because of a limited range of value
274//(when wchar_t is unsigned)
275template <bool _IsSigned>
276struct _WCharIndexT;
277
278#if !(defined (__BORLANDC__) && !defined(__linux__)) && \
279    !(defined (__GNUC__) && (defined (__MINGW32__) || defined (__CYGWIN__))) && \
280    !defined (__ICL)
281_STLP_TEMPLATE_NULL
282struct _WCharIndexT<true> {
283  static bool in_range(wchar_t c, size_t upperBound) {
284    return c >= 0 && size_t(c) < upperBound;
285  }
286};
287#endif
288
289_STLP_TEMPLATE_NULL
290struct _WCharIndexT<false> {
291  static bool in_range(wchar_t c, size_t upperBound) {
292    return size_t(c) < upperBound;
293  }
294};
295
296typedef _WCharIndexT<wchar_t(-1) < 0> _WCharIndex;
297
298// Some helper functions used in ctype<>::scan_is and scan_is_not.
299
300struct _Ctype_is_mask : public unary_function<char, bool> {
301  ctype_base::mask _Mask;
302  const ctype_base::mask* _M_table;
303
304  _Ctype_is_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
305  bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) != 0; }
306};
307
308struct _Ctype_not_mask : public unary_function<char, bool> {
309  ctype_base::mask _Mask;
310  const ctype_base::mask* _M_table;
311
312  _Ctype_not_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
313  bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) == 0; }
314};
315
316ctype<char>::ctype(const ctype_base::mask * __tab, bool __del, size_t __refs) :
317  locale::facet(__refs),
318  _M_ctype_table(__tab ? __tab : classic_table()),
319  _M_delete(__tab && __del)
320{}
321
322ctype<char>::~ctype() {
323  if (_M_delete)
324    delete[] __CONST_CAST(ctype_base::mask *, _M_ctype_table);
325}
326
327const char*
328#if defined (__DMC__)
329_STLP_DECLSPEC
330#endif
331ctype<char>::scan_is(ctype_base::mask  __m, const char* __low, const char* __high) const
332{ return _STLP_STD::find_if(__low, __high, _Ctype_is_mask(__m, _M_ctype_table)); }
333
334const char*
335#if defined (__DMC__)
336_STLP_DECLSPEC
337#endif
338ctype<char>::scan_not(ctype_base::mask  __m, const char* __low, const char* __high) const
339{ return _STLP_STD::find_if(__low, __high, _Ctype_not_mask(__m, _M_ctype_table)); }
340
341char ctype<char>::do_toupper(char __c) const
342{ return (char) _S_upper[(unsigned char) __c]; }
343char ctype<char>::do_tolower(char __c) const
344{ return (char) _S_lower[(unsigned char) __c]; }
345
346const char* ctype<char>::do_toupper(char* __low, const char* __high) const {
347  for ( ; __low < __high; ++__low)
348    *__low = (char) _S_upper[(unsigned char) *__low];
349  return __high;
350}
351const char* ctype<char>::do_tolower(char* __low, const char* __high) const {
352  for ( ; __low < __high; ++__low)
353    *__low = (char) _S_lower[(unsigned char) *__low];
354  return __high;
355}
356
357char
358ctype<char>::do_widen(char __c) const { return __c; }
359
360const char*
361ctype<char>::do_widen(const char* __low, const char* __high,
362                      char* __to) const {
363  _STLP_PRIV __copy_trivial(__low, __high, __to);
364  return __high;
365}
366char
367ctype<char>::do_narrow(char __c, char /* dfault */ ) const { return __c; }
368const char*
369ctype<char>::do_narrow(const char* __low, const char* __high,
370                       char /* dfault */, char* __to) const {
371  _STLP_PRIV __copy_trivial(__low, __high, __to);
372  return __high;
373}
374
375
376#if !defined (_STLP_NO_WCHAR_T)
377
378struct _Ctype_w_is_mask : public unary_function<wchar_t, bool> {
379  ctype_base::mask M;
380  const ctype_base::mask* table;
381
382  _Ctype_w_is_mask(ctype_base::mask m, const ctype_base::mask* t)
383    : M(m), table(t) {}
384  bool operator()(wchar_t c) const
385  { return _WCharIndex::in_range(c, ctype<char>::table_size) && (table[c] & M); }
386};
387
388//----------------------------------------------------------------------
389// ctype<wchar_t>
390
391ctype<wchar_t>::~ctype() {}
392
393
394bool ctype<wchar_t>::do_is(ctype_base::mask  m, wchar_t c) const {
395  const ctype_base::mask * table = ctype<char>::classic_table();
396  return _WCharIndex::in_range(c, ctype<char>::table_size) && (m & table[c]);
397}
398
399const wchar_t* ctype<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
400                                     ctype_base::mask * vec) const {
401  // boris : not clear if this is the right thing to do...
402  const ctype_base::mask * table = ctype<char>::classic_table();
403  wchar_t c;
404  for ( ; low < high; ++low, ++vec) {
405    c = *low;
406    *vec = _WCharIndex::in_range(c, ctype<char>::table_size) ? table[c] : ctype_base::mask(0);
407  }
408  return high;
409}
410
411const wchar_t*
412ctype<wchar_t>::do_scan_is(ctype_base::mask  m,
413                           const wchar_t* low, const wchar_t* high) const {
414  return find_if(low, high, _Ctype_w_is_mask(m, ctype<char>::classic_table()));
415}
416
417
418const wchar_t*
419ctype<wchar_t>::do_scan_not(ctype_base::mask  m,
420                            const wchar_t* low, const wchar_t* high) const {
421  return find_if(low, high, not1(_Ctype_w_is_mask(m, ctype<char>::classic_table())));
422}
423
424wchar_t ctype<wchar_t>::do_toupper(wchar_t c) const {
425  return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
426                                                           : c;
427}
428
429const wchar_t*
430ctype<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
431  for ( ; low < high; ++low) {
432    wchar_t c = *low;
433    *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
434                                                             : c;
435  }
436  return high;
437}
438
439wchar_t ctype<wchar_t>::do_tolower(wchar_t c) const {
440  return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
441                                                           : c;
442}
443
444const wchar_t*
445ctype<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
446  for ( ; low < high; ++low) {
447    wchar_t c = *low;
448    *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
449                                                             : c;
450  }
451  return high;
452}
453
454wchar_t ctype<wchar_t>::do_widen(char c) const {
455  return (wchar_t)(unsigned char)c;
456}
457
458const char*
459ctype<wchar_t>::do_widen(const char* low, const char* high,
460                         wchar_t* dest) const {
461  while (low != high)
462    *dest++ = (wchar_t)(unsigned char)*low++;
463  return high;
464}
465
466char ctype<wchar_t>::do_narrow(wchar_t c, char dfault) const
467{ return (unsigned char)c == c ? (char)c : dfault; }
468
469const wchar_t* ctype<wchar_t>::do_narrow(const wchar_t* low,
470                                         const wchar_t* high,
471                                         char dfault, char* dest) const {
472  while (low != high) {
473    wchar_t c = *low++;
474    *dest++ = (unsigned char)c == c ? (char)c : dfault;
475  }
476
477  return high;
478}
479
480# endif
481_STLP_END_NAMESPACE
482
483// Local Variables:
484// mode:C++
485// End:
486
487