• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/generation/make_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/if.hpp>
16 #include <boost/mpl/and.hpp>
17 #include <boost/mpl/not.hpp>
18 #include <boost/mpl/bool.hpp>
19 
20 #include <boost/utility/result_of.hpp>
21 #include <boost/core/enable_if.hpp>
22 
23 #include <boost/fusion/sequence/intrinsic/empty.hpp>
24 #include <boost/fusion/algorithm/iteration/fold.hpp>
25 
26 #include <boost/ref.hpp>
27 
28 namespace fusion = boost::fusion;
29 namespace mpl = boost::mpl;
30 
31 using boost::noncopyable;
32 typedef mpl::true_ no_nullary_call;
33 
34 using boost::ref;
35 using boost::cref;
36 
37 template <class Base = mpl::empty_base, class RemoveNullary = mpl::false_>
38 struct test_func
39     : Base
40 {
41     template <typename Sig>
42     struct result;
43 
44     template <class Self, class Seq>
45     struct result< Self(Seq &) >
46         : boost::enable_if<
47               mpl::not_<mpl::and_<boost::fusion::result_of::empty<Seq>, RemoveNullary> >,
48               long>
49     { };
50 
51     template <typename Seq>
operator ()test_func52     long operator()(Seq const & seq) const
53     {
54         long state = 0;
55         return fusion::fold(seq, state, fold_op());
56     }
57 
58     template < typename Seq >
operator ()test_func59     long operator()(Seq const & seq)
60     {
61         long state = 100;
62         return fusion::fold(seq, state, fold_op());
63     }
64 
65   private:
66 
67     struct fold_op
68     {
69         typedef long result_type;
70 
71         template <typename T>
operator ()test_func::fold_op72         long operator()(long value, T & elem) const
73         {
74           elem += sizeof(T);
75           return value + elem;
76         }
77     };
78 };
79 
80 template <typename T>
const_(T const & t)81 inline T const & const_(T const & t)
82 {
83     return t;
84 }
85 
main()86 int main()
87 {
88     test_func<> f;
89     test_func<noncopyable> f_nc;
90 
91     boost::fusion::result_of::make_unfused< test_func<> >::type unfused_func =
92         fusion::make_unfused(f);
93 
94     boost::fusion::result_of::make_unfused< boost::reference_wrapper<
95         test_func<noncopyable> > >::type unfused_func_ref =
96             fusion::make_unfused(ref(f_nc));
97 
98     boost::fusion::result_of::make_unfused< boost::reference_wrapper<
99         test_func<noncopyable> const> >::type unfused_func_c_ref =
100             fusion::make_unfused(cref(f_nc));
101 
102     BOOST_TEST(unfused_func() == 100);
103     BOOST_TEST(const_(unfused_func)() == 0);
104     BOOST_TEST(unfused_func_ref() == 100);
105     BOOST_TEST(unfused_func_c_ref() == 0);
106 
107     long lv1 = 2; int lv2 = 3l; char lv3 = '\007';
108     long expected;
109 
110     expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
111     BOOST_TEST(unfused_func(lv1,lv2,lv3) == 100 + expected);
112     BOOST_TEST(lv1 == 2+1*sizeof(lv1) && lv2 == 3+1*sizeof(lv2) && lv3 == 7+1*sizeof(lv3));
113 
114     expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
115     BOOST_TEST(const_(unfused_func)(lv1,lv2,lv3) == 0 + expected);
116     BOOST_TEST(lv1 == 2+2*sizeof(lv1) && lv2 == 3+2*sizeof(lv2) && lv3 == 7+2*sizeof(lv3));
117 
118     expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
119     BOOST_TEST(unfused_func_ref(lv1,lv2,lv3) == 100 + expected);
120     BOOST_TEST(lv1 == 2+3*sizeof(lv1) && lv2 == 3+3*sizeof(lv2) && lv3 == 7+3*sizeof(lv3));
121 
122     expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
123     BOOST_TEST(unfused_func_c_ref(lv1,lv2,lv3) == 0 + expected);
124     BOOST_TEST(lv1 == 2+4*sizeof(lv1) && lv2 == 3+4*sizeof(lv2) && lv3 == 7+4*sizeof(lv3));
125 
126     return boost::report_errors();
127 }
128 
129