• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 // c_ctype.hpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_XPRESSIVE_TRAITS_DETAIL_C_CTYPE_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_TRAITS_DETAIL_C_CTYPE_HPP_EAN_10_04_2005
10 
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER)
13 # pragma once
14 #endif
15 
16 #include <cctype>
17 #include <cstring>
18 #include <boost/mpl/assert.hpp>
19 #include <boost/xpressive/detail/detail_fwd.hpp>
20 
21 #ifndef BOOST_XPRESSIVE_NO_WREGEX
22 # include <cwchar>
23 # include <cwctype>
24 #endif
25 
26 namespace boost { namespace xpressive { namespace detail
27 {
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 // isnewline
31 //
isnewline(char ch)32 inline bool isnewline(char ch)
33 {
34     switch(ch)
35     {
36     case L'\n': case L'\r': case L'\f':
37         return true;
38     default:
39         return false;
40     }
41 }
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 // iswnewline
45 //
iswnewline(wchar_t ch)46 inline bool iswnewline(wchar_t ch)
47 {
48     switch(ch)
49     {
50     case L'\n': case L'\r': case L'\f': case 0x2028u: case 0x2029u: case 0x85u:
51         return true;
52     default:
53         return false;
54     }
55 }
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 // classname_a
59 //
60 template<typename FwdIter>
classname_a(FwdIter begin,FwdIter end)61 inline std::string classname_a(FwdIter begin, FwdIter end)
62 {
63     std::string name(begin, end);
64     for(std::size_t i = 0; i < name.size(); ++i)
65     {
66         using namespace std;
67         name[i] = static_cast<char>(tolower(static_cast<unsigned char>(name[i])));
68     }
69     return name;
70 }
71 
72 #ifndef BOOST_XPRESSIVE_NO_WREGEX
73 ///////////////////////////////////////////////////////////////////////////////
74 // classname_w
75 //
76 template<typename FwdIter>
classname_w(FwdIter begin,FwdIter end)77 inline std::wstring classname_w(FwdIter begin, FwdIter end)
78 {
79     std::wstring name(begin, end);
80     for(std::size_t i = 0; i < name.size(); ++i)
81     {
82         using namespace std;
83         name[i] = towlower(name[i]);
84     }
85     return name;
86 }
87 #endif
88 
89 
90 
91 ///////////////////////////////////////////////////////////////////////////////
92 // char_class_impl
93 //
94 template<typename Char>
95 struct char_class_impl;
96 
97 
98 #if defined(__QNXNTO__) || defined(__VXWORKS__)
99 
100 ///////////////////////////////////////////////////////////////////////////////
101 //
102 template<>
103 struct char_class_impl<char>
104 {
105     typedef short char_class_type;
106     BOOST_MPL_ASSERT_RELATION(0x07FF, ==, (_XB|_XA|_XS|_BB|_CN|_DI|_LO|_PU|_SP|_UP|_XD));
107     BOOST_STATIC_CONSTANT(short, char_class_underscore = 0x1000);
108     BOOST_STATIC_CONSTANT(short, char_class_newline = 0x2000);
109 
110     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl111     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
112     {
113         using namespace std;
114         string const name = classname_a(begin, end);
115         if(name == "alnum")     return _DI|_LO|_UP|_XA;
116         if(name == "alpha")     return _LO|_UP|_XA;
117         if(name == "blank")     return _SP|_XB;
118         if(name == "cntrl")     return _BB;
119         if(name == "d")         return _DI;
120         if(name == "digit")     return _DI;
121         if(name == "graph")     return _DI|_LO|_PU|_UP|_XA;
122         if(name == "lower")     return icase ? (_LO|_UP) : _LO;
123         if(name == "newline")   return char_class_newline;
124         if(name == "print")     return _DI|_LO|_PU|_SP|_UP|_XA;
125         if(name == "punct")     return _PU;
126         if(name == "s")         return _CN|_SP|_XS;
127         if(name == "space")     return _CN|_SP|_XS;
128         if(name == "upper")     return icase ? (_UP|_LO) : _UP;
129         if(name == "w")         return _DI|_LO|_UP|_XA|char_class_underscore;
130         if(name == "xdigit")    return _XD;
131         return 0;
132     }
133 
isctypeboost::xpressive::detail::char_class_impl134     static bool isctype(char ch, char_class_type mask)
135     {
136         using namespace std;
137         if(0 != (_Getchrtype((unsigned char)ch) & mask))
138         {
139             return true;
140         }
141 
142         switch(ch)
143         {
144         case '_': return 0 != (mask & char_class_underscore);
145         case '\n': case '\r': case '\f': return 0 != (mask & char_class_newline);
146         default:;
147         }
148 
149         return false;
150     }
151 };
152 
153 #ifndef BOOST_XPRESSIVE_NO_WREGEX
154 ///////////////////////////////////////////////////////////////////////////////
155 //
156 template<>
157 struct char_class_impl<wchar_t>
158 {
159     typedef int char_class_type;
160     //BOOST_STATIC_CONSTANT(int, char_class_alnum         = 0x0001);
161     BOOST_STATIC_CONSTANT(int, char_class_alpha         = 0x0002);
162     BOOST_STATIC_CONSTANT(int, char_class_blank         = 0x0004);
163     BOOST_STATIC_CONSTANT(int, char_class_cntrl         = 0x0008);
164     BOOST_STATIC_CONSTANT(int, char_class_digit         = 0x0010);
165     //BOOST_STATIC_CONSTANT(int, char_class_graph         = 0x0020);
166     BOOST_STATIC_CONSTANT(int, char_class_lower         = 0x0040);
167     //BOOST_STATIC_CONSTANT(int, char_class_print         = 0x0080);
168     BOOST_STATIC_CONSTANT(int, char_class_punct         = 0x0100);
169     BOOST_STATIC_CONSTANT(int, char_class_space         = 0x0200);
170     BOOST_STATIC_CONSTANT(int, char_class_upper         = 0x0400);
171     BOOST_STATIC_CONSTANT(int, char_class_underscore    = 0x0800);
172     BOOST_STATIC_CONSTANT(int, char_class_xdigit        = 0x1000);
173     BOOST_STATIC_CONSTANT(int, char_class_newline       = 0x2000);
174 
175     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl176     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
177     {
178         using namespace std;
179         wstring const name = classname_w(begin, end);
180         if(name == L"alnum")    return char_class_alpha|char_class_digit;
181         if(name == L"alpha")    return char_class_alpha;
182         if(name == L"blank")    return char_class_blank;
183         if(name == L"cntrl")    return char_class_cntrl;
184         if(name == L"d")        return char_class_digit;
185         if(name == L"digit")    return char_class_digit;
186         if(name == L"graph")    return char_class_punct|char_class_alpha|char_class_digit;
187         if(name == L"lower")    return icase ? (char_class_lower|char_class_upper) : char_class_lower;
188         if(name == L"newline")  return char_class_newline;
189         if(name == L"print")    return char_class_blank|char_class_punct|char_class_alpha|char_class_digit;
190         if(name == L"punct")    return char_class_punct;
191         if(name == L"s")        return char_class_space;
192         if(name == L"space")    return char_class_space;
193         if(name == L"upper")    return icase ? (char_class_upper|char_class_lower) : char_class_upper;
194         if(name == L"w")        return char_class_alpha|char_class_digit|char_class_underscore;
195         if(name == L"xdigit")   return char_class_xdigit;
196         return 0;
197     }
198 
isctypeboost::xpressive::detail::char_class_impl199     static bool isctype(wchar_t ch, char_class_type mask)
200     {
201         using namespace std;
202         return ((char_class_alpha & mask) && iswalpha(ch))
203             || ((char_class_blank & mask) && (L' ' == ch || L'\t' == ch)) // BUGBUG
204             || ((char_class_cntrl & mask) && iswcntrl(ch))
205             || ((char_class_digit & mask) && iswdigit(ch))
206             || ((char_class_lower & mask) && iswlower(ch))
207             || ((char_class_newline & mask) && detail::iswnewline(ch))
208             || ((char_class_punct & mask) && iswpunct(ch))
209             || ((char_class_space & mask) && iswspace(ch))
210             || ((char_class_upper & mask) && iswupper(ch))
211             || ((char_class_underscore & mask) && L'_' == ch)
212             || ((char_class_xdigit & mask) && iswxdigit(ch))
213             ;
214     }
215 };
216 #endif
217 
218 
219 #elif defined(__MINGW32_VERSION)
220 
221 
222 ///////////////////////////////////////////////////////////////////////////////
223 //
224 template<>
225 struct char_class_impl<char>
226 {
227     typedef int char_class_type;
228     BOOST_MPL_ASSERT_RELATION(0x81FF, ==, (_ALPHA|_UPPER|_LOWER|_DIGIT|_SPACE|_PUNCT|_CONTROL|_BLANK|_HEX|_LEADBYTE));
229     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0x1000);
230     BOOST_STATIC_CONSTANT(int, char_class_newline = 0x2000);
231 
232     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl233     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
234     {
235         using namespace std;
236         string const name = classname_a(begin, end);
237         if(name == "alnum")     return _ALPHA|_DIGIT;
238         if(name == "alpha")     return _ALPHA;
239         if(name == "blank")     return _BLANK; // this is ONLY space!!!
240         if(name == "cntrl")     return _CONTROL;
241         if(name == "d")         return _DIGIT;
242         if(name == "digit")     return _DIGIT;
243         if(name == "graph")     return _PUNCT|_ALPHA|_DIGIT;
244         if(name == "lower")     return icase ? (_LOWER|_UPPER) : _LOWER;
245         if(name == "newline")   return char_class_newline;
246         if(name == "print")     return _BLANK|_PUNCT|_ALPHA|_DIGIT;
247         if(name == "punct")     return _PUNCT;
248         if(name == "s")         return _SPACE;
249         if(name == "space")     return _SPACE;
250         if(name == "upper")     return icase ? (_UPPER|_LOWER) : _UPPER;
251         if(name == "w")         return _ALPHA|_DIGIT|char_class_underscore;
252         if(name == "xdigit")    return _HEX;
253         return 0;
254     }
255 
isctypeboost::xpressive::detail::char_class_impl256     static bool isctype(char ch, char_class_type mask)
257     {
258         using namespace std;
259         if(0 != _isctype(static_cast<unsigned char>(ch), mask))
260         {
261             return true;
262         }
263 
264         switch(ch)
265         {
266         case '\t': return 0 != (mask & _BLANK);
267         case '_': return 0 != (mask & char_class_underscore);
268         case '\n': case '\r': case '\f': return 0 != (mask & char_class_newline);
269         default:;
270         }
271 
272         return false;
273     }
274 };
275 
276 #ifndef BOOST_XPRESSIVE_NO_WREGEX
277 ///////////////////////////////////////////////////////////////////////////////
278 //
279 template<>
280 struct char_class_impl<wchar_t>
281 {
282     typedef wctype_t char_class_type;
283     BOOST_MPL_ASSERT_RELATION(0x81FF, ==, (_ALPHA|_UPPER|_LOWER|_DIGIT|_SPACE|_PUNCT|_CONTROL|_BLANK|_HEX|_LEADBYTE));
284     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0x1000);
285     BOOST_STATIC_CONSTANT(int, char_class_newline = 0x2000);
286 
287     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl288     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
289     {
290         using namespace std;
291         wstring const name = classname_w(begin, end);
292         if(name == L"alnum")    return _ALPHA|_DIGIT;
293         if(name == L"alpha")    return _ALPHA;
294         if(name == L"blank")    return _BLANK; // this is ONLY space!!!
295         if(name == L"cntrl")    return _CONTROL;
296         if(name == L"d")        return _DIGIT;
297         if(name == L"digit")    return _DIGIT;
298         if(name == L"graph")    return _PUNCT|_ALPHA|_DIGIT;
299         if(name == L"lower")    return icase ? (_LOWER|_UPPER) : _LOWER;
300         if(name == L"newline")  return char_class_newline;
301         if(name == L"print")    return _BLANK|_PUNCT|_ALPHA|_DIGIT;
302         if(name == L"punct")    return _PUNCT;
303         if(name == L"s")        return _SPACE;
304         if(name == L"space")    return _SPACE;
305         if(name == L"upper")    return icase ? (_UPPER|_LOWER) : _UPPER;
306         if(name == L"w")        return _ALPHA|_DIGIT|char_class_underscore;
307         if(name == L"xdigit")   return _HEX;
308         return 0;
309     }
310 
isctypeboost::xpressive::detail::char_class_impl311     static bool isctype(wchar_t ch, char_class_type mask)
312     {
313         using namespace std;
314         if(0 != iswctype(ch, mask))
315         {
316             return true;
317         }
318 
319         switch(ch)
320         {
321         case L'\t': return 0 != (mask & _BLANK);
322         case L'_': return 0 != (mask & char_class_underscore);
323         case L'\n': case L'\r': case L'\f': case 0x2028u: case 0x2029u: case 0x85u:
324             return 0 != (mask & char_class_newline);
325         default:;
326         }
327 
328         return false;
329     }
330 };
331 #endif
332 
333 
334 #elif defined(__CYGWIN__)
335 
336 
337 
338 ///////////////////////////////////////////////////////////////////////////////
339 //
340 template<>
341 struct char_class_impl<char>
342 {
343     typedef int char_class_type;
344     BOOST_MPL_ASSERT_RELATION(0377, ==, (_U|_L|_N|_S|_P|_C|_B|_X));
345     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0400);
346     BOOST_STATIC_CONSTANT(int, char_class_newline = 01000);
347 
348     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl349     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
350     {
351         using namespace std;
352         string const name = classname_a(begin, end);
353         if(name == "alnum")     return _U|_L|_N;
354         if(name == "alpha")     return _U|_L;
355         if(name == "blank")     return _B; // BUGBUG what is this?
356         if(name == "cntrl")     return _C;
357         if(name == "d")         return _N;
358         if(name == "digit")     return _N;
359         if(name == "graph")     return _P|_U|_L|_N;
360         if(name == "lower")     return icase ? (_L|_U) : _L;
361         if(name == "newline")   return char_class_newline;
362         if(name == "print")     return _B|_P|_U|_L|_N;
363         if(name == "punct")     return _P;
364         if(name == "s")         return _S;
365         if(name == "space")     return _S;
366         if(name == "upper")     return icase ? (_U|_L) : _U;
367         if(name == "w")         return _U|_L|_N|char_class_underscore;
368         if(name == "xdigit")    return _X;
369         return 0;
370     }
371 
isctypeboost::xpressive::detail::char_class_impl372     static bool isctype(char ch, char_class_type mask)
373     {
374         if(0 != static_cast<unsigned char>(((_ctype_+1)[(unsigned)(ch)]) & mask))
375         {
376             return true;
377         }
378 
379         switch(ch)
380         {
381         case '_': return 0 != (mask & char_class_underscore);
382         case '\n': case '\r': case '\f': return 0 != (mask & char_class_newline);
383         default:;
384         }
385 
386         return false;
387     }
388 };
389 
390 #ifndef BOOST_XPRESSIVE_NO_WREGEX
391 ///////////////////////////////////////////////////////////////////////////////
392 //
393 template<>
394 struct char_class_impl<wchar_t>
395 {
396     typedef int char_class_type;
397     //BOOST_STATIC_CONSTANT(int, char_class_alnum         = 0x0001);
398     BOOST_STATIC_CONSTANT(int, char_class_alpha         = 0x0002);
399     BOOST_STATIC_CONSTANT(int, char_class_blank         = 0x0004);
400     BOOST_STATIC_CONSTANT(int, char_class_cntrl         = 0x0008);
401     BOOST_STATIC_CONSTANT(int, char_class_digit         = 0x0010);
402     //BOOST_STATIC_CONSTANT(int, char_class_graph         = 0x0020);
403     BOOST_STATIC_CONSTANT(int, char_class_lower         = 0x0040);
404     //BOOST_STATIC_CONSTANT(int, char_class_print         = 0x0080);
405     BOOST_STATIC_CONSTANT(int, char_class_punct         = 0x0100);
406     BOOST_STATIC_CONSTANT(int, char_class_space         = 0x0200);
407     BOOST_STATIC_CONSTANT(int, char_class_upper         = 0x0400);
408     BOOST_STATIC_CONSTANT(int, char_class_underscore    = 0x0800);
409     BOOST_STATIC_CONSTANT(int, char_class_xdigit        = 0x1000);
410     BOOST_STATIC_CONSTANT(int, char_class_newline       = 0x2000);
411 
412     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl413     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
414     {
415         using namespace std;
416         wstring const name = classname_w(begin, end);
417         if(name == L"alnum")    return char_class_alpha|char_class_digit;
418         if(name == L"alpha")    return char_class_alpha;
419         if(name == L"blank")    return char_class_blank;
420         if(name == L"cntrl")    return char_class_cntrl;
421         if(name == L"d")        return char_class_digit;
422         if(name == L"digit")    return char_class_digit;
423         if(name == L"graph")    return char_class_punct|char_class_alpha|char_class_digit;
424         if(name == L"lower")    return icase ? (char_class_lower|char_class_upper) : char_class_lower;
425         if(name == L"newline")  return char_class_newline;
426         if(name == L"print")    return char_class_blank|char_class_punct|char_class_alpha|char_class_digit;
427         if(name == L"punct")    return char_class_punct;
428         if(name == L"s")        return char_class_space;
429         if(name == L"space")    return char_class_space;
430         if(name == L"upper")    return icase ? (char_class_upper|char_class_lower) : char_class_upper;
431         if(name == L"w")        return char_class_alpha|char_class_digit|char_class_underscore;
432         if(name == L"xdigit")   return char_class_xdigit;
433         return 0;
434     }
435 
isctypeboost::xpressive::detail::char_class_impl436     static bool isctype(wchar_t ch, char_class_type mask)
437     {
438         using namespace std;
439         return ((char_class_alpha & mask) && iswalpha(ch))
440             || ((char_class_blank & mask) && (L' ' == ch || L'\t' == ch)) // BUGBUG
441             || ((char_class_cntrl & mask) && iswcntrl(ch))
442             || ((char_class_digit & mask) && iswdigit(ch))
443             || ((char_class_lower & mask) && iswlower(ch))
444             || ((char_class_newline & mask) && detail::iswnewline(ch))
445             || ((char_class_punct & mask) && iswpunct(ch))
446             || ((char_class_space & mask) && iswspace(ch))
447             || ((char_class_upper & mask) && iswupper(ch))
448             || ((char_class_underscore & mask) && L'_' == ch)
449             || ((char_class_xdigit & mask) && iswxdigit(ch))
450             ;
451     }
452 };
453 #endif
454 
455 
456 
457 #elif defined(__GLIBC__)
458 
459 
460 
461 
462 ///////////////////////////////////////////////////////////////////////////////
463 //
464 template<>
465 struct char_class_impl<char>
466 {
467     typedef int char_class_type;
468     BOOST_MPL_ASSERT_RELATION(0xffff, ==, (_ISalnum|_ISalpha|_ISblank|_IScntrl|_ISdigit|_ISgraph|
469                                            _ISlower|_ISprint|_ISpunct|_ISspace|_ISupper|_ISxdigit|0xffff));
470     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0x00010000);
471     BOOST_STATIC_CONSTANT(int, char_class_newline = 0x00020000);
472 
473     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl474     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
475     {
476         using namespace std;
477         string const name = classname_a(begin, end);
478         if(name == "alnum")     return _ISalnum;
479         if(name == "alpha")     return _ISalpha;
480         if(name == "blank")     return _ISblank;
481         if(name == "cntrl")     return _IScntrl;
482         if(name == "d")         return _ISdigit;
483         if(name == "digit")     return _ISdigit;
484         if(name == "graph")     return _ISgraph;
485         if(name == "lower")     return icase ? (_ISlower|_ISupper) : _ISlower;
486         if(name == "print")     return _ISprint;
487         if(name == "newline")   return char_class_newline;
488         if(name == "punct")     return _ISpunct;
489         if(name == "s")         return _ISspace;
490         if(name == "space")     return _ISspace;
491         if(name == "upper")     return icase ? (_ISupper|_ISlower) : _ISupper;
492         if(name == "w")         return _ISalnum|char_class_underscore;
493         if(name == "xdigit")    return _ISxdigit;
494         return 0;
495     }
496 
isctypeboost::xpressive::detail::char_class_impl497     static bool isctype(char ch, char_class_type mask)
498     {
499         if(glibc_isctype(ch, mask))
500         {
501             return true;
502         }
503 
504         switch(ch)
505         {
506         case '_': return 0 != (mask & char_class_underscore);
507         case '\n': case '\r': case '\f': return 0 != (mask & char_class_newline);
508         default:;
509         }
510 
511         return false;
512     }
513 
glibc_isctypeboost::xpressive::detail::char_class_impl514     static bool glibc_isctype(char ch, char_class_type mask)
515     {
516         #ifdef __isctype
517         return 0 != __isctype(ch, mask);
518         #else
519         return 0 != ((*__ctype_b_loc())[(int)(ch)] & (unsigned short int)mask);
520         #endif
521     }
522 };
523 
524 #ifndef BOOST_XPRESSIVE_NO_WREGEX
525 ///////////////////////////////////////////////////////////////////////////////
526 //
527 template<>
528 struct char_class_impl<wchar_t>
529 {
530     typedef int char_class_type;
531     //BOOST_STATIC_CONSTANT(int, char_class_alnum         = 0x0001);
532     BOOST_STATIC_CONSTANT(int, char_class_alpha         = 0x0002);
533     BOOST_STATIC_CONSTANT(int, char_class_blank         = 0x0004);
534     BOOST_STATIC_CONSTANT(int, char_class_cntrl         = 0x0008);
535     BOOST_STATIC_CONSTANT(int, char_class_digit         = 0x0010);
536     //BOOST_STATIC_CONSTANT(int, char_class_graph         = 0x0020);
537     BOOST_STATIC_CONSTANT(int, char_class_lower         = 0x0040);
538     //BOOST_STATIC_CONSTANT(int, char_class_print         = 0x0080);
539     BOOST_STATIC_CONSTANT(int, char_class_punct         = 0x0100);
540     BOOST_STATIC_CONSTANT(int, char_class_space         = 0x0200);
541     BOOST_STATIC_CONSTANT(int, char_class_upper         = 0x0400);
542     BOOST_STATIC_CONSTANT(int, char_class_underscore    = 0x0800);
543     BOOST_STATIC_CONSTANT(int, char_class_xdigit        = 0x1000);
544     BOOST_STATIC_CONSTANT(int, char_class_newline       = 0x2000);
545 
546     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl547     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
548     {
549         using namespace std;
550         wstring const name = classname_w(begin, end);
551         if(name == L"alnum")    return char_class_alpha|char_class_digit;
552         if(name == L"alpha")    return char_class_alpha;
553         if(name == L"blank")    return char_class_blank;
554         if(name == L"cntrl")    return char_class_cntrl;
555         if(name == L"d")        return char_class_digit;
556         if(name == L"digit")    return char_class_digit;
557         if(name == L"graph")    return char_class_punct|char_class_alpha|char_class_digit;
558         if(name == L"lower")    return icase ? (char_class_lower|char_class_upper) : char_class_lower;
559         if(name == L"newline")  return char_class_newline;
560         if(name == L"print")    return char_class_blank|char_class_punct|char_class_alpha|char_class_digit;
561         if(name == L"punct")    return char_class_punct;
562         if(name == L"s")        return char_class_space;
563         if(name == L"space")    return char_class_space;
564         if(name == L"upper")    return icase ? (char_class_upper|char_class_lower) : char_class_upper;
565         if(name == L"w")        return char_class_alpha|char_class_digit|char_class_underscore;
566         if(name == L"xdigit")   return char_class_xdigit;
567         return 0;
568     }
569 
isctypeboost::xpressive::detail::char_class_impl570     static bool isctype(wchar_t ch, char_class_type mask)
571     {
572         using namespace std;
573         return ((char_class_alpha & mask) && iswalpha(ch))
574             || ((char_class_blank & mask) && (L' ' == ch || L'\t' == ch)) // BUGBUG
575             || ((char_class_cntrl & mask) && iswcntrl(ch))
576             || ((char_class_digit & mask) && iswdigit(ch))
577             || ((char_class_lower & mask) && iswlower(ch))
578             || ((char_class_newline & mask) && detail::iswnewline(ch))
579             || ((char_class_punct & mask) && iswpunct(ch))
580             || ((char_class_space & mask) && iswspace(ch))
581             || ((char_class_upper & mask) && iswupper(ch))
582             || ((char_class_underscore & mask) && L'_' == ch)
583             || ((char_class_xdigit & mask) && iswxdigit(ch))
584             ;
585     }
586 };
587 #endif
588 
589 
590 
591 #elif defined(_CPPLIB_VER) // Dinkumware STL
592 
593 
594 
595 
596 ///////////////////////////////////////////////////////////////////////////////
597 //
598 template<>
599 struct char_class_impl<char>
600 {
601     typedef int char_class_type;
602     BOOST_MPL_ASSERT_RELATION(0x81FF, ==, (_ALPHA|_UPPER|_LOWER|_DIGIT|_SPACE|_PUNCT|_CONTROL|_BLANK|_HEX|_LEADBYTE));
603     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0x1000);
604     BOOST_STATIC_CONSTANT(int, char_class_newline = 0x2000);
605 
606     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl607     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
608     {
609         using namespace std;
610         string const name = classname_a(begin, end);
611         if(name == "alnum")     return _ALPHA|_DIGIT;
612         if(name == "alpha")     return _ALPHA;
613         if(name == "blank")     return _BLANK; // this is ONLY space!!!
614         if(name == "cntrl")     return _CONTROL;
615         if(name == "d")         return _DIGIT;
616         if(name == "digit")     return _DIGIT;
617         if(name == "graph")     return _PUNCT|_ALPHA|_DIGIT;
618         if(name == "lower")     return icase ? (_LOWER|_UPPER) : _LOWER;
619         if(name == "newline")   return char_class_newline;
620         if(name == "print")     return _BLANK|_PUNCT|_ALPHA|_DIGIT;
621         if(name == "punct")     return _PUNCT;
622         if(name == "s")         return _SPACE;
623         if(name == "space")     return _SPACE;
624         if(name == "upper")     return icase ? (_UPPER|_LOWER) : _UPPER;
625         if(name == "w")         return _ALPHA|_DIGIT|char_class_underscore;
626         if(name == "xdigit")    return _HEX;
627         return 0;
628     }
629 
isctypeboost::xpressive::detail::char_class_impl630     static bool isctype(char ch, char_class_type mask)
631     {
632         using namespace std;
633         if(0 != _isctype(static_cast<unsigned char>(ch), mask))
634         {
635             return true;
636         }
637 
638         switch(ch)
639         {
640         case '\t': return 0 != (mask & _BLANK);
641         case '_': return 0 != (mask & char_class_underscore);
642         case '\n': case '\r': case '\f': return 0 != (mask & char_class_newline);
643         default:;
644         }
645 
646         return false;
647     }
648 };
649 
650 #ifndef BOOST_XPRESSIVE_NO_WREGEX
651 ///////////////////////////////////////////////////////////////////////////////
652 //
653 template<>
654 struct char_class_impl<wchar_t>
655 {
656     typedef wctype_t char_class_type;
657     BOOST_MPL_ASSERT_RELATION(0x81FF, ==, (_ALPHA|_UPPER|_LOWER|_DIGIT|_SPACE|_PUNCT|_CONTROL|_BLANK|_HEX|_LEADBYTE));
658     BOOST_STATIC_CONSTANT(int, char_class_underscore = 0x1000);
659     BOOST_STATIC_CONSTANT(int, char_class_newline = 0x2000);
660 
661     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl662     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
663     {
664         using namespace std;
665         wstring const name = classname_w(begin, end);
666         if(name == L"alnum")    return _ALPHA|_DIGIT;
667         if(name == L"alpha")    return _ALPHA;
668         if(name == L"blank")    return _BLANK; // this is ONLY space!!!
669         if(name == L"cntrl")    return _CONTROL;
670         if(name == L"d")        return _DIGIT;
671         if(name == L"digit")    return _DIGIT;
672         if(name == L"graph")    return _PUNCT|_ALPHA|_DIGIT;
673         if(name == L"lower")    return icase ? _LOWER|_UPPER : _LOWER;
674         if(name == L"newline")  return char_class_newline;
675         if(name == L"print")    return _BLANK|_PUNCT|_ALPHA|_DIGIT;
676         if(name == L"punct")    return _PUNCT;
677         if(name == L"s")        return _SPACE;
678         if(name == L"space")    return _SPACE;
679         if(name == L"upper")    return icase ? _UPPER|_LOWER : _UPPER;
680         if(name == L"w")        return _ALPHA|_DIGIT|char_class_underscore;
681         if(name == L"xdigit")   return _HEX;
682         return 0;
683     }
684 
isctypeboost::xpressive::detail::char_class_impl685     static bool isctype(wchar_t ch, char_class_type mask)
686     {
687         using namespace std;
688         if(0 != iswctype(ch, mask))
689         {
690             return true;
691         }
692 
693         switch(ch)
694         {
695         case L'\t': return 0 != (mask & _BLANK);
696         case L'_': return 0 != (mask & char_class_underscore);
697         case L'\n': case L'\r': case L'\f': case 0x2028u: case 0x2029u: case 0x85u:
698             return 0 != (mask & char_class_newline);
699         default:;
700         }
701 
702         return false;
703     }
704 };
705 #endif
706 
707 
708 
709 #else // unknown, use portable implementation
710 
711 
712 
713 
714 ///////////////////////////////////////////////////////////////////////////////
715 //
716 template<>
717 struct char_class_impl<char>
718 {
719     typedef int char_class_type;
720     //BOOST_STATIC_CONSTANT(int, char_class_alnum         = 0x0001);
721     BOOST_STATIC_CONSTANT(int, char_class_alpha         = 0x0002);
722     BOOST_STATIC_CONSTANT(int, char_class_blank         = 0x0004);
723     BOOST_STATIC_CONSTANT(int, char_class_cntrl         = 0x0008);
724     BOOST_STATIC_CONSTANT(int, char_class_digit         = 0x0010);
725     //BOOST_STATIC_CONSTANT(int, char_class_graph         = 0x0020);
726     BOOST_STATIC_CONSTANT(int, char_class_lower         = 0x0040);
727     //BOOST_STATIC_CONSTANT(int, char_class_print         = 0x0080);
728     BOOST_STATIC_CONSTANT(int, char_class_punct         = 0x0100);
729     BOOST_STATIC_CONSTANT(int, char_class_space         = 0x0200);
730     BOOST_STATIC_CONSTANT(int, char_class_upper         = 0x0400);
731     BOOST_STATIC_CONSTANT(int, char_class_underscore    = 0x0800);
732     BOOST_STATIC_CONSTANT(int, char_class_xdigit        = 0x1000);
733     BOOST_STATIC_CONSTANT(int, char_class_newline       = 0x2000);
734 
735     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl736     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
737     {
738         using namespace std;
739         string const name = classname_a(begin, end);
740         if(name == "alnum")     return char_class_alpha|char_class_digit;
741         if(name == "alpha")     return char_class_alpha;
742         if(name == "blank")     return char_class_blank;
743         if(name == "cntrl")     return char_class_cntrl;
744         if(name == "d")         return char_class_digit;
745         if(name == "digit")     return char_class_digit;
746         if(name == "graph")     return char_class_punct|char_class_alpha|char_class_digit;
747         if(name == "lower")     return icase ? (char_class_lower|char_class_upper) : char_class_lower;
748         if(name == "newline")   return char_class_newline;
749         if(name == "print")     return char_class_blank|char_class_punct|char_class_alpha|char_class_digit;
750         if(name == "punct")     return char_class_punct;
751         if(name == "s")         return char_class_space;
752         if(name == "space")     return char_class_space;
753         if(name == "upper")     return icase ? (char_class_upper|char_class_lower) : char_class_upper;
754         if(name == "w")         return char_class_alpha|char_class_digit|char_class_underscore;
755         if(name == "xdigit")    return char_class_xdigit;
756         return 0;
757     }
758 
isctypeboost::xpressive::detail::char_class_impl759     static bool isctype(char ch, char_class_type mask)
760     {
761         using namespace std;
762         unsigned char uch = static_cast<unsigned char>(ch);
763         return ((char_class_alpha & mask) && isalpha(uch))
764             || ((char_class_blank & mask) && (' ' == ch || '\t' == ch)) // BUGBUG
765             || ((char_class_cntrl & mask) && iscntrl(uch))
766             || ((char_class_digit & mask) && isdigit(uch))
767             || ((char_class_lower & mask) && islower(uch))
768             || ((char_class_newline & mask) && detail::isnewline(ch))
769             || ((char_class_punct & mask) && ispunct(uch))
770             || ((char_class_space & mask) && isspace(uch))
771             || ((char_class_upper & mask) && isupper(uch))
772             || ((char_class_underscore & mask) && '_' == ch)
773             || ((char_class_xdigit & mask) && isxdigit(uch))
774             ;
775     }
776 };
777 
778 #ifndef BOOST_XPRESSIVE_NO_WREGEX
779 ///////////////////////////////////////////////////////////////////////////////
780 //
781 template<>
782 struct char_class_impl<wchar_t>
783 {
784     typedef int char_class_type;
785     //BOOST_STATIC_CONSTANT(int, char_class_alnum         = 0x0001);
786     BOOST_STATIC_CONSTANT(int, char_class_alpha         = 0x0002);
787     BOOST_STATIC_CONSTANT(int, char_class_blank         = 0x0004);
788     BOOST_STATIC_CONSTANT(int, char_class_cntrl         = 0x0008);
789     BOOST_STATIC_CONSTANT(int, char_class_digit         = 0x0010);
790     //BOOST_STATIC_CONSTANT(int, char_class_graph         = 0x0020);
791     BOOST_STATIC_CONSTANT(int, char_class_lower         = 0x0040);
792     //BOOST_STATIC_CONSTANT(int, char_class_print         = 0x0080);
793     BOOST_STATIC_CONSTANT(int, char_class_punct         = 0x0100);
794     BOOST_STATIC_CONSTANT(int, char_class_space         = 0x0200);
795     BOOST_STATIC_CONSTANT(int, char_class_upper         = 0x0400);
796     BOOST_STATIC_CONSTANT(int, char_class_underscore    = 0x0800);
797     BOOST_STATIC_CONSTANT(int, char_class_xdigit        = 0x1000);
798     BOOST_STATIC_CONSTANT(int, char_class_newline       = 0x2000);
799 
800     template<typename FwdIter>
lookup_classnameboost::xpressive::detail::char_class_impl801     static char_class_type lookup_classname(FwdIter begin, FwdIter end, bool icase)
802     {
803         using namespace std;
804         wstring const name = classname_w(begin, end);
805         if(name == L"alnum")    return char_class_alpha|char_class_digit;
806         if(name == L"alpha")    return char_class_alpha;
807         if(name == L"blank")    return char_class_blank;
808         if(name == L"cntrl")    return char_class_cntrl;
809         if(name == L"d")        return char_class_digit;
810         if(name == L"digit")    return char_class_digit;
811         if(name == L"graph")    return char_class_punct|char_class_alpha|char_class_digit;
812         if(name == L"newline")  return char_class_newline;
813         if(name == L"lower")    return icase ? (char_class_lower|char_class_upper) : char_class_lower;
814         if(name == L"print")    return char_class_blank|char_class_punct|char_class_alpha|char_class_digit;
815         if(name == L"punct")    return char_class_punct;
816         if(name == L"s")        return char_class_space;
817         if(name == L"space")    return char_class_space;
818         if(name == L"upper")    return icase ? (char_class_upper|char_class_lower) : char_class_upper;
819         if(name == L"w")        return char_class_alpha|char_class_digit|char_class_underscore;
820         if(name == L"xdigit")   return char_class_xdigit;
821         return 0;
822     }
823 
isctypeboost::xpressive::detail::char_class_impl824     static bool isctype(wchar_t ch, char_class_type mask)
825     {
826         using namespace std;
827         return ((char_class_alpha & mask) && iswalpha(ch))
828             || ((char_class_blank & mask) && (L' ' == ch || L'\t' == ch)) // BUGBUG
829             || ((char_class_cntrl & mask) && iswcntrl(ch))
830             || ((char_class_digit & mask) && iswdigit(ch))
831             || ((char_class_lower & mask) && iswlower(ch))
832             || ((char_class_newline & mask) && detail::iswnewline(ch))
833             || ((char_class_punct & mask) && iswpunct(ch))
834             || ((char_class_space & mask) && iswspace(ch))
835             || ((char_class_upper & mask) && iswupper(ch))
836             || ((char_class_underscore & mask) && L'_' == ch)
837             || ((char_class_xdigit & mask) && iswxdigit(ch))
838             ;
839     }
840 };
841 #endif
842 
843 
844 #endif
845 
846 
847 }}} // namespace boost::xpressive::detail
848 
849 #endif
850