1 /*==============================================================================
2 Copyright (c) 2004 Peter Dimov
3 Copyright (c) 2005-2010 Joel de Guzman
4 Copyright (c) 2010 Thomas Heller
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9
10 #include <boost/config.hpp>
11
12 #if defined(BOOST_MSVC)
13 #pragma warning(disable: 4786) // identifier truncated in debug info
14 #pragma warning(disable: 4710) // function not inlined
15 #pragma warning(disable: 4711) // function selected for automatic inline expansion
16 #pragma warning(disable: 4514) // unreferenced inline removed
17 #endif
18
19 #include <boost/phoenix/core.hpp>
20 #include <boost/phoenix/bind.hpp>
21
22 #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
23 #pragma warning(push, 3)
24 #endif
25
26 #include <iostream>
27
28 #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
29 #pragma warning(pop)
30 #endif
31
32 #include <boost/detail/lightweight_test.hpp>
33
34 class X
35 {
36 private:
37
38 mutable int state_;
39
40 public:
41
X()42 X(): state_(0)
43 {
44 }
45
state() const46 int state() const
47 {
48 return state_;
49 }
50
51 typedef int result_type;
52
operator ()() const53 int operator()() const
54 {
55 return state_ += 17041;
56 }
57
operator ()(int x1) const58 int operator()(int x1) const
59 {
60 return state_ += x1;
61 }
62
operator ()(int x1,int x2) const63 int operator()(int x1, int x2) const
64 {
65 return state_ += x1+x2;
66 }
67
operator ()(int x1,int x2,int x3) const68 int operator()(int x1, int x2, int x3) const
69 {
70 return state_ += x1+x2+x3;
71 }
72
operator ()(int x1,int x2,int x3,int x4) const73 int operator()(int x1, int x2, int x3, int x4) const
74 {
75 return state_ += x1+x2+x3+x4;
76 }
77
operator ()(int x1,int x2,int x3,int x4,int x5) const78 int operator()(int x1, int x2, int x3, int x4, int x5) const
79 {
80 return state_ += x1+x2+x3+x4+x5;
81 }
82
operator ()(int x1,int x2,int x3,int x4,int x5,int x6) const83 int operator()(int x1, int x2, int x3, int x4, int x5, int x6) const
84 {
85 return state_ += x1+x2+x3+x4+x5+x6;
86 }
87
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7) const88 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7) const
89 {
90 return state_ += x1+x2+x3+x4+x5+x6+x7;
91 }
92
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8) const93 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8) const
94 {
95 return state_ += x1+x2+x3+x4+x5+x6+x7+x8;
96 }
97
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8,int x9) const98 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9) const
99 {
100 return state_ += x1+x2+x3+x4+x5+x6+x7+x8+x9;
101 }
102 };
103
104 class Y
105 {
106 private:
107
108 int state_;
109
110 public:
111
Y()112 Y(): state_(0)
113 {
114 }
115
state() const116 int state() const
117 {
118 return state_;
119 }
120
121 typedef int result_type;
122
operator ()()123 int operator()()
124 {
125 return state_ += 17041;
126 }
127
operator ()(int x1)128 int operator()(int x1)
129 {
130 return state_ += x1;
131 }
132
operator ()(int x1,int x2)133 int operator()(int x1, int x2)
134 {
135 return state_ += x1+x2;
136 }
137
operator ()(int x1,int x2,int x3)138 int operator()(int x1, int x2, int x3)
139 {
140 return state_ += x1+x2+x3;
141 }
142
operator ()(int x1,int x2,int x3,int x4)143 int operator()(int x1, int x2, int x3, int x4)
144 {
145 return state_ += x1+x2+x3+x4;
146 }
147
operator ()(int x1,int x2,int x3,int x4,int x5)148 int operator()(int x1, int x2, int x3, int x4, int x5)
149 {
150 return state_ += x1+x2+x3+x4+x5;
151 }
152
operator ()(int x1,int x2,int x3,int x4,int x5,int x6)153 int operator()(int x1, int x2, int x3, int x4, int x5, int x6)
154 {
155 return state_ += x1+x2+x3+x4+x5+x6;
156 }
157
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7)158 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7)
159 {
160 return state_ += x1+x2+x3+x4+x5+x6+x7;
161 }
162
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8)163 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8)
164 {
165 return state_ += x1+x2+x3+x4+x5+x6+x7+x8;
166 }
167
operator ()(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8,int x9)168 int operator()(int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9)
169 {
170 return state_ += x1+x2+x3+x4+x5+x6+x7+x8+x9;
171 }
172 };
173
f0(int & state_)174 int f0(int & state_)
175 {
176 return state_ += 17041;
177 }
178
f1(int & state_,int x1)179 int f1(int & state_, int x1)
180 {
181 return state_ += x1;
182 }
183
f2(int & state_,int x1,int x2)184 int f2(int & state_, int x1, int x2)
185 {
186 return state_ += x1+x2;
187 }
188
f3(int & state_,int x1,int x2,int x3)189 int f3(int & state_, int x1, int x2, int x3)
190 {
191 return state_ += x1+x2+x3;
192 }
193
f4(int & state_,int x1,int x2,int x3,int x4)194 int f4(int & state_, int x1, int x2, int x3, int x4)
195 {
196 return state_ += x1+x2+x3+x4;
197 }
198
f5(int & state_,int x1,int x2,int x3,int x4,int x5)199 int f5(int & state_, int x1, int x2, int x3, int x4, int x5)
200 {
201 return state_ += x1+x2+x3+x4+x5;
202 }
203
f6(int & state_,int x1,int x2,int x3,int x4,int x5,int x6)204 int f6(int & state_, int x1, int x2, int x3, int x4, int x5, int x6)
205 {
206 return state_ += x1+x2+x3+x4+x5+x6;
207 }
208
f7(int & state_,int x1,int x2,int x3,int x4,int x5,int x6,int x7)209 int f7(int & state_, int x1, int x2, int x3, int x4, int x5, int x6, int x7)
210 {
211 return state_ += x1+x2+x3+x4+x5+x6+x7;
212 }
213
f8(int & state_,int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8)214 int f8(int & state_, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8)
215 {
216 return state_ += x1+x2+x3+x4+x5+x6+x7+x8;
217 }
218
219 template <typename> struct wrap {};
220
test(F f,int a,int b)221 template<class F> void test(F f, int a, int b)
222 {
223 BOOST_TEST( f() == a + b );
224 BOOST_TEST( f() == a + 2*b );
225 BOOST_TEST( f() == a + 3*b );
226 }
227
228 using boost::phoenix::bind;
229 using boost::phoenix::ref;
230
stateful_function_object_test()231 void stateful_function_object_test()
232 {
233 ::test( bind( X() ), 0, 17041 );
234 ::test( bind( X(), 1 ), 0, 1 );
235 ::test( bind( X(), 1, 2 ), 0, 1+2 );
236 ::test( bind( X(), 1, 2, 3 ), 0, 1+2+3 );
237 ::test( bind( X(), 1, 2, 3, 4 ), 0, 1+2+3+4 );
238 ::test( bind( X(), 1, 2, 3, 4, 5 ), 0, 1+2+3+4+5 );
239 ::test( bind( X(), 1, 2, 3, 4, 5, 6 ), 0, 1+2+3+4+5+6 );
240 ::test( bind( X(), 1, 2, 3, 4, 5, 6, 7 ), 0, 1+2+3+4+5+6+7 );
241 ::test( bind( X(), 1, 2, 3, 4, 5, 6, 7, 8 ), 0, 1+2+3+4+5+6+7+8 );
242 ::test( bind( X(), 1, 2, 3, 4, 5, 6, 7, 8, 9 ), 0, 1+2+3+4+5+6+7+8+9 );
243
244 Y y;
245
246 int n = y.state();
247
248 ::test( bind( ref(y) ), n, 17041 );
249 n += 3 * 17041;
250
251 ::test( bind( ref(y), 1 ), n, 1 );
252 n += 3*1;
253
254 ::test( bind( ref(y), 1, 2 ), n, 1+2 );
255 n += 3*(1+2);
256
257 ::test( bind( ref(y), 1, 2, 3 ), n, 1+2+3 );
258 n += 3*(1+2+3);
259
260 ::test( bind( ref(y), 1, 2, 3, 4 ), n, 1+2+3+4 );
261 n += 3*(1+2+3+4);
262
263 ::test( bind( ref(y), 1, 2, 3, 4, 5 ), n, 1+2+3+4+5 );
264 n += 3*(1+2+3+4+5);
265
266 ::test( bind( ref(y), 1, 2, 3, 4, 5, 6 ), n, 1+2+3+4+5+6 );
267 n += 3*(1+2+3+4+5+6);
268
269 ::test( bind( ref(y), 1, 2, 3, 4, 5, 6, 7 ), n, 1+2+3+4+5+6+7 );
270 n += 3*(1+2+3+4+5+6+7);
271
272 ::test( bind( ref(y), 1, 2, 3, 4, 5, 6, 7, 8 ), n, 1+2+3+4+5+6+7+8 );
273 n += 3*(1+2+3+4+5+6+7+8);
274
275 ::test( bind( ref(y), 1, 2, 3, 4, 5, 6, 7, 8, 9 ), n, 1+2+3+4+5+6+7+8+9 );
276 n += 3*(1+2+3+4+5+6+7+8+9);
277
278 BOOST_TEST( y.state() == n );
279 }
280
stateful_function_test()281 void stateful_function_test()
282 {
283 using boost::phoenix::ref;
284
285 ::test( bind( f0, 0), 0, 17041 );
286 ::test( bind( f1, 0, 1 ), 0, 1 );
287 ::test( bind( f2, 0, 1, 2 ), 0, 1+2 );
288 ::test( bind( f3, 0, 1, 2, 3 ), 0, 1+2+3 );
289 ::test( bind( f4, 0, 1, 2, 3, 4 ), 0, 1+2+3+4 );
290 ::test( bind( f5, 0, 1, 2, 3, 4, 5 ), 0, 1+2+3+4+5 );
291 ::test( bind( f6, 0, 1, 2, 3, 4, 5, 6 ), 0, 1+2+3+4+5+6 );
292 ::test( bind( f7, 0, 1, 2, 3, 4, 5, 6, 7 ), 0, 1+2+3+4+5+6+7 );
293 ::test( bind( f8, 0, 1, 2, 3, 4, 5, 6, 7, 8 ), 0, 1+2+3+4+5+6+7+8 );
294 }
295
main()296 int main()
297 {
298 stateful_function_object_test();
299 stateful_function_test();
300 return boost::report_errors();
301 }
302