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
36 const size_t ctype<char>::table_size;
37 #endif
38 
39 // This macro is specifically for platforms where isprint() relies
40 // on separate flag
41 
42 const ctype_base::mask*
classic_table()43 ctype<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 
200 const 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 
236 const 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)
275 template <bool _IsSigned>
276 struct _WCharIndexT;
277 
278 #if !(defined (__BORLANDC__) && !defined(__linux__)) && \
279     !(defined (__GNUC__) && (defined (__MINGW32__) || defined (__CYGWIN__))) && \
280     !defined (__ICL)
281 _STLP_TEMPLATE_NULL
282 struct _WCharIndexT<true> {
in_range_WCharIndexT283   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
290 struct _WCharIndexT<false> {
in_range_WCharIndexT291   static bool in_range(wchar_t c, size_t upperBound) {
292     return size_t(c) < upperBound;
293   }
294 };
295 
296 typedef _WCharIndexT<wchar_t(-1) < 0> _WCharIndex;
297 
298 // Some helper functions used in ctype<>::scan_is and scan_is_not.
299 
300 struct _Ctype_is_mask : public unary_function<char, bool> {
301   ctype_base::mask _Mask;
302   const ctype_base::mask* _M_table;
303 
_Ctype_is_mask_Ctype_is_mask304   _Ctype_is_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
operator ()_Ctype_is_mask305   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) != 0; }
306 };
307 
308 struct _Ctype_not_mask : public unary_function<char, bool> {
309   ctype_base::mask _Mask;
310   const ctype_base::mask* _M_table;
311 
_Ctype_not_mask_Ctype_not_mask312   _Ctype_not_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
operator ()_Ctype_not_mask313   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) == 0; }
314 };
315 
ctype(const ctype_base::mask * __tab,bool __del,size_t __refs)316 ctype<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 
~ctype()322 ctype<char>::~ctype() {
323   if (_M_delete)
324     delete[] __CONST_CAST(ctype_base::mask *, _M_ctype_table);
325 }
326 
327 const char*
328 #if defined (__DMC__)
329 _STLP_DECLSPEC
330 #endif
scan_is(ctype_base::mask __m,const char * __low,const char * __high) const331 ctype<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 
334 const char*
335 #if defined (__DMC__)
336 _STLP_DECLSPEC
337 #endif
scan_not(ctype_base::mask __m,const char * __low,const char * __high) const338 ctype<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 
do_toupper(char __c) const341 char ctype<char>::do_toupper(char __c) const
342 { return (char) _S_upper[(unsigned char) __c]; }
do_tolower(char __c) const343 char ctype<char>::do_tolower(char __c) const
344 { return (char) _S_lower[(unsigned char) __c]; }
345 
do_toupper(char * __low,const char * __high) const346 const 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 }
do_tolower(char * __low,const char * __high) const351 const 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 
357 char
do_widen(char __c) const358 ctype<char>::do_widen(char __c) const { return __c; }
359 
360 const char*
do_widen(const char * __low,const char * __high,char * __to) const361 ctype<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 }
366 char
do_narrow(char __c,char) const367 ctype<char>::do_narrow(char __c, char /* dfault */ ) const { return __c; }
368 const char*
do_narrow(const char * __low,const char * __high,char,char * __to) const369 ctype<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 
378 struct _Ctype_w_is_mask : public unary_function<wchar_t, bool> {
379   ctype_base::mask M;
380   const ctype_base::mask* table;
381 
_Ctype_w_is_mask_Ctype_w_is_mask382   _Ctype_w_is_mask(ctype_base::mask m, const ctype_base::mask* t)
383     : M(m), table(t) {}
operator ()_Ctype_w_is_mask384   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 
~ctype()391 ctype<wchar_t>::~ctype() {}
392 
393 
do_is(ctype_base::mask m,wchar_t c) const394 bool 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 
do_is(const wchar_t * low,const wchar_t * high,ctype_base::mask * vec) const399 const 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 
411 const wchar_t*
do_scan_is(ctype_base::mask m,const wchar_t * low,const wchar_t * high) const412 ctype<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 
418 const wchar_t*
do_scan_not(ctype_base::mask m,const wchar_t * low,const wchar_t * high) const419 ctype<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 
do_toupper(wchar_t c) const424 wchar_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 
429 const wchar_t*
do_toupper(wchar_t * low,const wchar_t * high) const430 ctype<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 
do_tolower(wchar_t c) const439 wchar_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 
444 const wchar_t*
do_tolower(wchar_t * low,const wchar_t * high) const445 ctype<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 
do_widen(char c) const454 wchar_t ctype<wchar_t>::do_widen(char c) const {
455   return (wchar_t)(unsigned char)c;
456 }
457 
458 const char*
do_widen(const char * low,const char * high,wchar_t * dest) const459 ctype<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 
do_narrow(wchar_t c,char dfault) const466 char ctype<wchar_t>::do_narrow(wchar_t c, char dfault) const
467 { return (unsigned char)c == c ? (char)c : dfault; }
468 
do_narrow(const wchar_t * low,const wchar_t * high,char dfault,char * dest) const469 const 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