1 // Copyright (c) 2001-2010 Hartmut Kaiser
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)
6 // The main purpose of this example is to show how a single fusion sequence
7 // can be filled from a parsed input of the elements in different sequences
9 #include <boost/config/warning_disable.hpp>
10 #include <boost/mpl/print.hpp>
11 #include <boost/spirit/include/qi.hpp>
12 #include <boost/fusion/include/struct.hpp>
13 #include <boost/fusion/include/nview.hpp>
14 #include <boost/foreach.hpp>
16 namespace fusion
= boost::fusion
;
17 namespace qi
= boost::spirit::qi
;
19 ///////////////////////////////////////////////////////////////////////////////
22 // Our employee struct
29 std::string department
;
32 // define iterator type
33 typedef std::string::const_iterator iterator_type
;
35 // This is the output routine taking a format description and the data to
37 template <typename Parser
, typename Sequence
>
38 bool parse(std::string
const& input
, Parser
const& p
, Sequence
& s
)
40 iterator_type begin
= input
.begin();
41 return qi::parse(begin
, input
.end(), p
, s
);
45 // We need to tell fusion about our employee struct to make it a first-class
46 // fusion citizen. This has to be in global scope. Note that we don't need to
47 // list the members of our struct in the same sequence a they are defined
48 BOOST_FUSION_ADAPT_STRUCT(
51 (std::string
, surname
)
52 (std::string
, forename
)
53 (std::string
, department
)
57 ///////////////////////////////////////////////////////////////////////////////
58 // that's the different types we need to reorder the attributes
59 typedef fusion::result_of::as_nview
<client::employee
, 2, 0>::type name_and_age
;
60 typedef fusion::result_of::as_nview
<client::employee
, 1, 2, 4>::type names_and_salary
;
61 typedef fusion::result_of::as_nview
<client::employee
, 2, 0, 3>::type name_age_and_department
;
63 ///////////////////////////////////////////////////////////////////////////////
69 client::employee john
;
70 client::employee mary
;
73 // print data about employees in different formats
75 // parse forename and age only
76 name_and_age
johnview(fusion::as_nview
<2, 0>(john
));
77 bool r
= client::parse(
79 *(qi::char_
- ',') >> ", " >> qi::int_
,
82 std::cout
<< "Parsed: " << john
.forename
<< ", " << john
.age
86 // parse surname, forename, and salary
87 names_and_salary
maryview(fusion::as_nview
<1, 2, 4>(mary
));
89 "Higgins, Mary: 2200.36",
90 *(qi::char_
- ',') >> ", " >> *(qi::char_
- ':') >> ": " >> qi::double_
,
93 std::cout
<< "Parsed: " << mary
.forename
<< ", " << mary
.surname
94 << ", " << mary
.salary
<< std::endl
;
97 // parse forename, age, and department
98 name_age_and_department
tomview(fusion::as_nview
<2, 0, 3>(tom
));
101 *(qi::char_
- ':') >> ": " >> qi::int_
>> " (" >> *(qi::char_
- ')') >> ')',
104 std::cout
<< "Parsed: " << tom
.forename
<< ", " << tom
.age
105 << ", " << tom
.department
<< std::endl
;
109 // now parse a list of several employees and print them all
110 std::vector
<client::employee
> employees
;
112 // parse surname, forename, and salary for all employees
114 qi::rule
<client::iterator_type
, names_and_salary()> r
=
115 *(qi::char_
- ',') >> ", " >> *(qi::char_
- ',') >> ", " >> qi::double_
;
117 bool result
= client::parse(
118 "John, Smith, 2000.50\n" "Mary, Higgins, 2200.36\n" "Tom, Taylor, 3200.00\n",
119 r
% qi::eol
, employees
);
121 std::cout
<< "Parsed: " << std::endl
;
122 BOOST_FOREACH(client::employee
const& e
, employees
)
124 std::cout
<< e
.forename
<< ", " << e
.surname
<< ", " << e
.salary