/Src/Dependencies/Boost/boost/spirit/home/qi/numeric/int.hpp

http://hadesmem.googlecode.com/ · C++ Header · 407 lines · 298 code · 55 blank · 54 comment · 17 complexity · ca8ec8dafd902ec22136d646d9daf5e3 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2011 Bryce Lelbach
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #if !defined(BOOST_SPIRIT_INT_APR_17_2006_0830AM)
  8. #define BOOST_SPIRIT_INT_APR_17_2006_0830AM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/spirit/home/qi/skip_over.hpp>
  13. #include <boost/spirit/home/qi/detail/enable_lit.hpp>
  14. #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
  15. #include <boost/spirit/home/qi/meta_compiler.hpp>
  16. #include <boost/spirit/home/qi/parser.hpp>
  17. #include <boost/spirit/home/support/common_terminals.hpp>
  18. #include <boost/spirit/home/support/info.hpp>
  19. #include <boost/mpl/assert.hpp>
  20. #include <boost/type_traits/is_same.hpp>
  21. namespace boost { namespace spirit
  22. {
  23. namespace tag
  24. {
  25. template <typename T, unsigned Radix, unsigned MinDigits
  26. , int MaxDigits>
  27. struct int_parser {};
  28. }
  29. namespace qi
  30. {
  31. ///////////////////////////////////////////////////////////////////////
  32. // This one is the class that the user can instantiate directly in
  33. // order to create a customized int parser
  34. template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
  35. , int MaxDigits = -1>
  36. struct int_parser
  37. : spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
  38. {};
  39. }
  40. ///////////////////////////////////////////////////////////////////////////
  41. // Enablers
  42. ///////////////////////////////////////////////////////////////////////////
  43. //[primitive_parsers_enable_short
  44. template <> // enables short_
  45. struct use_terminal<qi::domain, tag::short_> : mpl::true_ {};
  46. //]
  47. template <typename A0> // enables lit(n)
  48. struct use_terminal<qi::domain
  49. , terminal_ex<tag::lit, fusion::vector1<A0> >
  50. , typename enable_if<is_same<A0, signed short> >::type>
  51. : mpl::true_ {};
  52. template <typename A0> // enables short_(n)
  53. struct use_terminal<qi::domain
  54. , terminal_ex<tag::short_, fusion::vector1<A0> > >
  55. : is_arithmetic<A0> {};
  56. template <> // enables *lazy* short_(n)
  57. struct use_lazy_terminal<qi::domain, tag::short_, 1> : mpl::true_ {};
  58. ///////////////////////////////////////////////////////////////////////////
  59. //[primitive_parsers_enable_int
  60. template <> // enables int_
  61. struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
  62. //]
  63. template <typename A0> // enables lit(n)
  64. struct use_terminal<qi::domain
  65. , terminal_ex<tag::lit, fusion::vector1<A0> >
  66. , typename enable_if<is_same<A0, signed> >::type>
  67. : mpl::true_ {};
  68. template <typename A0> // enables int_(n)
  69. struct use_terminal<qi::domain
  70. , terminal_ex<tag::int_, fusion::vector1<A0> > >
  71. : is_arithmetic<A0> {};
  72. template <> // enables *lazy* int_(n)
  73. struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
  74. ///////////////////////////////////////////////////////////////////////////
  75. //[primitive_parsers_enable_long
  76. template <> // enables long_
  77. struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
  78. //]
  79. template <typename A0> // enables lit(n)
  80. struct use_terminal<qi::domain
  81. , terminal_ex<tag::lit, fusion::vector1<A0> >
  82. , typename enable_if<is_same<A0, signed long> >::type>
  83. : mpl::true_ {};
  84. template <typename A0> // enables long_(n)
  85. struct use_terminal<qi::domain
  86. , terminal_ex<tag::long_, fusion::vector1<A0> > >
  87. : is_arithmetic<A0> {};
  88. template <> // enables *lazy* long_(n)
  89. struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
  90. ///////////////////////////////////////////////////////////////////////////
  91. #ifdef BOOST_HAS_LONG_LONG
  92. //[primitive_parsers_enable_long_long
  93. template <> // enables long_long
  94. struct use_terminal<qi::domain, tag::long_long> : mpl::true_ {};
  95. //]
  96. template <typename A0> // enables lit(n)
  97. struct use_terminal<qi::domain
  98. , terminal_ex<tag::lit, fusion::vector1<A0> >
  99. , typename enable_if<is_same<A0, boost::long_long_type> >::type>
  100. : mpl::true_ {};
  101. template <typename A0> // enables long_long(n)
  102. struct use_terminal<qi::domain
  103. , terminal_ex<tag::long_long, fusion::vector1<A0> > >
  104. : is_arithmetic<A0> {};
  105. template <> // enables *lazy* long_long(n)
  106. struct use_lazy_terminal<qi::domain, tag::long_long, 1> : mpl::true_ {};
  107. #endif
  108. ///////////////////////////////////////////////////////////////////////////
  109. // enables any custom int_parser
  110. template <typename T, unsigned Radix, unsigned MinDigits
  111. , int MaxDigits>
  112. struct use_terminal<qi::domain
  113. , tag::int_parser<T, Radix, MinDigits, MaxDigits> >
  114. : mpl::true_ {};
  115. // enables any custom int_parser(n)
  116. template <typename T, unsigned Radix, unsigned MinDigits
  117. , int MaxDigits, typename A0>
  118. struct use_terminal<qi::domain
  119. , terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
  120. , fusion::vector1<A0> >
  121. > : mpl::true_ {};
  122. // enables *lazy* custom int_parser(n)
  123. template <typename T, unsigned Radix, unsigned MinDigits
  124. , int MaxDigits>
  125. struct use_lazy_terminal<qi::domain
  126. , tag::int_parser<T, Radix, MinDigits, MaxDigits>, 1
  127. > : mpl::true_ {};
  128. }}
  129. namespace boost { namespace spirit { namespace qi
  130. {
  131. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  132. using spirit::short_;
  133. using spirit::int_;
  134. using spirit::long_;
  135. #ifdef BOOST_HAS_LONG_LONG
  136. using spirit::long_long;
  137. #endif
  138. using spirit::lit; // lit(1) is equivalent to 1
  139. #endif
  140. using spirit::short_type;
  141. using spirit::int_type;
  142. using spirit::long_type;
  143. using spirit::lit_type;
  144. #ifdef BOOST_HAS_LONG_LONG
  145. using spirit::long_long_type;
  146. #endif
  147. using spirit::lit_type;
  148. ///////////////////////////////////////////////////////////////////////////
  149. // This is the actual int parser
  150. ///////////////////////////////////////////////////////////////////////////
  151. //[primitive_parsers_int_parser
  152. template <
  153. typename T
  154. , unsigned Radix = 10
  155. , unsigned MinDigits = 1
  156. , int MaxDigits = -1>
  157. struct any_int_parser
  158. : primitive_parser<any_int_parser<T, Radix, MinDigits, MaxDigits> >
  159. {
  160. // check template parameter 'Radix' for validity
  161. BOOST_SPIRIT_ASSERT_MSG(
  162. Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
  163. not_supported_radix, ());
  164. template <typename Context, typename Iterator>
  165. struct attribute
  166. {
  167. typedef T type;
  168. };
  169. template <typename Iterator, typename Context
  170. , typename Skipper, typename Attribute>
  171. bool parse(Iterator& first, Iterator const& last
  172. , Context& /*context*/, Skipper const& skipper
  173. , Attribute& attr) const
  174. {
  175. typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
  176. qi::skip_over(first, last, skipper);
  177. return extract::call(first, last, attr);
  178. }
  179. template <typename Context>
  180. info what(Context& /*context*/) const
  181. {
  182. return info("integer");
  183. }
  184. };
  185. //]
  186. template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
  187. , int MaxDigits = -1, bool no_attribute = true>
  188. struct literal_int_parser
  189. : primitive_parser<literal_int_parser<T, Radix, MinDigits, MaxDigits
  190. , no_attribute> >
  191. {
  192. // check template parameter 'Radix' for validity
  193. BOOST_SPIRIT_ASSERT_MSG(
  194. Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
  195. not_supported_radix, ());
  196. template <typename Value>
  197. literal_int_parser(Value const& n) : n_(n) {}
  198. template <typename Context, typename Iterator>
  199. struct attribute
  200. : mpl::if_c<no_attribute, unused_type, T>
  201. {};
  202. template <typename Iterator, typename Context
  203. , typename Skipper, typename Attribute>
  204. bool parse(Iterator& first, Iterator const& last
  205. , Context& /*context*/, Skipper const& skipper
  206. , Attribute& attr) const
  207. {
  208. typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
  209. qi::skip_over(first, last, skipper);
  210. Iterator save = first;
  211. T attr_;
  212. if (extract::call(first, last, attr_) && (attr_ == n_))
  213. {
  214. traits::assign_to(attr_, attr);
  215. return true;
  216. }
  217. first = save;
  218. return false;
  219. }
  220. template <typename Context>
  221. info what(Context& /*context*/) const
  222. {
  223. return info("integer");
  224. }
  225. T n_;
  226. };
  227. ///////////////////////////////////////////////////////////////////////////
  228. // Parser generators: make_xxx function (objects)
  229. ///////////////////////////////////////////////////////////////////////////
  230. //[primitive_parsers_make_int
  231. template <
  232. typename T
  233. , unsigned Radix = 10
  234. , unsigned MinDigits = 1
  235. , int MaxDigits = -1>
  236. struct make_int
  237. {
  238. typedef any_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
  239. result_type operator()(unused_type, unused_type) const
  240. {
  241. return result_type();
  242. }
  243. };
  244. //]
  245. template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
  246. , int MaxDigits = -1>
  247. struct make_direct_int
  248. {
  249. typedef literal_int_parser<T, Radix, MinDigits, MaxDigits, false>
  250. result_type;
  251. template <typename Terminal>
  252. result_type operator()(Terminal const& term, unused_type) const
  253. {
  254. return result_type(fusion::at_c<0>(term.args));
  255. }
  256. };
  257. template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
  258. , int MaxDigits = -1>
  259. struct make_literal_int
  260. {
  261. typedef literal_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
  262. template <typename Terminal>
  263. result_type operator()(Terminal const& term, unused_type) const
  264. {
  265. return result_type(fusion::at_c<0>(term.args));
  266. }
  267. };
  268. ///////////////////////////////////////////////////////////////////////////
  269. template <typename Modifiers, typename A0>
  270. struct make_primitive<
  271. terminal_ex<tag::lit, fusion::vector1<A0> >
  272. , Modifiers, typename enable_if<is_same<A0, signed short> >::type>
  273. : make_literal_int<signed short> {};
  274. template <typename Modifiers, typename A0>
  275. struct make_primitive<
  276. terminal_ex<tag::lit, fusion::vector1<A0> >
  277. , Modifiers, typename enable_if<is_same<A0, signed> >::type>
  278. : make_literal_int<signed> {};
  279. template <typename Modifiers, typename A0>
  280. struct make_primitive<
  281. terminal_ex<tag::lit, fusion::vector1<A0> >
  282. , Modifiers, typename enable_if<is_same<A0, signed long> >::type>
  283. : make_literal_int<signed long> {};
  284. #ifdef BOOST_HAS_LONG_LONG
  285. template <typename Modifiers, typename A0>
  286. struct make_primitive<
  287. terminal_ex<tag::lit, fusion::vector1<A0> >
  288. , Modifiers, typename enable_if<is_same<A0, boost::long_long_type> >::type>
  289. : make_literal_int<boost::long_long_type> {};
  290. #endif
  291. ///////////////////////////////////////////////////////////////////////////
  292. template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
  293. , typename Modifiers>
  294. struct make_primitive<
  295. tag::int_parser<T, Radix, MinDigits, MaxDigits>
  296. , Modifiers>
  297. : make_int<T, Radix, MinDigits, MaxDigits> {};
  298. template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
  299. , typename A0, typename Modifiers>
  300. struct make_primitive<
  301. terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
  302. , fusion::vector1<A0> >, Modifiers>
  303. : make_direct_int<T, Radix, MinDigits, MaxDigits> {};
  304. ///////////////////////////////////////////////////////////////////////////
  305. //[primitive_parsers_short_primitive
  306. template <typename Modifiers>
  307. struct make_primitive<tag::short_, Modifiers>
  308. : make_int<short> {};
  309. //]
  310. template <typename Modifiers, typename A0>
  311. struct make_primitive<
  312. terminal_ex<tag::short_
  313. , fusion::vector1<A0> > , Modifiers>
  314. : make_direct_int<short> {};
  315. ///////////////////////////////////////////////////////////////////////////
  316. //[primitive_parsers_int_primitive
  317. template <typename Modifiers>
  318. struct make_primitive<tag::int_, Modifiers>
  319. : make_int<int> {};
  320. //]
  321. template <typename Modifiers, typename A0>
  322. struct make_primitive<
  323. terminal_ex<tag::int_
  324. , fusion::vector1<A0> > , Modifiers>
  325. : make_direct_int<int> {};
  326. ///////////////////////////////////////////////////////////////////////////
  327. //[primitive_parsers_long_primitive
  328. template <typename Modifiers>
  329. struct make_primitive<tag::long_, Modifiers>
  330. : make_int<long> {};
  331. //]
  332. template <typename Modifiers, typename A0>
  333. struct make_primitive<
  334. terminal_ex<tag::long_
  335. , fusion::vector1<A0> > , Modifiers>
  336. : make_direct_int<long> {};
  337. ///////////////////////////////////////////////////////////////////////////
  338. #ifdef BOOST_HAS_LONG_LONG
  339. //[primitive_parsers_long_long_primitive
  340. template <typename Modifiers>
  341. struct make_primitive<tag::long_long, Modifiers>
  342. : make_int<boost::long_long_type> {};
  343. //]
  344. template <typename Modifiers, typename A0>
  345. struct make_primitive<
  346. terminal_ex<tag::long_long
  347. , fusion::vector1<A0> > , Modifiers>
  348. : make_direct_int<boost::long_long_type> {};
  349. #endif
  350. }}}
  351. #endif