c_ctype.hpp 33 KB

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