1// result_of_tests.cpp -- The Boost Lambda Library ------------------
2//
3// Copyright (C) 2010 Steven Watanabe
4//
5// Distributed under the Boost Software License, Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// For more information, see www.boost.org
10
11// -----------------------------------------------------------------------
12
13
14#include <boost/core/lightweight_test.hpp>
15#define BOOST_CHECK BOOST_TEST
16
17#include <boost/lambda/bind.hpp>
18#include <boost/lambda/lambda.hpp>
19#include <boost/mpl/assert.hpp>
20#include <boost/type_traits/is_same.hpp>
21
22struct with_result_type {
23 typedef int result_type;
24 int operator()() const { return 0; }
25 int operator()(int) const { return 1; }
26 int operator()(int, int) const { return 2; }
27 int operator()(int, int, int) const { return 3; }
28 int operator()(int, int, int, int) const { return 4; }
29 int operator()(int, int, int, int, int) const { return 5; }
30 int operator()(int, int, int, int, int, int) const { return 6; }
31 int operator()(int, int, int, int, int, int, int) const { return 7; }
32 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
33 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
34};
35
36struct with_result_template_value {
37 template<class Sig>
38 struct result;
39 template<class This>
40 struct result<This()> {
41 typedef int type;
42 };
43 template<class This, class A1>
44 struct result<This(A1)> {
45 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
46 typedef int type;
47 };
48 template<class This, class A1, class A2>
49 struct result<This(A1, A2)> {
50 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
51 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
52 typedef int type;
53 };
54 template<class This, class A1, class A2, class A3>
55 struct result<This(A1, A2, A3)> {
56 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
57 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
58 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
59 typedef int type;
60 };
61 template<class This, class A1, class A2, class A3, class A4>
62 struct result<This(A1, A2, A3, A4)> {
63 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
64 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
65 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
66 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
67 typedef int type;
68 };
69 template<class This, class A1, class A2, class A3, class A4, class A5>
70 struct result<This(A1, A2, A3, A4, A5)> {
71 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
72 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
73 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
74 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
75 BOOST_MPL_ASSERT((boost::is_same<A5, int>));
76 typedef int type;
77 };
78 template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
79 struct result<This(A1, A2, A3, A4, A5, A6)> {
80 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
81 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
82 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
83 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
84 BOOST_MPL_ASSERT((boost::is_same<A5, int>));
85 BOOST_MPL_ASSERT((boost::is_same<A6, int>));
86 typedef int type;
87 };
88 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
89 struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
90 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
91 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
92 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
93 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
94 BOOST_MPL_ASSERT((boost::is_same<A5, int>));
95 BOOST_MPL_ASSERT((boost::is_same<A6, int>));
96 BOOST_MPL_ASSERT((boost::is_same<A7, int>));
97 typedef int type;
98 };
99 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
100 struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
101 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
102 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
103 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
104 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
105 BOOST_MPL_ASSERT((boost::is_same<A5, int>));
106 BOOST_MPL_ASSERT((boost::is_same<A6, int>));
107 BOOST_MPL_ASSERT((boost::is_same<A7, int>));
108 BOOST_MPL_ASSERT((boost::is_same<A8, int>));
109 typedef int type;
110 };
111 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
112 struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
113 BOOST_MPL_ASSERT((boost::is_same<A1, int>));
114 BOOST_MPL_ASSERT((boost::is_same<A2, int>));
115 BOOST_MPL_ASSERT((boost::is_same<A3, int>));
116 BOOST_MPL_ASSERT((boost::is_same<A4, int>));
117 BOOST_MPL_ASSERT((boost::is_same<A5, int>));
118 BOOST_MPL_ASSERT((boost::is_same<A6, int>));
119 BOOST_MPL_ASSERT((boost::is_same<A7, int>));
120 BOOST_MPL_ASSERT((boost::is_same<A8, int>));
121 BOOST_MPL_ASSERT((boost::is_same<A9, int>));
122 typedef int type;
123 };
124
125 int operator()() const { return 0; }
126 int operator()(int) const { return 1; }
127 int operator()(int, int) const { return 2; }
128 int operator()(int, int, int) const { return 3; }
129 int operator()(int, int, int, int) const { return 4; }
130 int operator()(int, int, int, int, int) const { return 5; }
131 int operator()(int, int, int, int, int, int) const { return 6; }
132 int operator()(int, int, int, int, int, int, int) const { return 7; }
133 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
134 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
135};
136
137struct with_result_template_reference {
138 template<class Sig>
139 struct result;
140 template<class This>
141 struct result<This()> {
142 typedef int type;
143 };
144 template<class This, class A1>
145 struct result<This(A1)> {
146 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
147 typedef int type;
148 };
149 template<class This, class A1, class A2>
150 struct result<This(A1, A2)> {
151 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
152 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
153 typedef int type;
154 };
155 template<class This, class A1, class A2, class A3>
156 struct result<This(A1, A2, A3)> {
157 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
158 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
159 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
160 typedef int type;
161 };
162 template<class This, class A1, class A2, class A3, class A4>
163 struct result<This(A1, A2, A3, A4)> {
164 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
165 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
166 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
167 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
168 typedef int type;
169 };
170 template<class This, class A1, class A2, class A3, class A4, class A5>
171 struct result<This(A1, A2, A3, A4, A5)> {
172 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
173 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
174 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
175 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
176 BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
177 typedef int type;
178 };
179 template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
180 struct result<This(A1, A2, A3, A4, A5, A6)> {
181 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
182 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
183 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
184 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
185 BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
186 BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
187 typedef int type;
188 };
189 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
190 struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
191 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
192 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
193 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
194 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
195 BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
196 BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
197 BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
198 typedef int type;
199 };
200 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
201 struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
202 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
203 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
204 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
205 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
206 BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
207 BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
208 BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
209 BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
210 typedef int type;
211 };
212 template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
213 struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
214 BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
215 BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
216 BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
217 BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
218 BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
219 BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
220 BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
221 BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
222 BOOST_MPL_ASSERT((boost::is_same<A9, int&>));
223 typedef int type;
224 };
225
226 int operator()() const { return 0; }
227 int operator()(int) const { return 1; }
228 int operator()(int, int) const { return 2; }
229 int operator()(int, int, int) const { return 3; }
230 int operator()(int, int, int, int) const { return 4; }
231 int operator()(int, int, int, int, int) const { return 5; }
232 int operator()(int, int, int, int, int, int) const { return 6; }
233 int operator()(int, int, int, int, int, int, int) const { return 7; }
234 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
235 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
236};
237
238template<class F>
239typename boost::result_of<F()>::type apply0(F f) {
240 return f();
241}
242template<class A, class F>
243typename boost::result_of<F(A)>::type apply1(F f, A a) {
244 return f(a);
245}
246template<class A, class B, class F>
247typename boost::result_of<F(A, B)>::type apply2(F f, A a, B b) {
248 return f(a, b);
249}
250template<class A, class B, class C, class F>
251typename boost::result_of<F(A, B, C)>::type apply3(F f, A a, B b, C c) {
252 return f(a, b, c);
253}
254
255using namespace boost::lambda;
256
257int main() {
258 BOOST_CHECK(boost::lambda::bind(with_result_type())() == 0);
259 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1)() == 1);
260 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2)() == 2);
261 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3)() == 3);
262 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)() == 4);
263 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)() == 5);
264 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)() == 6);
265 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)() == 7);
266 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
267 BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
268
269 // Nullary result_of fails
270 //BOOST_CHECK(boost::lambda::bind(with_result_template_value())() == 0);
271 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1)() == 1);
272 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2)() == 2);
273 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3)() == 3);
274 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)() == 4);
275 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)() == 5);
276 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)() == 6);
277 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)() == 7);
278 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
279 BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
280
281 int one = 1,
282 two = 2,
283 three = 3,
284 four = 4,
285 five = 5,
286 six = 6,
287 seven = 7,
288 eight = 8,
289 nine = 9;
290
291 // Nullary result_of fails
292 //BOOST_CHECK(boost::lambda::bind(with_result_template_reference())() == 0);
293 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one))() == 1);
294 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two))() == 2);
295 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three))() == 3);
296 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four))() == 4);
297 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five))() == 5);
298 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six))() == 6);
299 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven))() == 7);
300 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight))() == 8);
301 BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight), var(nine))() == 9);
302
303 // Check using result_of with lambda functors
304 BOOST_CHECK(apply0(constant(0)) == 0);
305 // returns local address and leads to undefined behavior
306 //~ BOOST_CHECK(apply1<int>(_1, one) == 1);
307 BOOST_CHECK(apply1<int&>(_1, one) == 1);
308 BOOST_CHECK(apply1<const int&>(_1, one) == 1);
309 BOOST_CHECK((apply2<int, int>(_1 + _2, one, two) == 3));
310 BOOST_CHECK((apply2<int&, int&>(_1 + _2, one, two) == 3));
311 BOOST_CHECK((apply2<const int&, const int&>(_1 + _2, one, two) == 3));
312 BOOST_CHECK((apply3<int, int, int>(_1 + _2 + _3, one, two, three) == 6));
313 BOOST_CHECK((apply3<int&, int&, int&>(_1 + _2 + _3, one, two, three) == 6));
314 BOOST_CHECK((apply3<const int&, const int&, const int&>(_1 + _2 + _3, one, two, three) == 6));
315
316 return boost::report_errors();
317}
318

source code of boost/libs/lambda/test/result_of_tests.cpp