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(__MRC__) || defined(__SC__))
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 #define PRINTFLAG ctype_base::mask( _Locale_PRINT & ~(_Locale_UPPER | _Locale_LOWER | _Locale_ALPHA | _Locale_DIGIT | _Locale_PUNCT | _Locale_SPACE | _Locale_XDIGIT ))
43 
44 const ctype_base::mask*
classic_table()45 ctype<char>::classic_table() _STLP_NOTHROW {
46   /* Ctype table for the ASCII character set.
47    * There are 257 entries in this table.  The first is EOF (-1).
48    * That is, the "table" seen by ctype<char> member functions is
49    * _S_classic_table + 1.
50    */
51   /* The following static assert check that alpha is not defined as upper | lower.
52    * STLport flags character like 'a' with alpha | lower, if alpha is badly configure
53    * then 'a' will also be seen as upper which is wrong.
54    */
55 #if !defined (__MWERKS__)
56   /* CodeWarrior 8 don't understabd this */
57   _STLP_STATIC_ASSERT((alpha & (lower | upper)) == 0)
58 #endif
59 
60   static const ctype_base::mask _S_classic_table[table_size] =
61   {
62     cntrl /* null */,
63     cntrl /* ^A */,
64     cntrl /* ^B */,
65     cntrl /* ^C */,
66     cntrl /* ^D */,
67     cntrl /* ^E */,
68     cntrl /* ^F */,
69     cntrl /* ^G */,
70     cntrl /* ^H */,
71     ctype_base::mask(space | cntrl) /* tab */,
72     ctype_base::mask(space | cntrl) /* LF */,
73     ctype_base::mask(space | cntrl) /* ^K */,
74     ctype_base::mask(space | cntrl) /* FF */,
75     ctype_base::mask(space | cntrl) /* ^M */,
76     cntrl /* ^N */,
77     cntrl /* ^O */,
78     cntrl /* ^P */,
79     cntrl /* ^Q */,
80     cntrl /* ^R */,
81     cntrl /* ^S */,
82     cntrl /* ^T */,
83     cntrl /* ^U */,
84     cntrl /* ^V */,
85     cntrl /* ^W */,
86     cntrl /* ^X */,
87     cntrl /* ^Y */,
88     cntrl /* ^Z */,
89     cntrl /* esc */,
90     cntrl /* ^\ */,
91     cntrl /* ^] */,
92     cntrl /* ^^ */,
93     cntrl /* ^_ */,
94     ctype_base::mask (space | PRINTFLAG) /*  */,
95     ctype_base::mask (punct | PRINTFLAG ) /* ! */,
96     ctype_base::mask (punct | PRINTFLAG ) /* " */,
97     ctype_base::mask (punct | PRINTFLAG ) /* # */,
98     ctype_base::mask (punct | PRINTFLAG ) /* $ */,
99     ctype_base::mask (punct | PRINTFLAG ) /* % */,
100     ctype_base::mask (punct | PRINTFLAG ) /* & */,
101     ctype_base::mask (punct | PRINTFLAG ) /* ' */,
102     ctype_base::mask (punct | PRINTFLAG ) /* ( */,
103     ctype_base::mask (punct | PRINTFLAG ) /* ) */,
104     ctype_base::mask (punct | PRINTFLAG ) /* * */,
105     ctype_base::mask (punct | PRINTFLAG ) /* + */,
106     ctype_base::mask (punct | PRINTFLAG ) /* , */,
107     ctype_base::mask (punct | PRINTFLAG ) /* - */,
108     ctype_base::mask (punct | PRINTFLAG ) /* . */,
109     ctype_base::mask (punct | PRINTFLAG ) /* / */,
110     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 0 */,
111     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 1 */,
112     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 2 */,
113     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 3 */,
114     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 4 */,
115     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 5 */,
116     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 6 */,
117     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 7 */,
118     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 8 */,
119     ctype_base::mask(digit | PRINTFLAG | xdigit) /* 9 */,
120     ctype_base::mask (punct | PRINTFLAG ) /* : */,
121     ctype_base::mask (punct | PRINTFLAG ) /* ; */,
122     ctype_base::mask (punct | PRINTFLAG ) /* < */,
123     ctype_base::mask (punct | PRINTFLAG ) /* = */,
124     ctype_base::mask (punct | PRINTFLAG ) /* > */,
125     ctype_base::mask (punct | PRINTFLAG ) /* ? */,
126     ctype_base::mask (punct | PRINTFLAG ) /* ! */,
127     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* A */,
128     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* B */,
129     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* C */,
130     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* D */,
131     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* E */,
132     ctype_base::mask(alpha | PRINTFLAG | upper | xdigit) /* F */,
133     ctype_base::mask(alpha | PRINTFLAG | upper) /* G */,
134     ctype_base::mask(alpha | PRINTFLAG | upper) /* H */,
135     ctype_base::mask(alpha | PRINTFLAG | upper) /* I */,
136     ctype_base::mask(alpha | PRINTFLAG | upper) /* J */,
137     ctype_base::mask(alpha | PRINTFLAG | upper) /* K */,
138     ctype_base::mask(alpha | PRINTFLAG | upper) /* L */,
139     ctype_base::mask(alpha | PRINTFLAG | upper) /* M */,
140     ctype_base::mask(alpha | PRINTFLAG | upper) /* N */,
141     ctype_base::mask(alpha | PRINTFLAG | upper) /* O */,
142     ctype_base::mask(alpha | PRINTFLAG | upper) /* P */,
143     ctype_base::mask(alpha | PRINTFLAG | upper) /* Q */,
144     ctype_base::mask(alpha | PRINTFLAG | upper) /* R */,
145     ctype_base::mask(alpha | PRINTFLAG | upper) /* S */,
146     ctype_base::mask(alpha | PRINTFLAG | upper) /* T */,
147     ctype_base::mask(alpha | PRINTFLAG | upper) /* U */,
148     ctype_base::mask(alpha | PRINTFLAG | upper) /* V */,
149     ctype_base::mask(alpha | PRINTFLAG | upper) /* W */,
150     ctype_base::mask(alpha | PRINTFLAG | upper) /* X */,
151     ctype_base::mask(alpha | PRINTFLAG | upper) /* Y */,
152     ctype_base::mask(alpha | PRINTFLAG | upper) /* Z */,
153     ctype_base::mask (punct | PRINTFLAG ) /* [ */,
154     ctype_base::mask (punct | PRINTFLAG ) /* \ */,
155     ctype_base::mask (punct | PRINTFLAG ) /* ] */,
156     ctype_base::mask (punct | PRINTFLAG ) /* ^ */,
157     ctype_base::mask (punct | PRINTFLAG ) /* _ */,
158     ctype_base::mask (punct | PRINTFLAG ) /* ` */,
159     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* a */,
160     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* b */,
161     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* c */,
162     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* d */,
163     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* e */,
164     ctype_base::mask(alpha | PRINTFLAG | lower | xdigit) /* f */,
165     ctype_base::mask(alpha | PRINTFLAG | lower) /* g */,
166     ctype_base::mask(alpha | PRINTFLAG | lower) /* h */,
167     ctype_base::mask(alpha | PRINTFLAG | lower) /* i */,
168     ctype_base::mask(alpha | PRINTFLAG | lower) /* j */,
169     ctype_base::mask(alpha | PRINTFLAG | lower) /* k */,
170     ctype_base::mask(alpha | PRINTFLAG | lower) /* l */,
171     ctype_base::mask(alpha | PRINTFLAG | lower) /* m */,
172     ctype_base::mask(alpha | PRINTFLAG | lower) /* n */,
173     ctype_base::mask(alpha | PRINTFLAG | lower) /* o */,
174     ctype_base::mask(alpha | PRINTFLAG | lower) /* p */,
175     ctype_base::mask(alpha | PRINTFLAG | lower) /* q */,
176     ctype_base::mask(alpha | PRINTFLAG | lower) /* r */,
177     ctype_base::mask(alpha | PRINTFLAG | lower) /* s */,
178     ctype_base::mask(alpha | PRINTFLAG | lower) /* t */,
179     ctype_base::mask(alpha | PRINTFLAG | lower) /* u */,
180     ctype_base::mask(alpha | PRINTFLAG | lower) /* v */,
181     ctype_base::mask(alpha | PRINTFLAG | lower) /* w */,
182     ctype_base::mask(alpha | PRINTFLAG | lower) /* x */,
183     ctype_base::mask(alpha | PRINTFLAG | lower) /* y */,
184     ctype_base::mask(alpha | PRINTFLAG | lower) /* x */,
185     ctype_base::mask (punct | PRINTFLAG ) /* { */,
186     ctype_base::mask (punct | PRINTFLAG ) /* | */,
187     ctype_base::mask (punct | PRINTFLAG ) /* } */,
188     ctype_base::mask (punct | PRINTFLAG ) /* ~ */,
189     cntrl /* del (0x7f)*/,
190     /* ASCII is a 7-bit code, so everything else is non-ASCII */
191     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),
192     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),
193     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),
194     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),
195     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),
196     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),
197     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),
198     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),
199     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),
200     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),
201     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),
202     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),
203     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),
204     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),
205     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),
206     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)
207   };
208   return _S_classic_table;
209 }
210 
211 // For every c in the range 0 <= c < 256, _S_upper[c] is the
212 // uppercased version of c and _S_lower[c] is the lowercased
213 // version.  As before, these two tables assume the ASCII character
214 // set.
215 
216 const unsigned char _S_upper[ctype<char>::table_size] =
217 {
218   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
219   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
220   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
221   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
222   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
223   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
224   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
225   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
226   0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
227   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
228   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
229   0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
230   0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
231   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
232   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
233   0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
234   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
235   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
236   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
237   0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
238   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
239   0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
240   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
241   0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
242   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
243   0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
244   0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
245   0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
246   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
247   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
248   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
249   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
250 };
251 
252 const unsigned char _S_lower[ctype<char>::table_size] =
253 {
254   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
255   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
256   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
257   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
258   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
259   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
260   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
261   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
262   0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
263   0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
264   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
265   0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
266   0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
267   0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
268   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
269   0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
270   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
271   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
272   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
273   0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
274   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
275   0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
276   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
277   0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
278   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
279   0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
280   0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
281   0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
282   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
283   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
284   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
285   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
286 };
287 
288 //An helper struct to check wchar_t index without generating warnings
289 //under some compilers (gcc) because of a limited range of value
290 //(when wchar_t is unsigned)
291 template <bool _IsSigned>
292 struct _WCharIndexT;
293 
294 #if !defined (__BORLANDC__) && \
295     !(defined (__GNUC__) && (defined (__MINGW32__) || defined (__CYGWIN__))) && \
296 	!defined (__GCCE__) && \
297     !defined (__ICL)
298 _STLP_TEMPLATE_NULL
299 struct _WCharIndexT<true> {
in_range_WCharIndexT300   static bool in_range(wchar_t c, size_t upperBound) {
301     return c >= 0 && size_t(c) < upperBound;
302   }
303 };
304 #endif
305 
306 _STLP_TEMPLATE_NULL
307 struct _WCharIndexT<false> {
in_range_WCharIndexT308   static bool in_range(wchar_t c, size_t upperBound) {
309     return size_t(c) < upperBound;
310   }
311 };
312 
313 typedef _WCharIndexT<wchar_t(-1) < 0> _WCharIndex;
314 
315 // Some helper functions used in ctype<>::scan_is and scan_is_not.
316 
317 struct _Ctype_is_mask {
318   typedef char argument_type;
319   typedef bool result_type;
320 
321   ctype_base::mask _Mask;
322   const ctype_base::mask* _M_table;
323 
_Ctype_is_mask_Ctype_is_mask324   _Ctype_is_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
operator ()_Ctype_is_mask325   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) != 0; }
326 };
327 
328 struct _Ctype_not_mask {
329   typedef char argument_type;
330   typedef bool result_type;
331 
332   ctype_base::mask _Mask;
333   const ctype_base::mask* _M_table;
334 
_Ctype_not_mask_Ctype_not_mask335   _Ctype_not_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
operator ()_Ctype_not_mask336   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) == 0; }
337 };
338 
ctype(const ctype_base::mask * __tab,bool __del,size_t __refs)339 ctype<char>::ctype(const ctype_base::mask * __tab, bool __del, size_t __refs) :
340   locale::facet(__refs),
341   _M_ctype_table(__tab ? __tab : classic_table()),
342   _M_delete(__tab && __del)
343 {}
344 
~ctype()345 ctype<char>::~ctype() {
346   if (_M_delete)
347     delete[] __CONST_CAST(ctype_base::mask *, _M_ctype_table);
348 }
349 
350 const char*
scan_is(ctype_base::mask __m,const char * __low,const char * __high) const351 ctype<char>::scan_is(ctype_base::mask  __m, const char* __low, const char* __high) const  {
352   return _STLP_STD::find_if(__low, __high, _Ctype_is_mask(__m, _M_ctype_table));
353 }
354 
355 const char*
scan_not(ctype_base::mask __m,const char * __low,const char * __high) const356 ctype<char>::scan_not(ctype_base::mask  __m, const char* __low, const char* __high) const {
357   return _STLP_STD::find_if(__low, __high, _Ctype_not_mask(__m, _M_ctype_table));
358 }
359 
do_toupper(char __c) const360 char ctype<char>::do_toupper(char __c) const
361 { return (char) _S_upper[(unsigned char) __c]; }
do_tolower(char __c) const362 char ctype<char>::do_tolower(char __c) const
363 { return (char) _S_lower[(unsigned char) __c]; }
364 
do_toupper(char * __low,const char * __high) const365 const char* ctype<char>::do_toupper(char* __low, const char* __high) const {
366   for ( ; __low < __high; ++__low)
367     *__low = (char) _S_upper[(unsigned char) *__low];
368   return __high;
369 }
do_tolower(char * __low,const char * __high) const370 const char* ctype<char>::do_tolower(char* __low, const char* __high) const {
371   for ( ; __low < __high; ++__low)
372     *__low = (char) _S_lower[(unsigned char) *__low];
373   return __high;
374 }
375 
376 char
do_widen(char __c) const377 ctype<char>::do_widen(char __c) const { return __c; }
378 
379 const char*
do_widen(const char * __low,const char * __high,char * __to) const380 ctype<char>::do_widen(const char* __low, const char* __high,
381                       char* __to) const {
382   _STLP_PRIV __copy_trivial(__low, __high, __to);
383   return __high;
384 }
385 char
do_narrow(char __c,char) const386 ctype<char>::do_narrow(char __c, char /* dfault */ ) const { return __c; }
387 const char*
do_narrow(const char * __low,const char * __high,char,char * __to) const388 ctype<char>::do_narrow(const char* __low, const char* __high,
389                        char /* dfault */, char* __to) const {
390   _STLP_PRIV __copy_trivial(__low, __high, __to);
391   return __high;
392 }
393 
394 
395 #if !defined (_STLP_NO_WCHAR_T)
396 
397   struct _Ctype_w_is_mask {
398     typedef wchar_t argument_type;
399     typedef bool    result_type;
400 
401     ctype_base::mask M;
402     const ctype_base::mask* table;
403 
_Ctype_w_is_mask_Ctype_w_is_mask404     _Ctype_w_is_mask(ctype_base::mask m, const ctype_base::mask* t)
405       : M(m), table(t) {}
operator ()_Ctype_w_is_mask406     bool operator()(wchar_t c) const {
407       return _WCharIndex::in_range(c, ctype<char>::table_size) && (table[c] & M);
408     }
409   };
410 
411 //----------------------------------------------------------------------
412 // ctype<wchar_t>
413 
~ctype()414 ctype<wchar_t>::~ctype() {}
415 
416 
do_is(ctype_base::mask m,wchar_t c) const417 bool ctype<wchar_t>::do_is(ctype_base::mask  m, wchar_t c) const {
418   const ctype_base::mask * table = ctype<char>::classic_table();
419   return _WCharIndex::in_range(c, ctype<char>::table_size) && (m & table[c]);
420 }
421 
do_is(const wchar_t * low,const wchar_t * high,ctype_base::mask * vec) const422 const wchar_t* ctype<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
423                                      ctype_base::mask * vec) const {
424   // boris : not clear if this is the right thing to do...
425   const ctype_base::mask * table = ctype<char>::classic_table();
426   for ( ; low < high; ++low, ++vec) {
427     wchar_t c = *low;
428     *vec = _WCharIndex::in_range(c, ctype<char>::table_size) ? table[c] : ctype_base::mask(0);
429   }
430   return high;
431 }
432 
433 const wchar_t*
do_scan_is(ctype_base::mask m,const wchar_t * low,const wchar_t * high) const434 ctype<wchar_t>::do_scan_is(ctype_base::mask  m,
435                            const wchar_t* low, const wchar_t* high) const {
436   return find_if(low, high, _Ctype_w_is_mask(m, ctype<char>::classic_table()));
437 }
438 
439 
440 const wchar_t*
do_scan_not(ctype_base::mask m,const wchar_t * low,const wchar_t * high) const441 ctype<wchar_t>::do_scan_not(ctype_base::mask  m,
442                             const wchar_t* low, const wchar_t* high) const {
443   return find_if(low, high, not1(_Ctype_w_is_mask(m, ctype<char>::classic_table())));
444 }
445 
do_toupper(wchar_t c) const446 wchar_t ctype<wchar_t>::do_toupper(wchar_t c) const {
447   return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
448                                                            : c;
449 }
450 
451 const wchar_t*
do_toupper(wchar_t * low,const wchar_t * high) const452 ctype<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
453   for ( ; low < high; ++low) {
454     wchar_t c = *low;
455     *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
456                                                              : c;
457   }
458   return high;
459 }
460 
do_tolower(wchar_t c) const461 wchar_t ctype<wchar_t>::do_tolower(wchar_t c) const {
462   return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
463                                                            : c;
464 }
465 
466 const wchar_t*
do_tolower(wchar_t * low,const wchar_t * high) const467 ctype<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
468   for ( ; low < high; ++low) {
469     wchar_t c = *low;
470     *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
471                                                              : c;
472   }
473   return high;
474 }
475 
do_widen(char c) const476 wchar_t ctype<wchar_t>::do_widen(char c) const {
477   return (wchar_t)(unsigned char)c;
478 }
479 
480 const char*
do_widen(const char * low,const char * high,wchar_t * dest) const481 ctype<wchar_t>::do_widen(const char* low, const char* high,
482                          wchar_t* dest) const {
483   while (low != high)
484     *dest++ = (wchar_t)(unsigned char)*low++;
485   return high;
486 }
487 
do_narrow(wchar_t c,char dfault) const488 char ctype<wchar_t>::do_narrow(wchar_t c, char dfault) const {
489   return (unsigned char) c == c ? c : dfault;
490 }
491 
do_narrow(const wchar_t * low,const wchar_t * high,char dfault,char * dest) const492 const wchar_t* ctype<wchar_t>::do_narrow(const wchar_t* low,
493                                          const wchar_t* high,
494                                          char dfault, char* dest) const {
495   while (low != high) {
496     wchar_t c = *low++;
497     *dest++ = (unsigned char) c == c ? c : dfault;
498   }
499 
500   return high;
501 }
502 
503 # endif
504 _STLP_END_NAMESPACE
505 
506 // Local Variables:
507 // mode:C++
508 // End:
509 
510