• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2007 Joel de Guzman
3     Copyright (c) 2015      John Fletcher
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #include <iostream>
9 #include <cmath>
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/phoenix/core.hpp>
12 #include <boost/phoenix/operator.hpp>
13 #include <boost/phoenix/bind.hpp>
14 
15 namespace phoenix = boost::phoenix;
16 using std::cout;
17 using std::pow;
18 
19     struct test
20     {
21         typedef void result_type;
22 
23         void
operator ()test24         operator()() const
25         {
26             cout << "Test lazy functions...\n";
27         }
28     };
29 
30     struct sqr
31     {
32         template <typename Sig>
33         struct result;
34 
35         template <typename This, typename Arg>
36         struct result<This(Arg&)>
37         {
38             typedef Arg type;
39         };
40 
41         template <typename Arg>
42         Arg
operator ()sqr43         operator()(Arg n) const
44         {
45             return n * n;
46         }
47     };
48 
49     struct fact
50     {
51         template <typename Sig>
52         struct result;
53 
54         template <typename This, typename Arg>
55         struct result<This(Arg&)>
56         {
57             typedef Arg type;
58         };
59 
60         template <typename Arg>
61         Arg
operator ()fact62         operator()(Arg n) const
63         {
64             return (n <= 0) ? 1 : n * (*this)(n-1);
65         }
66     };
67 
68     struct power
69     {
70         template<typename Sig>
71         struct result;
72 
73         template<typename This, typename Arg1, typename Arg2>
74         struct result<This(Arg1&, Arg2&)>
75         {
76             typedef Arg1 type;
77         };
78 
79         template <typename Arg1, typename Arg2>
80         Arg1
operator ()power81         operator()(Arg1 a, Arg2 b) const
82         {
83             return pow(a, b);
84         }
85     };
86 
87     struct add
88     {
89         template <typename Sig>
90         struct result;
91 
92         template <typename This, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
93         struct result<This(Arg1&, Arg2&, Arg3&, Arg4&)>
94         {
95             typedef Arg1 type;
96         };
97 
98         template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
99         Arg1
operator ()add100         operator()(Arg1 a, Arg2 b, Arg3 c, Arg4 d) const
101         {
102             return a + b + c + d;
103         }
104     };
105 
106 int
main()107 main()
108 {
109     using phoenix::bind;
110     using phoenix::ref;
111     using phoenix::arg_names::_1;
112     using phoenix::arg_names::arg1;
113     using phoenix::arg_names::arg2;
114 
115     int i5 = 5;
116     double d5 = 5, d3 = 3;
117 
118     test()();
119     BOOST_TEST(bind(sqr(), arg1)(i5) == (i5*i5));
120     BOOST_TEST(bind(fact(), 4)() == 24);
121     BOOST_TEST(bind(fact(), arg1)(i5) == 120);
122     BOOST_TEST((int)bind(power(), arg1, arg2)(d5, d3) == (int)std::pow(d5, d3));
123     BOOST_TEST((bind(sqr(), arg1) + 5)(i5) == ((i5*i5)+5));
124     BOOST_TEST(bind(add(), arg1, arg1, arg1, arg1)(i5) == (5+5+5+5));
125 
126     int const ic5 = 5;
127     // testing consts
128     BOOST_TEST(bind(sqr(), arg1)(ic5) == (ic5*ic5));
129 
130     // From Steven Watanabe
131     sqr s;
132     int x = 2;
133     int result = bind(ref(s), _1)(x);
134     BOOST_TEST(result == 4);
135 
136     return boost::report_errors();
137 }
138