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
15namespace phoenix = boost::phoenix;
16using std::cout;
17using std::pow;
18
19 struct test
20 {
21 typedef void result_type;
22
23 void
24 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
43 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
62 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
81 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
100 operator()(Arg1 a, Arg2 b, Arg3 c, Arg4 d) const
101 {
102 return a + b + c + d;
103 }
104 };
105
106int
107main()
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(f: ref(t&: s), a: _1)(x);
134 BOOST_TEST(result == 4);
135
136 return boost::report_errors();
137}
138

source code of boost/libs/phoenix/test/bind/bind_function_object_tests.cpp