]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fusion/test/functional/invoke.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fusion / test / functional / invoke.cpp
1 /*=============================================================================
2 Copyright (c) 2005-2006 Joao Abecasis
3 Copyright (c) 2006-2007 Tobias Schwinger
4
5 Use modification and distribution are 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
10 #include <boost/config.hpp>
11 #include <boost/fusion/functional/invocation/invoke.hpp>
12 #include <boost/detail/lightweight_test.hpp>
13
14 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
15 #include <functional>
16 #endif
17
18 #include <memory>
19 #include <boost/noncopyable.hpp>
20
21 #include <boost/type_traits/is_same.hpp>
22
23 #include <boost/mpl/int.hpp>
24
25 #include <boost/fusion/container/vector.hpp>
26 #include <boost/fusion/container/list.hpp>
27 #include <boost/fusion/sequence/intrinsic/size.hpp>
28 #include <boost/fusion/sequence/intrinsic/begin.hpp>
29 #include <boost/fusion/view/single_view.hpp>
30 #include <boost/fusion/view/iterator_range.hpp>
31 #include <boost/fusion/iterator/advance.hpp>
32 #include <boost/fusion/algorithm/transformation/join.hpp>
33
34 #include "../compile_time/sfinae_friendly.hpp"
35
36 namespace mpl = boost::mpl;
37 namespace fusion = boost::fusion;
38
39 template <typename T>
40 inline T const & const_(T const & t)
41 {
42 return t;
43 }
44
45 struct object {};
46 struct object_nc : boost::noncopyable {};
47
48 struct fobj
49 {
50 // Handle nullary separately to exercise result_of support
51 template <typename Sig>
52 struct result;
53
54 template <class Self, typename T0>
55 struct result< Self(T0) >
56 {
57 typedef int type;
58 };
59
60 template <class Self, typename T0, typename T1>
61 struct result< Self(T0, T1) >
62 {
63 typedef int type;
64 };
65
66 template <class Self, typename T0, typename T1, typename T2>
67 struct result< Self(T0, T1, T2) >
68 {
69 typedef int type;
70 };
71
72 int operator()(int i) { return 2 + i; }
73 int operator()(int i) const { return 3 + i; }
74
75 int operator()(int i, object &) { return 4 + i; }
76 int operator()(int i, object &) const { return 5 + i; }
77 int operator()(int i, object const &) { return 6 + i; }
78 int operator()(int i, object const &) const { return 7 + i; }
79
80 int operator()(int i, object &, object_nc &) { return 10 + i; }
81 int operator()(int i, object &, object_nc &) const { return 11 + i; }
82 int operator()(int i, object const &, object_nc &);
83 int operator()(int i, object const &, object_nc &) const;
84 };
85 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj, sfinae_friendly::v0>));
86 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj, sfinae_friendly::v1>));
87 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj, sfinae_friendly::v2>));
88 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj, sfinae_friendly::v3>));
89
90
91 struct nullary_fobj
92 {
93 typedef int result_type;
94
95 int operator()() { return 0; }
96 int operator()() const { return 1; }
97 };
98 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj, sfinae_friendly::v1>));
99 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj, sfinae_friendly::v2>));
100 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj, sfinae_friendly::v3>));
101
102
103 struct fobj_nc
104 : boost::noncopyable
105 {
106 // Handle nullary separately to exercise result_of support
107 template <typename Sig>
108 struct result;
109
110 template <class Self, typename T0>
111 struct result< Self(T0)>
112 {
113 typedef int type;
114 };
115
116 int operator()(int i) { return 14 + i; }
117 int operator()(int i) const { return 15 + i; }
118 };
119 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj_nc, sfinae_friendly::v0>));
120 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj_nc, sfinae_friendly::v1>));
121 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj_nc, sfinae_friendly::v2>));
122 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<fobj_nc, sfinae_friendly::v3>));
123
124
125 struct nullary_fobj_nc
126 : boost::noncopyable
127 {
128 typedef int result_type;
129
130 int operator()() { return 12; }
131 int operator()() const { return 13; }
132 };
133 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj_nc, sfinae_friendly::v1>));
134 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj_nc, sfinae_friendly::v2>));
135 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<nullary_fobj_nc, sfinae_friendly::v3>));
136
137
138 int nullary() { return 16; }
139 int unary(int i) { return 17 + i; }
140 int binary1(int i, object &) { return 18 + i; }
141 int binary2(int i, object const &) { return 19 + i; }
142 //FIXME
143 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(), sfinae_friendly::v1>));
144 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(), sfinae_friendly::v2>));
145 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(), sfinae_friendly::v3>));
146 //
147 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int), sfinae_friendly::v0>));
148 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int), sfinae_friendly::v1>));
149 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int), sfinae_friendly::v2>));
150 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int), sfinae_friendly::v3>));
151 //
152 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object &), sfinae_friendly::v0>));
153 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object &), sfinae_friendly::v1>));
154 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object &), sfinae_friendly::v2>));
155 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object &), sfinae_friendly::v3>));
156 //
157 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object const &), sfinae_friendly::v0>));
158 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object const &), sfinae_friendly::v1>));
159 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object const &), sfinae_friendly::v2>));
160 //SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<int(*)(int, object const &), sfinae_friendly::v3>));
161
162 typedef int (* func_ptr)(int);
163 typedef int (* const c_func_ptr)(int);
164 typedef int (* volatile v_func_ptr)(int);
165 typedef int (* const volatile cv_func_ptr)(int);
166
167 func_ptr func_ptr1 = &unary;
168 c_func_ptr func_ptr2 = &unary;
169 v_func_ptr func_ptr3 = &unary;
170 cv_func_ptr func_ptr4 = &unary;
171
172 class members
173 {
174 public:
175 int data;
176
177 members()
178 : data(20)
179 { }
180
181 int nullary() { return data + 1; }
182 int nullary_c() const { return data + 2; }
183 int unary(int i) { return data + 3 + i; }
184 int unary_c(int i) const { return data + 4 + i; }
185 int binary(int i, object) { return data + 5 + i; }
186 int binary_c(int i, object) const { return data + 6 + i; }
187 };
188
189 #ifdef BOOST_NO_CXX11_SMART_PTR
190 typedef std::auto_ptr<members > members_ptr;
191 typedef std::auto_ptr<members const> const_members_ptr;
192 #else
193 typedef std::unique_ptr<members > members_ptr;
194 typedef std::unique_ptr<members const> const_members_ptr;
195 #endif
196
197 struct derived
198 : members
199 {
200 };
201
202 #ifdef BOOST_NO_CXX11_SMART_PTR
203 typedef std::auto_ptr<derived > derived_ptr;
204 typedef std::auto_ptr<derived const> const_derived_ptr;
205 #else
206 typedef std::unique_ptr<derived > derived_ptr;
207 typedef std::unique_ptr<derived const> const_derived_ptr;
208 #endif
209
210
211 typedef int element1_type;
212 typedef object element2_type;
213 typedef object_nc & element3_type;
214
215 int element1 = 100;
216 object element2 = object();
217 object_nc element3;
218
219 members that;
220
221 members_ptr spt_that(new members);
222 const_members_ptr spt_that_c(new members);
223
224 typedef fusion::single_view<members > sv_obj;
225 typedef fusion::single_view<members &> sv_ref;
226 typedef fusion::single_view<members *> sv_ptr;
227 typedef fusion::single_view<members const > sv_obj_c;
228 typedef fusion::single_view<members const &> sv_ref_c;
229 typedef fusion::single_view<members const *> sv_ptr_c;
230 typedef fusion::single_view<members_ptr const &> sv_spt;
231 typedef fusion::single_view<const_members_ptr const &> sv_spt_c;
232
233 sv_obj sv_obj_ctx( that);
234 sv_ref sv_ref_ctx( that);
235 sv_ptr sv_ptr_ctx(& that);
236 sv_obj_c sv_obj_c_ctx( that);
237 sv_ref_c sv_ref_c_ctx( that);
238 sv_ptr_c sv_ptr_c_ctx(& that);
239 sv_spt sv_spt_ctx(spt_that);
240 sv_spt_c sv_spt_c_ctx(spt_that_c);
241 template <typename F, typename S>
242 struct sv_helper
243 {
244 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_obj , S>::type>));
245 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ref , S>::type>));
246 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ptr , S>::type>));
247 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_obj_c, S>::type>));
248 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ref_c, S>::type>));
249 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ptr_c, S>::type>));
250 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_spt , S>::type>));
251 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_spt_c, S>::type>));
252 };
253 // FIXME:
254 //template struct sv_helper<int (members::*)() , sfinae_friendly::v1>;
255 //template struct sv_helper<int (members::*)() , sfinae_friendly::v2>;
256 //template struct sv_helper<int (members::*)() , sfinae_friendly::v3>;
257 //template struct sv_helper<int (members::*)() const, sfinae_friendly::v1>;
258 //template struct sv_helper<int (members::*)() const, sfinae_friendly::v2>;
259 //template struct sv_helper<int (members::*)() const, sfinae_friendly::v3>;
260
261 //template struct sv_helper<int (members::*)(int) , sfinae_friendly::v0>;
262 //template struct sv_helper<int (members::*)(int) , sfinae_friendly::v1>;
263 //template struct sv_helper<int (members::*)(int) , sfinae_friendly::v2>;
264 //template struct sv_helper<int (members::*)(int) , sfinae_friendly::v3>;
265 //template struct sv_helper<int (members::*)(int) const, sfinae_friendly::v0>;
266 //template struct sv_helper<int (members::*)(int) const, sfinae_friendly::v1>;
267 //template struct sv_helper<int (members::*)(int) const, sfinae_friendly::v2>;
268 //template struct sv_helper<int (members::*)(int) const, sfinae_friendly::v3>;
269
270 //template struct sv_helper<int (members::*)(int, object) , sfinae_friendly::v0>;
271 //template struct sv_helper<int (members::*)(int, object) , sfinae_friendly::v1>;
272 //template struct sv_helper<int (members::*)(int, object) , sfinae_friendly::v2>;
273 //template struct sv_helper<int (members::*)(int, object) , sfinae_friendly::v3>;
274 //template struct sv_helper<int (members::*)(int, object) const, sfinae_friendly::v0>;
275 //template struct sv_helper<int (members::*)(int, object) const, sfinae_friendly::v1>;
276 //template struct sv_helper<int (members::*)(int, object) const, sfinae_friendly::v2>;
277 //template struct sv_helper<int (members::*)(int, object) const, sfinae_friendly::v3>;
278
279 derived derived_that;
280
281 derived_ptr spt_derived_that(new derived);
282 const_derived_ptr spt_derived_that_c(new derived);
283
284 typedef fusion::single_view<derived > sv_obj_d;
285 typedef fusion::single_view<derived &> sv_ref_d;
286 typedef fusion::single_view<derived *> sv_ptr_d;
287 typedef fusion::single_view<derived const > sv_obj_c_d;
288 typedef fusion::single_view<derived const &> sv_ref_c_d;
289 typedef fusion::single_view<derived const *> sv_ptr_c_d;
290 typedef fusion::single_view<derived_ptr const &> sv_spt_d;
291 typedef fusion::single_view<const_derived_ptr const &> sv_spt_c_d;
292
293 sv_obj_d sv_obj_d_ctx( derived_that);
294 sv_ref_d sv_ref_d_ctx( derived_that);
295 sv_ptr_d sv_ptr_d_ctx(& derived_that);
296 sv_obj_c_d sv_obj_c_d_ctx( derived_that);
297 sv_ref_c_d sv_ref_c_d_ctx( derived_that);
298 sv_ptr_c_d sv_ptr_c_d_ctx(& derived_that);
299 sv_spt_d sv_spt_d_ctx(spt_derived_that);
300 sv_spt_c_d sv_spt_c_d_ctx(spt_derived_that_c);
301 template <typename F, typename S>
302 struct sv_d_helper
303 {
304 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_obj_d , S>::type>));
305 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ref_d , S>::type>));
306 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ptr_d , S>::type>));
307 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_obj_c_d, S>::type>));
308 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ref_c_d, S>::type>));
309 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_ptr_c_d, S>::type>));
310 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_spt_d , S>::type>));
311 SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke<F, typename fusion::result_of::join<sv_spt_c_d, S>::type>));
312 };
313 // FIXME:
314 //template struct sv_d_helper<int (members::*)() , sfinae_friendly::v1>;
315 //template struct sv_d_helper<int (members::*)() , sfinae_friendly::v2>;
316 //template struct sv_d_helper<int (members::*)() , sfinae_friendly::v3>;
317 //template struct sv_d_helper<int (members::*)() const, sfinae_friendly::v1>;
318 //template struct sv_d_helper<int (members::*)() const, sfinae_friendly::v2>;
319 //template struct sv_d_helper<int (members::*)() const, sfinae_friendly::v3>;
320
321 //template struct sv_d_helper<int (members::*)(int) , sfinae_friendly::v0>;
322 //template struct sv_d_helper<int (members::*)(int) , sfinae_friendly::v1>;
323 //template struct sv_d_helper<int (members::*)(int) , sfinae_friendly::v2>;
324 //template struct sv_d_helper<int (members::*)(int) , sfinae_friendly::v3>;
325 //template struct sv_d_helper<int (members::*)(int) const, sfinae_friendly::v0>;
326 //template struct sv_d_helper<int (members::*)(int) const, sfinae_friendly::v1>;
327 //template struct sv_d_helper<int (members::*)(int) const, sfinae_friendly::v2>;
328 //template struct sv_d_helper<int (members::*)(int) const, sfinae_friendly::v3>;
329
330 //template struct sv_d_helper<int (members::*)(int, object) , sfinae_friendly::v0>;
331 //template struct sv_d_helper<int (members::*)(int, object) , sfinae_friendly::v1>;
332 //template struct sv_d_helper<int (members::*)(int, object) , sfinae_friendly::v2>;
333 //template struct sv_d_helper<int (members::*)(int, object) , sfinae_friendly::v3>;
334 //template struct sv_d_helper<int (members::*)(int, object) const, sfinae_friendly::v0>;
335 //template struct sv_d_helper<int (members::*)(int, object) const, sfinae_friendly::v1>;
336 //template struct sv_d_helper<int (members::*)(int, object) const, sfinae_friendly::v2>;
337 //template struct sv_d_helper<int (members::*)(int, object) const, sfinae_friendly::v3>;
338
339 template <class Sequence>
340 void test_sequence_n(Sequence & seq, mpl::int_<0>)
341 {
342 // Function Objects
343
344 nullary_fobj f;
345
346 BOOST_TEST(f () == fusion::invoke(f , seq ));
347 BOOST_TEST(f () == fusion::invoke(f , const_(seq)));
348
349 // Note: The function object is taken by value, so we request the copy
350 // to be const with an explicit template argument. We can also request
351 // the function object to be pased by reference...
352 BOOST_TEST(const_(f)() == fusion::invoke<nullary_fobj const >(const_(f), seq ));
353 BOOST_TEST(const_(f)() == fusion::invoke<nullary_fobj const &>(const_(f), const_(seq)));
354
355 nullary_fobj_nc nc_f;
356 // ...and we further ensure there is no copying in this case, using a
357 // noncopyable function object.
358 BOOST_TEST(nc_f () == fusion::invoke<nullary_fobj_nc &>(nc_f , seq ));
359 BOOST_TEST(nc_f () == fusion::invoke<nullary_fobj_nc &>(nc_f , const_(seq)));
360 BOOST_TEST(const_(nc_f)() == fusion::invoke<nullary_fobj_nc const &>(const_(nc_f), seq ));
361 BOOST_TEST(const_(nc_f)() == fusion::invoke<nullary_fobj_nc const &>(const_(nc_f), const_(seq)));
362
363 // Builtin Functions
364
365 // Call through ref/ptr to function
366 BOOST_TEST(nullary() == fusion::invoke<int (&)()>(nullary, seq));
367 BOOST_TEST(nullary() == fusion::invoke(& nullary, seq));
368
369 // Call through ptr to member function
370 // Note: The non-const function members::nullary can't be invoked with
371 // fusion::join(sv_obj_ctx,seq)), which is const and so is its first element
372 BOOST_TEST(that.nullary() == fusion::invoke(& members::nullary, fusion::join(sv_ref_ctx,seq)));
373 BOOST_TEST(that.nullary() == fusion::invoke(& members::nullary, fusion::join(sv_ptr_ctx,seq)));
374 BOOST_TEST(that.nullary() == fusion::invoke(& members::nullary, fusion::join(sv_spt_ctx,seq)));
375 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_obj_ctx,seq)));
376 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_ref_ctx,seq)));
377 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_ptr_ctx,seq)));
378 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_spt_ctx,seq)));
379 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_obj_c_ctx,seq)));
380 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_ref_c_ctx,seq)));
381 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_ptr_c_ctx,seq)));
382 BOOST_TEST(that.nullary_c() == fusion::invoke(& members::nullary_c, fusion::join(sv_spt_c_ctx,seq)));
383
384 // Pointer to data member
385
386 // $$$ JDG $$$ disabling this test due to C++11 error: assignment of read-only location
387 //~ BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_obj_ctx,seq)) = that.data));
388 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_ref_ctx,seq)) = that.data));
389 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_ptr_ctx,seq)) = that.data));
390 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_spt_ctx,seq)) = that.data));
391 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_obj_c_ctx,seq)));
392 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_ref_c_ctx,seq)));
393 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_ptr_c_ctx,seq)));
394 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_spt_c_ctx,seq)));
395
396 // $$$ JDG $$$ disabling this test due to C++11 error: assignment of read-only location
397 //~ BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_obj_d_ctx,seq)) = that.data));
398 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_ref_d_ctx,seq)) = that.data));
399 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_ptr_d_ctx,seq)) = that.data));
400 BOOST_TEST(that.data == (fusion::invoke(& members::data, fusion::join(sv_spt_d_ctx,seq)) = that.data));
401 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_obj_c_d_ctx,seq)));
402 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_ref_c_d_ctx,seq)));
403 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_ptr_c_d_ctx,seq)));
404 BOOST_TEST(that.data == fusion::invoke(& members::data, fusion::join(sv_spt_c_d_ctx,seq)));
405 }
406
407 template <class Sequence>
408 void test_sequence_n(Sequence & seq, mpl::int_<1>)
409 {
410 fobj f;
411 BOOST_TEST(f(element1) == fusion::invoke(f , seq ));
412 BOOST_TEST(f(element1) == fusion::invoke(f , const_(seq)));
413 BOOST_TEST(const_(f)(element1) == fusion::invoke<fobj const >(const_(f), seq ));
414 BOOST_TEST(const_(f)(element1) == fusion::invoke<fobj const &>(const_(f), const_(seq)));
415
416 fobj_nc nc_f;
417 BOOST_TEST(nc_f(element1) == fusion::invoke<fobj_nc &>(nc_f, seq ));
418 BOOST_TEST(nc_f(element1) == fusion::invoke<fobj_nc &>(nc_f, const_(seq)));
419 BOOST_TEST(const_(nc_f)(element1) == fusion::invoke<fobj_nc const &>(const_(nc_f), seq ));
420 BOOST_TEST(const_(nc_f)(element1) == fusion::invoke<fobj_nc const &>(const_(nc_f), const_(seq)));
421
422 BOOST_TEST(unary(element1) == fusion::invoke<int (&)(int)>(unary, seq));
423 BOOST_TEST(func_ptr1(element1) == fusion::invoke(func_ptr1, seq));
424 BOOST_TEST(func_ptr2(element1) == fusion::invoke(func_ptr2, seq));
425 BOOST_TEST(func_ptr3(element1) == fusion::invoke(func_ptr3, seq));
426 BOOST_TEST(func_ptr4(element1) == fusion::invoke(func_ptr4, seq));
427
428 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_ref_ctx,seq)));
429 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_ptr_ctx,seq)));
430 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_spt_ctx,seq)));
431 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_obj_ctx,seq)));
432 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ref_ctx,seq)));
433 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ptr_ctx,seq)));
434 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_spt_ctx,seq)));
435 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_obj_c_ctx,seq)));
436 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ref_c_ctx,seq)));
437 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ptr_c_ctx,seq)));
438 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_spt_c_ctx,seq)));
439
440 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_ref_d_ctx,seq)));
441 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_ptr_d_ctx,seq)));
442 BOOST_TEST(that.unary(element1) == fusion::invoke(& members::unary, fusion::join(sv_spt_d_ctx,seq)));
443 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_obj_d_ctx,seq)));
444 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ref_d_ctx,seq)));
445 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ptr_d_ctx,seq)));
446 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_spt_d_ctx,seq)));
447 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_obj_c_d_ctx,seq)));
448 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ref_c_d_ctx,seq)));
449 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_ptr_c_d_ctx,seq)));
450 BOOST_TEST(that.unary_c(element1) == fusion::invoke(& members::unary_c, fusion::join(sv_spt_c_d_ctx,seq)));
451 }
452
453 template <class Sequence>
454 void test_sequence_n(Sequence & seq, mpl::int_<2>)
455 {
456 fobj f;
457 BOOST_TEST(f (element1, element2) == fusion::invoke(f , seq));
458 BOOST_TEST(f (element1, const_(element2)) == fusion::invoke(f , const_(seq)));
459 BOOST_TEST(const_(f)(element1, element2) == fusion::invoke<fobj const>(const_(f), seq));
460 BOOST_TEST(const_(f)(element1, const_(element2)) == fusion::invoke<fobj const>(const_(f), const_(seq)));
461
462 BOOST_TEST(binary1(element1, element2) == fusion::invoke(binary1, seq));
463 BOOST_TEST(binary2(element1, element2) == fusion::invoke(binary2, seq));
464
465 BOOST_TEST(that.binary(element1,element2) == fusion::invoke(& members::binary, fusion::join(sv_ref_ctx,seq)));
466 BOOST_TEST(that.binary(element1,element2) == fusion::invoke(& members::binary, fusion::join(sv_ptr_ctx,seq)));
467 BOOST_TEST(that.binary(element1,element2) == fusion::invoke(& members::binary, fusion::join(sv_spt_ctx,seq)));
468 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_obj_ctx,seq)));
469 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_ref_ctx,seq)));
470 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_ptr_ctx,seq)));
471 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_spt_ctx,seq)));
472 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_obj_c_ctx,seq)));
473 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_ref_c_ctx,seq)));
474 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_ptr_c_ctx,seq)));
475 BOOST_TEST(that.binary_c(element1,element2) == fusion::invoke(& members::binary_c, fusion::join(sv_spt_c_ctx,seq)));
476 }
477
478 template <class Sequence>
479 void test_sequence_n(Sequence & seq, mpl::int_<3>)
480 {
481 fobj f;
482
483 BOOST_TEST(f(element1, element2, element3) == fusion::invoke(f, seq));
484 BOOST_TEST(const_(f)(element1, element2, element3) == fusion::invoke<fobj const>(const_(f), seq));
485 }
486
487 template <class Sequence>
488 void test_sequence(Sequence & seq)
489 {
490 test_sequence_n(seq, mpl::int_<boost::fusion::result_of::size<Sequence>::value>());
491 }
492
493
494 void result_type_tests()
495 {
496 using boost::is_same;
497
498 BOOST_TEST(( is_same<
499 boost::fusion::result_of::invoke<int (*)(), fusion::vector0<> >::type, int
500 >::value ));
501 // disabled until boost::result_of supports it
502 // BOOST_TEST(( is_same<
503 // boost::fusion::result_of::invoke<int (*)(...), fusion::vector1<int> >::type, int
504 // >::value ));
505 BOOST_TEST(( is_same<
506 boost::fusion::result_of::invoke<int (members::*)(), fusion::vector1<members*> >::type, int
507 >::value ));
508 // disabled until boost::result_of supports it
509 // BOOST_TEST(( is_same<
510 // boost::fusion::result_of::invoke<int (members::*)(...), fusion::vector2<members*,int> >::type, int
511 // >::value ));
512 }
513
514 int main()
515 {
516 result_type_tests();
517
518 typedef fusion::vector<> vector0;
519 typedef fusion::vector<element1_type> vector1;
520 typedef fusion::vector<element1_type, element2_type> vector2;
521 typedef fusion::vector<element1_type, element2_type, element3_type> vector3;
522
523 vector0 v0;
524 vector1 v1(element1);
525 vector2 v2(element1, element2);
526
527 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
528 // Note: C++11 will pickup the rvalue overload for the d argument
529 // since we do not have all permutations (expensive!) for all const&
530 // and && arguments. We either have all && or all const& arguments only.
531 // For that matter, use std::ref to disambiguate the call.
532
533 vector3 v3(element1, element2, std::ref(element3));
534 #else
535 vector3 v3(element1, element2, element3);
536 #endif
537
538 test_sequence(v0);
539 test_sequence(v1);
540 test_sequence(v2);
541 test_sequence(v3);
542
543 typedef fusion::list<> list0;
544 typedef fusion::list<element1_type> list1;
545 typedef fusion::list<element1_type, element2_type> list2;
546 typedef fusion::list<element1_type, element2_type, element3_type> list3;
547
548 list0 l0;
549 list1 l1(element1);
550 list2 l2(element1, element2);
551 list3 l3(element1, element2, element3);
552
553 test_sequence(l0);
554 test_sequence(l1);
555 test_sequence(l2);
556 test_sequence(l3);
557
558 return boost::report_errors();
559 }
560