basic_chset.ipp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Joel de Guzman
  3. Copyright (c) 2001-2003 Daniel Nuffer
  4. http://spirit.sourceforge.net/
  5. Use, modification and distribution is subject to the Boost Software
  6. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #ifndef BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
  10. #define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include <bitset>
  13. #include <boost/xpressive/detail/utility/chset/basic_chset.hpp>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. namespace boost { namespace xpressive { namespace detail
  16. {
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //
  19. // basic_chset: character set implementation
  20. //
  21. ///////////////////////////////////////////////////////////////////////////////
  22. template<typename Char>
  23. inline basic_chset<Char>::basic_chset()
  24. {
  25. }
  26. //////////////////////////////////
  27. template<typename Char>
  28. inline basic_chset<Char>::basic_chset(basic_chset const &arg)
  29. : rr_(arg.rr_)
  30. {
  31. }
  32. //////////////////////////////////
  33. template<typename Char>
  34. inline bool basic_chset<Char>::empty() const
  35. {
  36. return this->rr_.empty();
  37. }
  38. //////////////////////////////////
  39. template<typename Char>
  40. template<typename Traits>
  41. inline bool basic_chset<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
  42. {
  43. return this->rr_.test(v);
  44. }
  45. //////////////////////////////////
  46. template<typename Char>
  47. template<typename Traits>
  48. inline bool basic_chset<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
  49. {
  50. return this->rr_.test(v, tr);
  51. }
  52. //////////////////////////////////
  53. template<typename Char>
  54. inline void basic_chset<Char>::set(Char from, Char to)
  55. {
  56. this->rr_.set(range<Char>(from, to));
  57. }
  58. //////////////////////////////////
  59. template<typename Char>
  60. template<typename Traits>
  61. inline void basic_chset<Char>::set(Char from, Char to, Traits const &)
  62. {
  63. this->rr_.set(range<Char>(from, to));
  64. }
  65. //////////////////////////////////
  66. template<typename Char>
  67. inline void basic_chset<Char>::set(Char c)
  68. {
  69. this->rr_.set(range<Char>(c, c));
  70. }
  71. //////////////////////////////////
  72. template<typename Char>
  73. template<typename Traits>
  74. inline void basic_chset<Char>::set(Char c, Traits const &)
  75. {
  76. this->rr_.set(range<Char>(c, c));
  77. }
  78. //////////////////////////////////
  79. template<typename Char>
  80. inline void basic_chset<Char>::clear(Char c)
  81. {
  82. this->rr_.clear(range<Char>(c, c));
  83. }
  84. //////////////////////////////////
  85. template<typename Char>
  86. template<typename Traits>
  87. inline void basic_chset<Char>::clear(Char c, Traits const &)
  88. {
  89. this->rr_.clear(range<Char>(c, c));
  90. }
  91. //////////////////////////////////
  92. template<typename Char>
  93. inline void basic_chset<Char>::clear(Char from, Char to)
  94. {
  95. this->rr_.clear(range<Char>(from, to));
  96. }
  97. //////////////////////////////////
  98. template<typename Char>
  99. template<typename Traits>
  100. inline void basic_chset<Char>::clear(Char from, Char to, Traits const &)
  101. {
  102. this->rr_.clear(range<Char>(from, to));
  103. }
  104. //////////////////////////////////
  105. template<typename Char>
  106. inline void basic_chset<Char>::clear()
  107. {
  108. this->rr_.clear();
  109. }
  110. /////////////////////////////////
  111. template<typename Char>
  112. inline void basic_chset<Char>::inverse()
  113. {
  114. // BUGBUG is this right? Does this handle icase correctly?
  115. basic_chset<Char> inv;
  116. inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
  117. inv -= *this;
  118. this->swap(inv);
  119. }
  120. /////////////////////////////////
  121. template<typename Char>
  122. inline void basic_chset<Char>::swap(basic_chset<Char> &that)
  123. {
  124. this->rr_.swap(that.rr_);
  125. }
  126. /////////////////////////////////
  127. template<typename Char>
  128. inline basic_chset<Char> &
  129. basic_chset<Char>::operator |=(basic_chset<Char> const &that)
  130. {
  131. typedef typename range_run<Char>::const_iterator const_iterator;
  132. for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
  133. {
  134. this->rr_.set(*iter);
  135. }
  136. return *this;
  137. }
  138. /////////////////////////////////
  139. template<typename Char>
  140. inline basic_chset<Char> &
  141. basic_chset<Char>::operator &=(basic_chset<Char> const &that)
  142. {
  143. basic_chset<Char> inv;
  144. inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
  145. inv -= that;
  146. *this -= inv;
  147. return *this;
  148. }
  149. /////////////////////////////////
  150. template<typename Char>
  151. inline basic_chset<Char> &
  152. basic_chset<Char>::operator -=(basic_chset<Char> const &that)
  153. {
  154. typedef typename range_run<Char>::const_iterator const_iterator;
  155. for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
  156. {
  157. this->rr_.clear(*iter);
  158. }
  159. return *this;
  160. }
  161. /////////////////////////////////
  162. template<typename Char>
  163. inline basic_chset<Char> &
  164. basic_chset<Char>::operator ^=(basic_chset<Char> const &that)
  165. {
  166. basic_chset bma = that;
  167. bma -= *this;
  168. *this -= that;
  169. *this |= bma;
  170. return *this;
  171. }
  172. #if(CHAR_BIT == 8)
  173. ///////////////////////////////////////////////////////////////////////////////
  174. //
  175. // basic_chset: specializations for 8 bit chars using std::bitset
  176. //
  177. ///////////////////////////////////////////////////////////////////////////////
  178. template<typename Char>
  179. inline basic_chset_8bit<Char>::basic_chset_8bit()
  180. {
  181. }
  182. /////////////////////////////////
  183. template<typename Char>
  184. inline basic_chset_8bit<Char>::basic_chset_8bit(basic_chset_8bit<Char> const &arg)
  185. : bset_(arg.bset_)
  186. {
  187. }
  188. /////////////////////////////////
  189. template<typename Char>
  190. inline bool basic_chset_8bit<Char>::empty() const
  191. {
  192. return !this->bset_.any();
  193. }
  194. /////////////////////////////////
  195. template<typename Char>
  196. template<typename Traits>
  197. inline bool basic_chset_8bit<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
  198. {
  199. return this->bset_.test((unsigned char)v);
  200. }
  201. /////////////////////////////////
  202. template<typename Char>
  203. template<typename Traits>
  204. inline bool basic_chset_8bit<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
  205. {
  206. return this->bset_.test((unsigned char)tr.translate_nocase(v));
  207. }
  208. /////////////////////////////////
  209. template<typename Char>
  210. inline void basic_chset_8bit<Char>::set(Char from, Char to)
  211. {
  212. for(int i = from; i <= to; ++i)
  213. {
  214. this->bset_.set((unsigned char)i);
  215. }
  216. }
  217. /////////////////////////////////
  218. template<typename Char>
  219. template<typename Traits>
  220. inline void basic_chset_8bit<Char>::set(Char from, Char to, Traits const &tr)
  221. {
  222. for(int i = from; i <= to; ++i)
  223. {
  224. this->bset_.set((unsigned char)tr.translate_nocase((Char)i));
  225. }
  226. }
  227. /////////////////////////////////
  228. template<typename Char>
  229. inline void basic_chset_8bit<Char>::set(Char c)
  230. {
  231. this->bset_.set((unsigned char)c);
  232. }
  233. /////////////////////////////////
  234. template<typename Char>
  235. template<typename Traits>
  236. inline void basic_chset_8bit<Char>::set(Char c, Traits const &tr)
  237. {
  238. this->bset_.set((unsigned char)tr.translate_nocase(c));
  239. }
  240. /////////////////////////////////
  241. template<typename Char>
  242. inline void basic_chset_8bit<Char>::clear(Char from, Char to)
  243. {
  244. for(int i = from; i <= to; ++i)
  245. {
  246. this->bset_.reset((unsigned char)i);
  247. }
  248. }
  249. /////////////////////////////////
  250. template<typename Char>
  251. template<typename Traits>
  252. inline void basic_chset_8bit<Char>::clear(Char from, Char to, Traits const &tr)
  253. {
  254. for(int i = from; i <= to; ++i)
  255. {
  256. this->bset_.reset((unsigned char)tr.translate_nocase((Char)i));
  257. }
  258. }
  259. /////////////////////////////////
  260. template<typename Char>
  261. inline void basic_chset_8bit<Char>::clear(Char c)
  262. {
  263. this->bset_.reset((unsigned char)c);
  264. }
  265. /////////////////////////////////
  266. template<typename Char>
  267. template<typename Traits>
  268. inline void basic_chset_8bit<Char>::clear(Char c, Traits const &tr)
  269. {
  270. this->bset_.reset((unsigned char)tr.tranlsate_nocase(c));
  271. }
  272. /////////////////////////////////
  273. template<typename Char>
  274. inline void basic_chset_8bit<Char>::clear()
  275. {
  276. this->bset_.reset();
  277. }
  278. /////////////////////////////////
  279. template<typename Char>
  280. inline void basic_chset_8bit<Char>::inverse()
  281. {
  282. this->bset_.flip();
  283. }
  284. /////////////////////////////////
  285. template<typename Char>
  286. inline void basic_chset_8bit<Char>::swap(basic_chset_8bit<Char> &that)
  287. {
  288. std::swap(this->bset_, that.bset_);
  289. }
  290. /////////////////////////////////
  291. template<typename Char>
  292. inline basic_chset_8bit<Char> &
  293. basic_chset_8bit<Char>::operator |=(basic_chset_8bit<Char> const &that)
  294. {
  295. this->bset_ |= that.bset_;
  296. return *this;
  297. }
  298. /////////////////////////////////
  299. template<typename Char>
  300. inline basic_chset_8bit<Char> &
  301. basic_chset_8bit<Char>::operator &=(basic_chset_8bit<Char> const &that)
  302. {
  303. this->bset_ &= that.bset_;
  304. return *this;
  305. }
  306. /////////////////////////////////
  307. template<typename Char>
  308. inline basic_chset_8bit<Char> &
  309. basic_chset_8bit<Char>::operator -=(basic_chset_8bit<Char> const &that)
  310. {
  311. this->bset_ &= ~that.bset_;
  312. return *this;
  313. }
  314. /////////////////////////////////
  315. template<typename Char>
  316. inline basic_chset_8bit<Char> &
  317. basic_chset_8bit<Char>::operator ^=(basic_chset_8bit<Char> const &that)
  318. {
  319. this->bset_ ^= that.bset_;
  320. return *this;
  321. }
  322. template<typename Char>
  323. inline std::bitset<256> const &
  324. basic_chset_8bit<Char>::base() const
  325. {
  326. return this->bset_;
  327. }
  328. #endif // if(CHAR_BIT == 8)
  329. ///////////////////////////////////////////////////////////////////////////////
  330. // helpers
  331. template<typename Char, typename Traits>
  332. inline void set_char(basic_chset<Char> &chset, Char ch, Traits const &tr, bool icase)
  333. {
  334. icase ? chset.set(ch, tr) : chset.set(ch);
  335. }
  336. template<typename Char, typename Traits>
  337. inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase)
  338. {
  339. icase ? chset.set(from, to, tr) : chset.set(from, to);
  340. }
  341. template<typename Char, typename Traits>
  342. inline void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &tr)
  343. {
  344. BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(Char));
  345. for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
  346. {
  347. typedef typename std::char_traits<Char>::int_type int_type;
  348. Char ch = std::char_traits<Char>::to_char_type(static_cast<int_type>(i));
  349. if(no != tr.isctype(ch, char_class))
  350. {
  351. chset.set(ch);
  352. }
  353. }
  354. }
  355. }}} // namespace boost::xpressive::detail
  356. #endif