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 
7 #include <boost/detail/lightweight_test.hpp>
8 #include <boost/config/warning_disable.hpp>
9 
10 #include <boost/spirit/include/qi.hpp>
11 #include <boost/fusion/tuple.hpp>
12 #include <string>
13 
14 struct foo_parts
15 {
16     boost::optional<std::string> first;
17     std::string second;
18 };
19 
20 namespace boost { namespace spirit { namespace traits
21 {
22     template <>
23     struct transform_attribute<foo_parts
24       , fusion::tuple<std::string &, optional<std::string> &>
25       , spirit::qi::domain>
26     {
27         typedef fusion::tuple<std::string&, optional<std::string>&> type;
28 
preboost::spirit::traits::transform_attribute29         static type pre(foo_parts & parts)
30         {
31             return fusion::tie(parts.second, parts.first);
32         }
33 
postboost::spirit::traits::transform_attribute34         static void post(foo_parts &, type const &) {}
failboost::spirit::traits::transform_attribute35         static void fail(foo_parts &) {}
36     };
37 }}}
38 
39 namespace qi = boost::spirit::qi;
40 
41 template <typename Iterator>
42 struct foo_grammar : qi::grammar<Iterator, foo_parts()>
43 {
foo_grammarfoo_grammar44     foo_grammar() : foo_grammar::base_type(start, "foo")
45     {
46         foo_part =
47                +qi::alpha >> -(+qi::digit)
48             |   qi::attr(std::string())
49                 >> qi::attr(boost::optional<std::string>())
50             ;
51 
52         start = foo_part.alias();
53     }
54 
55     typedef boost::fusion::tuple<std::string&, boost::optional<std::string>&>
56         tuple_type;
57 
58     qi::rule<Iterator, tuple_type()> foo_part;
59     qi::rule<Iterator, foo_parts()> start;
60 };
61 
main()62 int main()
63 {
64     foo_parts instance;
65     foo_grammar<std::string::iterator> grammar;
66     std::string input = "abc123";
67 
68     BOOST_TEST(qi::parse(input.begin(), input.end(), grammar, instance) &&
69         instance.first && instance.first.get() == "123" &&
70         instance.second == "abc");
71 
72     return boost::report_errors();
73 }
74 
75