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