2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00
Files
spirit/example/qi/reorder_struct.cpp
Nikita Kniazev f44479bcd3 Remove boost/config/warning_disable.hpp usage
It is better to manage warnings on our side to know what warnings we need to fix or suppress, and the only thing that header does is disabling deprecation warnings on MSVC and ICC which we would prefer to not show to users.
2021-08-24 03:14:12 +03:00

129 lines
4.3 KiB
C++

// Copyright (c) 2001-2010 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// The main purpose of this example is to show how a single fusion sequence
// can be filled from a parsed input of the elements in different sequences
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/struct.hpp>
#include <boost/fusion/include/nview.hpp>
#include <boost/foreach.hpp>
namespace fusion = boost::fusion;
namespace qi = boost::spirit::qi;
///////////////////////////////////////////////////////////////////////////////
namespace client
{
// Our employee struct
struct employee
{
std::string surname;
std::string forename;
int age;
double salary;
std::string department;
};
// define iterator type
typedef std::string::const_iterator iterator_type;
// This is the output routine taking a format description and the data to
// print
template <typename Parser, typename Sequence>
bool parse(std::string const& input, Parser const& p, Sequence& s)
{
iterator_type begin = input.begin();
return qi::parse(begin, input.end(), p, s);
}
}
// We need to tell fusion about our employee struct to make it a first-class
// fusion citizen. This has to be in global scope. Note that we don't need to
// list the members of our struct in the same sequence a they are defined
BOOST_FUSION_ADAPT_STRUCT(
client::employee,
(int, age)
(std::string, surname)
(std::string, forename)
(std::string, department)
(double, salary)
)
///////////////////////////////////////////////////////////////////////////////
// that's the different types we need to reorder the attributes
typedef fusion::result_of::as_nview<client::employee, 2, 0>::type name_and_age;
typedef fusion::result_of::as_nview<client::employee, 1, 2, 4>::type names_and_salary;
typedef fusion::result_of::as_nview<client::employee, 2, 0, 3>::type name_age_and_department;
///////////////////////////////////////////////////////////////////////////////
int main()
{
std::string str;
// some employees
client::employee john;
client::employee mary;
client::employee tom;
// print data about employees in different formats
{
// parse forename and age only
name_and_age johnview(fusion::as_nview<2, 0>(john));
bool r = client::parse(
"John, 25",
*(qi::char_ - ',') >> ", " >> qi::int_,
johnview);
if (r) {
std::cout << "Parsed: " << john.forename << ", " << john.age
<< std::endl;
}
// parse surname, forename, and salary
names_and_salary maryview(fusion::as_nview<1, 2, 4>(mary));
r = client::parse(
"Higgins, Mary: 2200.36",
*(qi::char_ - ',') >> ", " >> *(qi::char_ - ':') >> ": " >> qi::double_,
maryview);
if (r) {
std::cout << "Parsed: " << mary.forename << ", " << mary.surname
<< ", " << mary.salary << std::endl;
}
// parse forename, age, and department
name_age_and_department tomview(fusion::as_nview<2, 0, 3>(tom));
client::parse(
"Tom: 48 (Boss)",
*(qi::char_ - ':') >> ": " >> qi::int_ >> " (" >> *(qi::char_ - ')') >> ')',
tomview);
if (r) {
std::cout << "Parsed: " << tom.forename << ", " << tom.age
<< ", " << tom.department << std::endl;
}
}
// now parse a list of several employees and print them all
std::vector<client::employee> employees;
// parse surname, forename, and salary for all employees
{
qi::rule<client::iterator_type, names_and_salary()> r =
*(qi::char_ - ',') >> ", " >> *(qi::char_ - ',') >> ", " >> qi::double_;
bool result = client::parse(
"John, Smith, 2000.50\n" "Mary, Higgins, 2200.36\n" "Tom, Taylor, 3200.00\n",
r % qi::eol, employees);
std::cout << "Parsed: " << std::endl;
BOOST_FOREACH(client::employee const& e, employees)
{
std::cout << e.forename << ", " << e.surname << ", " << e.salary
<< std::endl;
}
}
return 0;
}