1 // result_of_tests.cpp -- The Boost Lambda Library ------------------
3 // Copyright (C) 2010 Steven Watanabe
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)
9 // For more information, see www.boost.org
11 // -----------------------------------------------------------------------
14 #include <boost/core/lightweight_test.hpp>
15 #include <boost/lambda/bind.hpp>
16 #include <boost/lambda/lambda.hpp>
17 #include <boost/mpl/assert.hpp>
18 #include <boost/type_traits/is_same.hpp>
20 struct with_result_type
{
21 typedef int result_type
;
22 int operator()() const { return 0; }
23 int operator()(int) const { return 1; }
24 int operator()(int, int) const { return 2; }
25 int operator()(int, int, int) const { return 3; }
26 int operator()(int, int, int, int) const { return 4; }
27 int operator()(int, int, int, int, int) const { return 5; }
28 int operator()(int, int, int, int, int, int) const { return 6; }
29 int operator()(int, int, int, int, int, int, int) const { return 7; }
30 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
31 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
34 struct with_result_template_value
{
38 struct result
<This()> {
41 template<class This
, class A1
>
42 struct result
<This(A1
)> {
43 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
46 template<class This
, class A1
, class A2
>
47 struct result
<This(A1
, A2
)> {
48 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
49 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
52 template<class This
, class A1
, class A2
, class A3
>
53 struct result
<This(A1
, A2
, A3
)> {
54 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
55 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
56 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
59 template<class This
, class A1
, class A2
, class A3
, class A4
>
60 struct result
<This(A1
, A2
, A3
, A4
)> {
61 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
62 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
63 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
64 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
67 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
>
68 struct result
<This(A1
, A2
, A3
, A4
, A5
)> {
69 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
70 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
71 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
72 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
73 BOOST_MPL_ASSERT((boost::is_same
<A5
, int>));
76 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
>
77 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
)> {
78 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
79 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
80 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
81 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
82 BOOST_MPL_ASSERT((boost::is_same
<A5
, int>));
83 BOOST_MPL_ASSERT((boost::is_same
<A6
, int>));
86 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
>
87 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
)> {
88 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
89 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
90 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
91 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
92 BOOST_MPL_ASSERT((boost::is_same
<A5
, int>));
93 BOOST_MPL_ASSERT((boost::is_same
<A6
, int>));
94 BOOST_MPL_ASSERT((boost::is_same
<A7
, int>));
97 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
, class A8
>
98 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
, A8
)> {
99 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
100 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
101 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
102 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
103 BOOST_MPL_ASSERT((boost::is_same
<A5
, int>));
104 BOOST_MPL_ASSERT((boost::is_same
<A6
, int>));
105 BOOST_MPL_ASSERT((boost::is_same
<A7
, int>));
106 BOOST_MPL_ASSERT((boost::is_same
<A8
, int>));
109 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
, class A8
, class A9
>
110 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
, A8
, A9
)> {
111 BOOST_MPL_ASSERT((boost::is_same
<A1
, int>));
112 BOOST_MPL_ASSERT((boost::is_same
<A2
, int>));
113 BOOST_MPL_ASSERT((boost::is_same
<A3
, int>));
114 BOOST_MPL_ASSERT((boost::is_same
<A4
, int>));
115 BOOST_MPL_ASSERT((boost::is_same
<A5
, int>));
116 BOOST_MPL_ASSERT((boost::is_same
<A6
, int>));
117 BOOST_MPL_ASSERT((boost::is_same
<A7
, int>));
118 BOOST_MPL_ASSERT((boost::is_same
<A8
, int>));
119 BOOST_MPL_ASSERT((boost::is_same
<A9
, int>));
123 int operator()() const { return 0; }
124 int operator()(int) const { return 1; }
125 int operator()(int, int) const { return 2; }
126 int operator()(int, int, int) const { return 3; }
127 int operator()(int, int, int, int) const { return 4; }
128 int operator()(int, int, int, int, int) const { return 5; }
129 int operator()(int, int, int, int, int, int) const { return 6; }
130 int operator()(int, int, int, int, int, int, int) const { return 7; }
131 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
132 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
135 struct with_result_template_reference
{
139 struct result
<This()> {
142 template<class This
, class A1
>
143 struct result
<This(A1
)> {
144 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
147 template<class This
, class A1
, class A2
>
148 struct result
<This(A1
, A2
)> {
149 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
150 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
153 template<class This
, class A1
, class A2
, class A3
>
154 struct result
<This(A1
, A2
, A3
)> {
155 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
156 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
157 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
160 template<class This
, class A1
, class A2
, class A3
, class A4
>
161 struct result
<This(A1
, A2
, A3
, A4
)> {
162 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
163 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
164 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
165 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
168 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
>
169 struct result
<This(A1
, A2
, A3
, A4
, A5
)> {
170 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
171 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
172 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
173 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
174 BOOST_MPL_ASSERT((boost::is_same
<A5
, int&>));
177 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
>
178 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
)> {
179 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
180 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
181 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
182 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
183 BOOST_MPL_ASSERT((boost::is_same
<A5
, int&>));
184 BOOST_MPL_ASSERT((boost::is_same
<A6
, int&>));
187 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
>
188 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
)> {
189 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
190 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
191 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
192 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
193 BOOST_MPL_ASSERT((boost::is_same
<A5
, int&>));
194 BOOST_MPL_ASSERT((boost::is_same
<A6
, int&>));
195 BOOST_MPL_ASSERT((boost::is_same
<A7
, int&>));
198 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
, class A8
>
199 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
, A8
)> {
200 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
201 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
202 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
203 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
204 BOOST_MPL_ASSERT((boost::is_same
<A5
, int&>));
205 BOOST_MPL_ASSERT((boost::is_same
<A6
, int&>));
206 BOOST_MPL_ASSERT((boost::is_same
<A7
, int&>));
207 BOOST_MPL_ASSERT((boost::is_same
<A8
, int&>));
210 template<class This
, class A1
, class A2
, class A3
, class A4
, class A5
, class A6
, class A7
, class A8
, class A9
>
211 struct result
<This(A1
, A2
, A3
, A4
, A5
, A6
, A7
, A8
, A9
)> {
212 BOOST_MPL_ASSERT((boost::is_same
<A1
, int&>));
213 BOOST_MPL_ASSERT((boost::is_same
<A2
, int&>));
214 BOOST_MPL_ASSERT((boost::is_same
<A3
, int&>));
215 BOOST_MPL_ASSERT((boost::is_same
<A4
, int&>));
216 BOOST_MPL_ASSERT((boost::is_same
<A5
, int&>));
217 BOOST_MPL_ASSERT((boost::is_same
<A6
, int&>));
218 BOOST_MPL_ASSERT((boost::is_same
<A7
, int&>));
219 BOOST_MPL_ASSERT((boost::is_same
<A8
, int&>));
220 BOOST_MPL_ASSERT((boost::is_same
<A9
, int&>));
224 int operator()() const { return 0; }
225 int operator()(int) const { return 1; }
226 int operator()(int, int) const { return 2; }
227 int operator()(int, int, int) const { return 3; }
228 int operator()(int, int, int, int) const { return 4; }
229 int operator()(int, int, int, int, int) const { return 5; }
230 int operator()(int, int, int, int, int, int) const { return 6; }
231 int operator()(int, int, int, int, int, int, int) const { return 7; }
232 int operator()(int, int, int, int, int, int, int, int) const { return 8; }
233 int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
237 typename
boost::result_of
<F()>::type
apply0(F f
) {
240 template<class A
, class F
>
241 typename
boost::result_of
<F(A
)>::type
apply1(F f
, A a
) {
244 template<class A
, class B
, class F
>
245 typename
boost::result_of
<F(A
, B
)>::type
apply2(F f
, A a
, B b
) {
248 template<class A
, class B
, class C
, class F
>
249 typename
boost::result_of
<F(A
, B
, C
)>::type
apply3(F f
, A a
, B b
, C c
) {
253 using namespace boost::lambda
;
257 BOOST_TEST_EQ(boost::lambda::bind(with_result_type())(), 0);
258 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1)(), 1);
259 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2)(), 2);
260 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3)(), 3);
261 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)(), 4);
262 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)(), 5);
263 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)(), 6);
264 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)(), 7);
265 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)(), 8);
266 BOOST_TEST_EQ(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)(), 9);
268 // Nullary result_of fails
269 //BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value())(), 0);
270 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1)(), 1);
271 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2)(), 2);
272 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3)(), 3);
273 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)(), 4);
274 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)(), 5);
275 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)(), 6);
276 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)(), 7);
277 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)(), 8);
278 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)(), 9);
290 // Nullary result_of fails
291 //BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference())(), 0);
292 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
))(), 1);
293 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
))(), 2);
294 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
))(), 3);
295 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
), var(four
))(), 4);
296 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
), var(four
), var(five
))(), 5);
297 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
), var(four
), var(five
), var(six
))(), 6);
298 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
), var(four
), var(five
), var(six
), var(seven
))(), 7);
299 BOOST_TEST_EQ(boost::lambda::bind(with_result_template_reference(), var(one
), var(two
), var(three
), var(four
), var(five
), var(six
), var(seven
), var(eight
))(), 8);
300 BOOST_TEST_EQ(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 // Check using result_of with lambda functors
303 //BOOST_TEST_EQ(apply0(constant(0)), 0);
304 BOOST_TEST_EQ(apply1
<int>(_1
, one
), 1);
305 BOOST_TEST_EQ(apply1
<int&>(_1
, one
), 1);
306 BOOST_TEST_EQ(apply1
<const int&>(_1
, one
), 1);
307 BOOST_TEST_EQ((apply2
<int, int>(_1
+ _2
, one
, two
)), 3);
308 BOOST_TEST_EQ((apply2
<int&, int&>(_1
+ _2
, one
, two
)), 3);
309 BOOST_TEST_EQ((apply2
<const int&, const int&>(_1
+ _2
, one
, two
)), 3);
310 BOOST_TEST_EQ((apply3
<int, int, int>(_1
+ _2
+ _3
, one
, two
, three
)), 6);
311 BOOST_TEST_EQ((apply3
<int&, int&, int&>(_1
+ _2
+ _3
, one
, two
, three
)), 6);
312 BOOST_TEST_EQ((apply3
<const int&, const int&, const int&>(_1
+ _2
+ _3
, one
, two
, three
)), 6);
314 return boost::report_errors();