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 #define qDebug 0
14 #include <iostream>
15 #include <cstring>
16 #if qDebug
17 #define BOOST_SPIRIT_DEBUG
18 #endif
19
20 #include "impl/string_length.hpp"
21 #include <boost/spirit/include/classic_core.hpp>
22 #include <boost/spirit/include/classic_assign_actor.hpp>
23 #include <boost/spirit/include/classic_while.hpp>
24 #include <boost/ref.hpp>
25
26 namespace local
27 {
28 template <typename T>
29 struct var_wrapper
30 : public ::boost::reference_wrapper<T>
31 {
32 typedef boost::reference_wrapper<T> parent;
33
var_wrapperlocal::var_wrapper34 explicit inline var_wrapper(T& t) : parent(t) {}
35
operator ()local::var_wrapper36 inline T& operator()() const { return parent::get(); }
37 };
38
39 template <typename T>
40 inline var_wrapper<T>
var(T & t)41 var(T& t)
42 {
43 return var_wrapper<T>(t);
44 }
45 }
46
47 namespace
48 {
49 template <typename T>
50 class add_actor
51 {
52 public:
add_actor(T & ref_)53 explicit add_actor(T &ref_) : ref(ref_) {}
54
55 template <typename T2>
operator ()(T2 const & val) const56 void operator()(T2 const &val) const
57 { ref += val; }
58
59 private:
60 T& ref;
61 };
62
63 template <typename T>
64 inline add_actor<T> const
add(T & ref)65 add(T& ref)
66 {
67 return add_actor<T>(ref);
68 }
69 }
70
71 typedef BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
72
73 unsigned int test_count = 0;
74 unsigned int error_count = 0;
75 unsigned int iterations_performed;
76
77 unsigned int number_result;
78 static const unsigned int kError = 999;
79 static const bool good = true;
80 static const bool bad = false;
81
82 rule_t while_rule;
83 rule_t do_while_rule;
84
85 void
test_while(char const * s,unsigned int wanted,rule_t const & r,unsigned int iterations_wanted)86 test_while(
87 char const *s,
88 unsigned int wanted,
89 rule_t const &r,
90 unsigned int iterations_wanted)
91 {
92 using namespace std;
93
94 ++test_count;
95
96 number_result = 0;
97 iterations_performed = 0;
98
99 BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = BOOST_SPIRIT_CLASSIC_NS::parse(s, s+ test_impl::string_length(s), r);
100
101 bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
102
103 result &= iterations_performed == iterations_wanted;
104
105 if (m.full && (m.length != test_impl::string_length(s)))
106 result = bad;
107
108 if (result==good)
109 cout << "PASSED";
110 else
111 {
112 ++error_count;
113 cout << "FAILED";
114 }
115
116 cout << ": \"" << s << "\" ==> ";
117 if (!m.full)
118 cout << "<error>";
119 else
120 cout << number_result;
121 cout << " " << iterations_performed << " of "
122 << iterations_wanted << " iterations\n";
123 }
124
125 template<typename T>
126 struct inc_actor
127 {
inc_actorinc_actor128 explicit inc_actor(T &t) : var(t) {}
129 template<typename IteratorT>
operator ()inc_actor130 void operator()(IteratorT const &, IteratorT const &) const
131 {
132 ++var;
133 }
134 template<typename U>
operator ()inc_actor135 void operator()(U) const
136 {
137 ++var;
138 }
139 T &var;
140 };
141
142 template<typename T>
143 inc_actor<T>
inc(T & t)144 inc(T &t)
145 {
146 return inc_actor<T>(t);
147 }
148
149 int
main()150 main()
151 {
152 using namespace std;
153 using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
154 using ::BOOST_SPIRIT_CLASSIC_NS::while_p;
155 using ::BOOST_SPIRIT_CLASSIC_NS::do_p;
156 using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
157
158 #if qDebug
159 BOOST_SPIRIT_DEBUG_RULE(while_rule);
160 BOOST_SPIRIT_DEBUG_RULE(do_while_rule);
161 #endif
162
163 while_rule
164 = uint_p[assign_a(number_result)]
165 >> while_p('+')
166 [
167 uint_p[add(number_result)][inc(iterations_performed)]
168 ];
169
170 do_while_rule
171 = do_p
172 [
173 uint_p[add(number_result)][inc(iterations_performed)]
174 ].while_p('+');
175
176 cout << "/////////////////////////////////////////////////////////\n";
177 cout << "\n";
178 cout << " while_p test\n";
179 cout << "\n";
180 cout << "/////////////////////////////////////////////////////////\n";
181 cout << "\n";
182
183 cout << "while_p()[]\n";
184 test_while("", kError, while_rule, 0);
185 test_while("1", 1, while_rule, 0);
186 test_while("1+1", 2, while_rule, 1);
187 test_while("1+1+12", 14, while_rule, 2);
188 test_while("1+1+x", kError, while_rule, 1);
189
190 cout << "do_p[].while_p()\n";
191 test_while("", kError, do_while_rule, 0);
192 test_while("1", 1, do_while_rule, 1);
193 test_while("1+1", 2, do_while_rule, 2);
194 test_while("1+1+12", 14, do_while_rule, 3);
195 test_while("1+1+x", kError, do_while_rule, 2);
196
197 std::cout << "\n ";
198 if (error_count==0)
199 cout << "All " << test_count << " while_p-tests passed.\n"
200 << "Test concluded successfully\n";
201 else
202 cout << error_count << " of " << test_count << " while_p-tests failed\n"
203 << "Test failed\n";
204
205 return error_count!=0;
206 }
207