Advertisement
Guest User

Untitled

a guest
Apr 24th, 2014
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.89 KB | None | 0 0
  1. integer %=
  2. attr_cast<int,std::string>(
  3. lexeme[
  4. -(char_('+') | char_('-')) >>
  5. char_("1-9") >> *char_("0-9")
  6. ]
  7. )
  8. ;
  9.  
  10. template <>
  11. struct transform_attribute<int, std::string, qi::domain>
  12. {
  13. // input type
  14. typedef std::string& type;
  15.  
  16. static std::string pre(int & d) {
  17. return "";
  18. }
  19. static void post(int & val, const type attr) {
  20. val = boost::lexical_cast<int>(attr);
  21. }
  22. static void fail(int &) {}
  23. };
  24.  
  25. integer %= qi::int_; // Job Done
  26.  
  27. bool ok = parse(f, l,
  28. (matches['-'] | -lit('+') >> attr(false)) [ phx::ref(negative) = _1 ] >> // sign
  29. eps [ _val = 0 ] >>
  30. +digit [ _val *= 10, _val += (_1 - '0') ],
  31. parsed);
  32.  
  33. namespace boost { namespace spirit { namespace traits {
  34.  
  35. template <typename Int>
  36. struct assign_to_attribute_from_value<
  37. Int,
  38. std::string,
  39. typename std::enable_if<std::is_integral<Int>::value, void>::type // Enabler
  40. >
  41. {
  42. static void call(std::string const& val, Int& attr) {
  43. //std::cout << __PRETTY_FUNCTION__ << "('" << val << "')n";
  44. attr = boost::lexical_cast<Int>(val);
  45. }
  46. };
  47.  
  48. } } }
  49.  
  50. // boost lexical_cast does not usefully support `char` types as integrals... (SIC)
  51. template <>
  52. struct assign_to_attribute_from_value<signed char, std::string> {
  53. static void call(std::string const& val, signed char& attr) {
  54. int tmp;
  55. assign_to_attribute_from_value<int, std::string>::call(val, tmp);
  56. attr = static_cast<signed char>(tmp);
  57. }
  58. };
  59.  
  60. template <>
  61. struct assign_to_attribute_from_value<unsigned char, std::string> {
  62. static void call(std::string const& val, unsigned char& attr) {
  63. unsigned int tmp;
  64. assign_to_attribute_from_value<unsigned int, std::string>::call(val, tmp);
  65. attr = static_cast<unsigned char>(tmp);
  66. }
  67. };
  68.  
  69. Int parsed = 0;
  70. bool ok = parse(f, l, as_string [ -char_("-+") >> +digit ], parsed);
  71.  
  72. Int parsed = 0;
  73. bool ok = qi::parse(f, l, qi::auto_, parsed);
  74.  
  75. #include <boost/spirit/include/qi.hpp>
  76.  
  77. template <typename Int>
  78. void do_test() {
  79. for (Int const testcase : { std::numeric_limits<Int>::min(), Int(), std::numeric_limits<Int>::max() }) {
  80. auto const input = std::to_string(testcase);
  81. auto f(input.begin()), l(input.end());
  82.  
  83. Int parsed = 0;
  84. bool ok = boost::spirit::qi::parse(f, l, boost::spirit::qi::auto_, parsed);
  85.  
  86. if (!ok || f!=l)
  87. throw std::runtime_error("parse error");
  88.  
  89. std::cout << std::boolalpha << (testcase==parsed) << "t" << testcase << " -> " << parsed << "n";
  90. }
  91. }
  92.  
  93. int main() {
  94. do_test<int16_t>(); do_test<uint16_t>();
  95. do_test<int32_t>(); do_test<uint32_t>();
  96. do_test<int64_t>(); do_test<uint64_t>();
  97. do_test<intmax_t>(); do_test<uintmax_t>();
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement