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