1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*=============================================================================
Copyright (c) 2002-2010 Hartmut Kaiser
Copyright (c) 2002-2010 Joel de Guzman
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)
=============================================================================*/
///////////////////////////////////////////////////////////////////////////////
//
// This sample demonstrates a generator for a comma separated list of numbers.
// No actions. It is based on the example qi/num_lists.cpp for reading in
// some numbers to generate.
//
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace client
{
///////////////////////////////////////////////////////////////////////////
// Our number list parser, please see the example qi/numlist1.cpp for
// more information
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double>& v)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
bool r = phrase_parse(first, last, double_ % ',', space, v);
if (first != last)
return false;
return r;
}
//[tutorial_karma_numlist3_complex
// a simple complex number representation z = a + bi
struct complex
{
complex (double a, double b = 0.0) : a(a), b(b) {}
double a;
double b;
};
// the streaming operator for the type complex
std::ostream&
operator<< (std::ostream& os, complex const& z)
{
os << "{" << z.a << "," << z.b << "}";
return os;
}
//]
///////////////////////////////////////////////////////////////////////////
// Our number list generator
///////////////////////////////////////////////////////////////////////////
//[tutorial_karma_numlist3
template <typename OutputIterator, typename Container>
bool generate_numbers(OutputIterator& sink, Container const& v)
{
using boost::spirit::karma::stream;
using boost::spirit::karma::generate;
using boost::spirit::karma::eol;
bool r = generate(
sink, // destination: output iterator
stream % eol, // the generator
v // the data to output
);
return r;
}
//]
}
////////////////////////////////////////////////////////////////////////////
// Main program
////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "\tA comma separated list generator for Spirit...\n\n";
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Give me a comma separated list of numbers.\n";
std::cout << "Type [q or Q] to quit\n\n";
std::string str;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::vector<double> v; // here we put the data gotten from input
if (client::parse_numbers(str.begin(), str.end(), v))
{
// ok, we got some numbers, fill a vector of client::complex
// instances and print them back out
std::vector<client::complex> vc;
std::vector<double>::const_iterator end = v.end();
for (std::vector<double>::const_iterator it = v.begin();
it != end; ++it)
{
double real(*it);
if (++it != end)
vc.push_back(client::complex(real, *it));
else {
vc.push_back(client::complex(real));
break;
}
}
std::cout << "-------------------------\n";
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
if (!client::generate_numbers(sink, vc))
{
std::cout << "-------------------------\n";
std::cout << "Generating failed\n";
std::cout << "-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Generated:\n" << generated << "\n";
std::cout << "-------------------------\n";
}
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
}
|