1 /*=============================================================================
2 Phoenix V1.0
3 Copyright (c) 2002-2003 Martin Wille
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 // vi:ts=4:sw=4:et
10 // Tests for BOOST_SPIRIT_CLASSIC_NS::while_p
11 // [28-Dec-2002]
12 ////////////////////////////////////////////////////////////////////////////////
13 #include <iostream>
14 #include <cstring>
15
16 #include "impl/string_length.hpp"
17 #include <boost/spirit/include/classic_core.hpp>
18 #include <boost/spirit/include/classic_assign_actor.hpp>
19 #include <boost/spirit/include/classic_while.hpp>
20 #include <boost/ref.hpp>
21
22 namespace local
23 {
24 template <typename T>
25 struct var_wrapper
26 : public ::boost::reference_wrapper<T>
27 {
28 typedef boost::reference_wrapper<T> parent;
29
var_wrapperlocal::var_wrapper30 explicit inline var_wrapper(T& t) : parent(t) {}
31
operator ()local::var_wrapper32 inline T& operator()() const { return parent::get(); }
33 };
34
35 template <typename T>
36 inline var_wrapper<T>
var(T & t)37 var(T& t)
38 {
39 return var_wrapper<T>(t);
40 }
41 }
42
43 namespace
44 {
45 template <typename T>
46 class add_actor
47 {
48 public:
add_actor(T & ref_)49 explicit add_actor(T &ref_) : ref(ref_) {}
50
51 template <typename T2>
operator ()(T2 const & val) const52 void operator()(T2 const &val) const
53 { ref += val; }
54
55 private:
56 T& ref;
57 };
58
59 template <typename T>
60 inline add_actor<T> const
add(T & ref)61 add(T& ref)
62 {
63 return add_actor<T>(ref);
64 }
65 }
66
67 typedef BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
68
69 unsigned int test_count = 0;
70 unsigned int error_count = 0;
71 unsigned int iterations_performed;
72
73 unsigned int number_result;
74 static const unsigned int kError = 999;
75 static const bool good = true;
76 static const bool bad = false;
77
78 rule_t while_rule;
79 rule_t do_while_rule;
80
81 void
test_while(char const * s,unsigned int wanted,rule_t const & r,unsigned int iterations_wanted)82 test_while(
83 char const *s,
84 unsigned int wanted,
85 rule_t const &r,
86 unsigned int iterations_wanted)
87 {
88 using namespace std;
89
90 ++test_count;
91
92 number_result = 0;
93 iterations_performed = 0;
94
95 BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = BOOST_SPIRIT_CLASSIC_NS::parse(s, s+ test_impl::string_length(s), r);
96
97 bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
98
99 result &= iterations_performed == iterations_wanted;
100
101 if (m.full && (m.length != test_impl::string_length(s)))
102 result = bad;
103
104 if (result==good)
105 cout << "PASSED";
106 else
107 {
108 ++error_count;
109 cout << "FAILED";
110 }
111
112 cout << ": \"" << s << "\" ==> ";
113 if (!m.full)
114 cout << "<error>";
115 else
116 cout << number_result;
117 cout << " " << iterations_performed << " of "
118 << iterations_wanted << " iterations\n";
119 }
120
121 template<typename T>
122 struct inc_actor
123 {
inc_actorinc_actor124 explicit inc_actor(T &t) : var(t) {}
125 template<typename IteratorT>
operator ()inc_actor126 void operator()(IteratorT const &, IteratorT const &) const
127 {
128 ++var;
129 }
130 template<typename U>
operator ()inc_actor131 void operator()(U) const
132 {
133 ++var;
134 }
135 T &var;
136 };
137
138 template<typename T>
139 inc_actor<T>
inc(T & t)140 inc(T &t)
141 {
142 return inc_actor<T>(t);
143 }
144
145 int
main()146 main()
147 {
148 using namespace std;
149 using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
150 using ::BOOST_SPIRIT_CLASSIC_NS::while_p;
151 using ::BOOST_SPIRIT_CLASSIC_NS::do_p;
152 using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
153
154 #if qDebug
155 BOOST_SPIRIT_DEBUG_RULE(while_rule);
156 BOOST_SPIRIT_DEBUG_RULE(do_while_rule);
157 #endif
158
159 while_rule
160 = uint_p[assign_a(number_result)]
161 >> while_p('+')
162 [
163 uint_p[add(number_result)][inc(iterations_performed)]
164 ];
165
166 do_while_rule
167 = do_p
168 [
169 uint_p[add(number_result)][inc(iterations_performed)]
170 ].while_p('+');
171
172 cout << "/////////////////////////////////////////////////////////\n";
173 cout << "\n";
174 cout << " while_p test\n";
175 cout << "\n";
176 cout << "/////////////////////////////////////////////////////////\n";
177 cout << "\n";
178
179 cout << "while_p()[]\n";
180 test_while("", kError, while_rule, 0);
181 test_while("1", 1, while_rule, 0);
182 test_while("1+1", 2, while_rule, 1);
183 test_while("1+1+12", 14, while_rule, 2);
184 test_while("1+1+x", kError, while_rule, 1);
185
186 cout << "do_p[].while_p()\n";
187 test_while("", kError, do_while_rule, 0);
188 test_while("1", 1, do_while_rule, 1);
189 test_while("1+1", 2, do_while_rule, 2);
190 test_while("1+1+12", 14, do_while_rule, 3);
191 test_while("1+1+x", kError, do_while_rule, 2);
192
193 std::cout << "\n ";
194 if (error_count==0)
195 cout << "All " << test_count << " while_p-tests passed.\n"
196 << "Test concluded successfully\n";
197 else
198 cout << error_count << " of " << test_count << " while_p-tests failed\n"
199 << "Test failed\n";
200
201 return error_count!=0;
202 }
203