/Src/Dependencies/Boost/boost/spirit/home/qi/string/symbols.hpp

http://hadesmem.googlecode.com/ · C++ Header · 414 lines · 346 code · 54 blank · 14 comment · 7 complexity · 223dea5e84f17f03771f7d35fa11301f MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM)
  7. #define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/domain.hpp>
  12. #include <boost/spirit/home/qi/skip_over.hpp>
  13. #include <boost/spirit/home/qi/string/tst.hpp>
  14. #include <boost/spirit/home/qi/reference.hpp>
  15. #include <boost/spirit/home/qi/meta_compiler.hpp>
  16. #include <boost/spirit/home/qi/detail/assign_to.hpp>
  17. #include <boost/spirit/home/qi/parser.hpp>
  18. #include <boost/spirit/home/support/detail/get_encoding.hpp>
  19. #include <boost/spirit/home/support/modify.hpp>
  20. #include <boost/spirit/home/support/info.hpp>
  21. #include <boost/spirit/home/support/unused.hpp>
  22. #include <boost/spirit/home/support/string_traits.hpp>
  23. #include <boost/fusion/include/at.hpp>
  24. #include <boost/range.hpp>
  25. #include <boost/type_traits/add_reference.hpp>
  26. #include <boost/shared_ptr.hpp>
  27. #if defined(BOOST_MSVC)
  28. # pragma warning(push)
  29. # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
  30. #endif
  31. namespace boost { namespace spirit { namespace qi
  32. {
  33. template <
  34. typename Char = char
  35. , typename T = unused_type
  36. , typename Lookup = tst<Char, T>
  37. , typename Filter = tst_pass_through>
  38. struct symbols
  39. : proto::extends<
  40. typename proto::terminal<
  41. reference<symbols<Char, T, Lookup, Filter> >
  42. >::type
  43. , symbols<Char, T, Lookup, Filter>
  44. >
  45. , primitive_parser<symbols<Char, T, Lookup, Filter> >
  46. {
  47. typedef Char char_type; // the character type
  48. typedef T value_type; // the value associated with each entry
  49. typedef symbols<Char, T, Lookup, Filter> this_type;
  50. typedef reference<this_type> reference_;
  51. typedef typename proto::terminal<reference_>::type terminal;
  52. typedef proto::extends<terminal, this_type> base_type;
  53. template <typename Context, typename Iterator>
  54. struct attribute
  55. {
  56. typedef value_type type;
  57. };
  58. symbols(std::string const& name = "symbols")
  59. : base_type(terminal::make(reference_(*this)))
  60. , add(*this)
  61. , remove(*this)
  62. , lookup(new Lookup())
  63. , name_(name)
  64. {
  65. }
  66. symbols(symbols const& syms)
  67. : base_type(terminal::make(reference_(*this)))
  68. , add(*this)
  69. , remove(*this)
  70. , lookup(syms.lookup)
  71. , name_(syms.name_)
  72. {
  73. }
  74. template <typename Filter_>
  75. symbols(symbols<Char, T, Lookup, Filter_> const& syms)
  76. : base_type(terminal::make(reference_(*this)))
  77. , add(*this)
  78. , remove(*this)
  79. , lookup(syms.lookup)
  80. , name_(syms.name_)
  81. {
  82. }
  83. template <typename Symbols>
  84. symbols(Symbols const& syms, std::string const& name = "symbols")
  85. : base_type(terminal::make(reference_(*this)))
  86. , add(*this)
  87. , remove(*this)
  88. , lookup(new Lookup())
  89. , name_(name)
  90. {
  91. typename range_const_iterator<Symbols>::type si = boost::begin(syms);
  92. while (si != boost::end(syms))
  93. add(*si++);
  94. }
  95. template <typename Symbols, typename Data>
  96. symbols(Symbols const& syms, Data const& data
  97. , std::string const& name = "symbols")
  98. : base_type(terminal::make(reference_(*this)))
  99. , add(*this)
  100. , remove(*this)
  101. , lookup(new Lookup())
  102. , name_(name)
  103. {
  104. typename range_const_iterator<Symbols>::type si = boost::begin(syms);
  105. typename range_const_iterator<Data>::type di = boost::begin(data);
  106. while (si != boost::end(syms))
  107. add(*si++, *di++);
  108. }
  109. symbols&
  110. operator=(symbols const& rhs)
  111. {
  112. name_ = rhs.name_;
  113. *lookup = *rhs.lookup;
  114. return *this;
  115. }
  116. template <typename Filter_>
  117. symbols&
  118. operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
  119. {
  120. name_ = rhs.name_;
  121. *lookup = *rhs.lookup;
  122. return *this;
  123. }
  124. void clear()
  125. {
  126. lookup->clear();
  127. }
  128. struct adder;
  129. struct remover;
  130. template <typename Str>
  131. adder const&
  132. operator=(Str const& str)
  133. {
  134. lookup->clear();
  135. return add(str);
  136. }
  137. template <typename Str>
  138. friend adder const&
  139. operator+=(symbols& sym, Str const& str)
  140. {
  141. return sym.add(str);
  142. }
  143. template <typename Str>
  144. friend remover const&
  145. operator-=(symbols& sym, Str const& str)
  146. {
  147. return sym.remove(str);
  148. }
  149. // non-const version needed to suppress proto's += kicking in
  150. template <typename Str>
  151. friend adder const&
  152. operator+=(symbols& sym, Str& str)
  153. {
  154. return sym.add(str);
  155. }
  156. // non-const version needed to suppress proto's -= kicking in
  157. template <typename Str>
  158. friend remover const&
  159. operator-=(symbols& sym, Str& str)
  160. {
  161. return sym.remove(str);
  162. }
  163. template <typename F>
  164. void for_each(F f) const
  165. {
  166. lookup->for_each(f);
  167. }
  168. template <typename Str>
  169. value_type& at(Str const& str)
  170. {
  171. return *lookup->add(traits::get_begin<Char>(str)
  172. , traits::get_end<Char>(str), T());
  173. }
  174. template <typename Iterator>
  175. value_type* prefix_find(Iterator& first, Iterator const& last)
  176. {
  177. return lookup->find(first, last, Filter());
  178. }
  179. template <typename Iterator>
  180. value_type const* prefix_find(Iterator& first, Iterator const& last) const
  181. {
  182. return lookup->find(first, last, Filter());
  183. }
  184. template <typename Str>
  185. value_type* find(Str const& str)
  186. {
  187. return find_impl(traits::get_begin<Char>(str)
  188. , traits::get_end<Char>(str));
  189. }
  190. template <typename Str>
  191. value_type const* find(Str const& str) const
  192. {
  193. return find_impl(traits::get_begin<Char>(str)
  194. , traits::get_end<Char>(str));
  195. }
  196. private:
  197. template <typename Iterator>
  198. value_type* find_impl(Iterator begin, Iterator end)
  199. {
  200. value_type* r = lookup->find(begin, end, Filter());
  201. return begin == end ? r : 0;
  202. }
  203. template <typename Iterator>
  204. value_type const* find_impl(Iterator begin, Iterator end) const
  205. {
  206. value_type const* r = lookup->find(begin, end, Filter());
  207. return begin == end ? r : 0;
  208. }
  209. public:
  210. template <typename Iterator, typename Context
  211. , typename Skipper, typename Attribute>
  212. bool parse(Iterator& first, Iterator const& last
  213. , Context& /*context*/, Skipper const& skipper, Attribute& attr) const
  214. {
  215. qi::skip_over(first, last, skipper);
  216. if (value_type* val_ptr
  217. = lookup->find(first, last, Filter()))
  218. {
  219. spirit::traits::assign_to(*val_ptr, attr);
  220. return true;
  221. }
  222. return false;
  223. }
  224. template <typename Context>
  225. info what(Context& /*context*/) const
  226. {
  227. return info(name_);
  228. }
  229. void name(std::string const &str)
  230. {
  231. name_ = str;
  232. }
  233. std::string const &name() const
  234. {
  235. return name_;
  236. }
  237. struct adder
  238. {
  239. template <typename, typename = unused_type, typename = unused_type>
  240. struct result { typedef adder const& type; };
  241. adder(symbols& sym)
  242. : sym(sym)
  243. {
  244. }
  245. template <typename Iterator>
  246. adder const&
  247. operator()(Iterator const& first, Iterator const& last, T const& val) const
  248. {
  249. sym.lookup->add(first, last, val);
  250. return *this;
  251. }
  252. template <typename Str>
  253. adder const&
  254. operator()(Str const& s, T const& val = T()) const
  255. {
  256. sym.lookup->add(traits::get_begin<Char>(s)
  257. , traits::get_end<Char>(s), val);
  258. return *this;
  259. }
  260. template <typename Str>
  261. adder const&
  262. operator,(Str const& s) const
  263. {
  264. sym.lookup->add(traits::get_begin<Char>(s)
  265. , traits::get_end<Char>(s), T());
  266. return *this;
  267. }
  268. symbols& sym;
  269. private:
  270. // silence MSVC warning C4512: assignment operator could not be generated
  271. adder& operator= (adder const&);
  272. };
  273. struct remover
  274. {
  275. template <typename, typename = unused_type, typename = unused_type>
  276. struct result { typedef remover const& type; };
  277. remover(symbols& sym)
  278. : sym(sym)
  279. {
  280. }
  281. template <typename Iterator>
  282. remover const&
  283. operator()(Iterator const& first, Iterator const& last) const
  284. {
  285. sym.lookup->remove(first, last);
  286. return *this;
  287. }
  288. template <typename Str>
  289. remover const&
  290. operator()(Str const& s) const
  291. {
  292. sym.lookup->remove(traits::get_begin<Char>(s)
  293. , traits::get_end<Char>(s));
  294. return *this;
  295. }
  296. template <typename Str>
  297. remover const&
  298. operator,(Str const& s) const
  299. {
  300. sym.lookup->remove(traits::get_begin<Char>(s)
  301. , traits::get_end<Char>(s));
  302. return *this;
  303. }
  304. symbols& sym;
  305. private:
  306. // silence MSVC warning C4512: assignment operator could not be generated
  307. remover& operator= (remover const&);
  308. };
  309. adder add;
  310. remover remove;
  311. shared_ptr<Lookup> lookup;
  312. std::string name_;
  313. };
  314. ///////////////////////////////////////////////////////////////////////////
  315. // Parser generators: make_xxx function (objects)
  316. ///////////////////////////////////////////////////////////////////////////
  317. template <typename Char, typename T, typename Lookup
  318. , typename Filter, typename Modifiers>
  319. struct make_primitive<reference<symbols<Char, T, Lookup, Filter> >, Modifiers>
  320. {
  321. template <typename CharEncoding>
  322. struct no_case_filter
  323. {
  324. Char operator()(Char ch) const
  325. {
  326. return static_cast<Char>(CharEncoding::tolower(ch));
  327. }
  328. };
  329. typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
  330. typedef reference<symbols<Char, T, Lookup, Filter> > reference_;
  331. typedef no_case_filter<
  332. typename spirit::detail::get_encoding_with_case<
  333. Modifiers
  334. , char_encoding::standard
  335. , no_case::value>::type>
  336. nc_filter;
  337. typedef typename mpl::if_<
  338. no_case
  339. , symbols<Char, T, Lookup, nc_filter>
  340. , reference_>::type
  341. result_type;
  342. result_type operator()(reference_ ref, unused_type) const
  343. {
  344. return result_type(ref.ref.get());
  345. }
  346. };
  347. }}}
  348. namespace boost { namespace spirit { namespace traits
  349. {
  350. ///////////////////////////////////////////////////////////////////////////
  351. template <typename Char, typename T, typename Lookup, typename Filter
  352. , typename Attr, typename Context, typename Iterator>
  353. struct handles_container<qi::symbols<Char, T, Lookup, Filter>, Attr, Context, Iterator>
  354. : traits::is_container<Attr> {};
  355. }}}
  356. #if defined(BOOST_MSVC)
  357. # pragma warning(pop)
  358. #endif
  359. #endif