• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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