regression_transform_assignment.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. // Copyright (c) 2011 Dean Michael Berries
  3. //
  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. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/config/warning_disable.hpp>
  8. #include <boost/spirit/include/qi.hpp>
  9. #include <boost/fusion/tuple.hpp>
  10. #include <string>
  11. struct foo_parts
  12. {
  13. boost::optional<std::string> first;
  14. std::string second;
  15. };
  16. namespace boost { namespace spirit { namespace traits
  17. {
  18. template <>
  19. struct transform_attribute<foo_parts
  20. , fusion::tuple<std::string &, optional<std::string> &>
  21. , spirit::qi::domain>
  22. {
  23. typedef fusion::tuple<std::string&, optional<std::string>&> type;
  24. static type pre(foo_parts & parts)
  25. {
  26. return fusion::tie(parts.second, parts.first);
  27. }
  28. static void post(foo_parts &, type const &) {}
  29. static void fail(foo_parts &) {}
  30. };
  31. }}}
  32. namespace qi = boost::spirit::qi;
  33. template <typename Iterator>
  34. struct foo_grammar : qi::grammar<Iterator, foo_parts()>
  35. {
  36. foo_grammar() : foo_grammar::base_type(start, "foo")
  37. {
  38. foo_part =
  39. +qi::alpha >> -(+qi::digit)
  40. | qi::attr(std::string())
  41. >> qi::attr(boost::optional<std::string>())
  42. ;
  43. start = foo_part.alias();
  44. }
  45. typedef boost::fusion::tuple<std::string&, boost::optional<std::string>&>
  46. tuple_type;
  47. qi::rule<Iterator, tuple_type()> foo_part;
  48. qi::rule<Iterator, foo_parts()> start;
  49. };
  50. int main()
  51. {
  52. foo_parts instance;
  53. foo_grammar<std::string::iterator> grammar;
  54. std::string input = "abc123";
  55. BOOST_TEST(qi::parse(input.begin(), input.end(), grammar, instance) &&
  56. instance.first && instance.first.get() == "123" &&
  57. instance.second == "abc");
  58. return boost::report_errors();
  59. }