1 /*=============================================================================
2 Copyright (c) 2006-2007 Tobias Schwinger
3
4 Use modification and distribution are subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 ==============================================================================*/
8
9 #include <boost/fusion/functional/adapter/unfused.hpp>
10 #include <boost/detail/lightweight_test.hpp>
11
12 #include <boost/noncopyable.hpp>
13
14 #include <boost/mpl/empty_base.hpp>
15 #include <boost/mpl/identity.hpp>
16
17 #include <boost/utility/result_of.hpp>
18
19 #include <boost/fusion/sequence/intrinsic/empty.hpp>
20 #include <boost/fusion/algorithm/iteration/fold.hpp>
21
22 namespace fusion = boost::fusion;
23 namespace mpl = boost::mpl;
24
25 using boost::noncopyable;
26
27 template <class Base = boost::mpl::empty_base>
28 struct test_func
29 : Base
30 {
31 template <typename Sig>
32 struct result;
33
34 template <class Self, class Seq>
35 struct result< Self(Seq) >
36 : mpl::identity<long>
37 { };
38
39 template <typename Seq>
operator ()test_func40 long operator()(Seq const & seq) const
41 {
42 long state = 0;
43 return fusion::fold(seq, state, fold_op());
44 }
45
46 template <typename Seq>
operator ()test_func47 long operator()(Seq const & seq)
48 {
49 long state = 100;
50 return fusion::fold(seq, state, fold_op());
51 }
52
53 private:
54
55 struct fold_op
56 {
57 typedef long result_type;
58
59 template <typename T>
operator ()test_func::fold_op60 long operator()(long value, T & elem) const
61 {
62 elem += sizeof(T);
63 return value + elem;
64 }
65 };
66 };
67
result_type_tests()68 void result_type_tests()
69 {
70 using boost::is_same;
71
72 typedef fusion::unfused< test_func<> > t;
73 BOOST_TEST(( is_same< boost::result_of< t () >::type, long >::value ));
74 BOOST_TEST(( is_same< boost::result_of< t (int &) >::type, long >::value ));
75 }
76
main()77 int main()
78 {
79 result_type_tests();
80
81 test_func<noncopyable> f;
82 fusion::unfused< test_func<> > unfused_func;
83 fusion::unfused< test_func<noncopyable> & > unfused_func_ref(f);
84 fusion::unfused< test_func<> const > unfused_func_c;
85 fusion::unfused< test_func<> > const unfused_func_c2;
86 fusion::unfused< test_func<noncopyable> const & > unfused_func_c_ref(f);
87
88 BOOST_TEST(unfused_func() == 100);
89 BOOST_TEST(unfused_func_ref() == 100);
90 BOOST_TEST(unfused_func_c() == 0);
91 BOOST_TEST(unfused_func_c2() == 0);
92 BOOST_TEST(unfused_func_c_ref() == 0);
93
94 long lv1 = 2; int lv2 = 3l; char lv3 = '\007';
95 long expected;
96
97 expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
98 BOOST_TEST(unfused_func(lv1,lv2,lv3) == 100 + expected);
99 BOOST_TEST(lv1 == 2+1*sizeof(lv1) && lv2 == 3+1*sizeof(lv2) && lv3 == 7+1*sizeof(lv3));
100
101 expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
102 BOOST_TEST(unfused_func_ref(lv1,lv2,lv3) == 100 + expected);
103 BOOST_TEST(lv1 == 2+2*sizeof(lv1) && lv2 == 3+2*sizeof(lv2) && lv3 == 7+2*sizeof(lv3));
104
105 expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
106 BOOST_TEST(unfused_func_c(lv1,lv2,lv3) == 0 + expected);
107 BOOST_TEST(lv1 == 2+3*sizeof(lv1) && lv2 == 3+3*sizeof(lv2) && lv3 == 7+3*sizeof(lv3));
108
109 expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
110 BOOST_TEST(unfused_func_c2(lv1,lv2,lv3) == 0 + expected);
111 BOOST_TEST(lv1 == 2+4*sizeof(lv1) && lv2 == 3+4*sizeof(lv2) && lv3 == 7+4*sizeof(lv3));
112
113 expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
114 BOOST_TEST(unfused_func_c_ref(lv1,lv2,lv3) == 0 + expected);
115 BOOST_TEST(lv1 == 2+5*sizeof(lv1) && lv2 == 3+5*sizeof(lv2) && lv3 == 7+5*sizeof(lv3));
116
117 return boost::report_errors();
118 }
119
120