]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/yap/test/call_expr.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / yap / test / call_expr.cpp
1 // Copyright (C) 2016-2018 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <boost/yap/expression.hpp>
7
8 #include <boost/core/lightweight_test.hpp>
9
10 #include <sstream>
11
12
13 template<typename T>
14 using term = boost::yap::terminal<boost::yap::expression, T>;
15
16 template<typename T>
17 using ref = boost::yap::expression_ref<boost::yap::expression, T>;
18
19 namespace yap = boost::yap;
20 namespace bh = boost::hana;
21
22
23 namespace user {
24
25 struct number
26 {
27 explicit operator double() const { return value; }
28
29 double value;
30 };
31
32 number naxpy(number a, number x, number y)
33 {
34 return number{a.value * x.value + y.value + 10.0};
35 }
36
37 struct tag_type
38 {};
39
40 inline number tag_function(double a, double b) { return number{a + b}; }
41
42 struct eval_xform_tag
43 {
44 decltype(auto) operator()(
45 yap::expr_tag<yap::expr_kind::call>, tag_type, number a, double b)
46 {
47 return tag_function(a.value, b);
48 }
49
50 int operator()(
51 yap::expr_tag<yap::expr_kind::call>, tag_type, double a, double b)
52 {
53 return 42;
54 }
55
56 char const * operator()() { return "42"; }
57 };
58
59 struct empty_xform
60 {};
61
62 struct eval_xform_expr
63 {
64 decltype(auto) operator()(yap::expression<
65 yap::expr_kind::call,
66 bh::tuple<
67 ref<term<user::tag_type>>,
68 term<user::number>,
69 term<int>>> const & expr)
70 {
71 using namespace boost::hana::literals;
72 return tag_function(
73 (double)yap::value(expr.elements[1_c]).value,
74 (double)yap::value(expr.elements[2_c]));
75 }
76
77 decltype(auto) operator()(yap::expression<
78 yap::expr_kind::call,
79 bh::tuple<
80 ref<term<user::tag_type>>,
81 ref<term<user::number>>,
82 term<int>>> const & expr)
83 {
84 using namespace boost::hana::literals;
85 return tag_function(
86 (double)yap::value(expr.elements[1_c]).value,
87 (double)yap::value(expr.elements[2_c]));
88 }
89 };
90
91 struct eval_xform_both
92 {
93 decltype(auto) operator()(
94 yap::expr_tag<yap::expr_kind::call>,
95 tag_type,
96 user::number a,
97 double b)
98 {
99 return tag_function(a.value, b);
100 }
101
102 decltype(auto) operator()(yap::expression<
103 yap::expr_kind::call,
104 bh::tuple<
105 ref<term<user::tag_type>>,
106 term<user::number>,
107 term<int>>> const & expr)
108 {
109 using namespace boost::hana::literals;
110 throw std::logic_error("Oops! Picked the wrong overload!");
111 return tag_function(
112 (double)yap::value(expr.elements[1_c]).value,
113 (double)yap::value(expr.elements[2_c]));
114 }
115
116 decltype(auto) operator()(yap::expression<
117 yap::expr_kind::call,
118 bh::tuple<
119 ref<term<user::tag_type>>,
120 ref<term<user::number>>,
121 term<int>>> const & expr)
122 {
123 using namespace boost::hana::literals;
124 throw std::logic_error("Oops! Picked the wrong overload!");
125 return tag_function(
126 (double)yap::value(expr.elements[1_c]).value,
127 (double)yap::value(expr.elements[2_c]));
128 }
129 };
130 }
131
132
133 int main()
134 {
135 {
136 using namespace boost::yap::literals;
137
138 {
139 auto plus = yap::make_terminal(user::tag_type{});
140 auto expr = plus(user::number{13}, 1);
141
142 {
143 transform(expr, user::empty_xform{});
144 }
145
146 {
147 user::number result = transform(expr, user::eval_xform_tag{});
148 BOOST_TEST(result.value == 14);
149 }
150
151 {
152 user::number result = transform(expr, user::eval_xform_expr{});
153 BOOST_TEST(result.value == 14);
154 }
155
156 {
157 user::number result = transform(expr, user::eval_xform_both{});
158 BOOST_TEST(result.value == 14);
159 }
160 }
161
162 {
163 auto plus = yap::make_terminal(user::tag_type{});
164 auto thirteen = yap::make_terminal(user::number{13});
165 auto expr = plus(thirteen, 1);
166
167 {
168 user::number result = transform(expr, user::eval_xform_tag{});
169 BOOST_TEST(result.value == 14);
170 }
171
172 {
173 user::number result = transform(expr, user::eval_xform_expr{});
174 BOOST_TEST(result.value == 14);
175 }
176
177 {
178 user::number result = transform(expr, user::eval_xform_both{});
179 BOOST_TEST(result.value == 14);
180 }
181 }
182
183 {
184 term<user::number> a{{1.0}};
185 term<user::number> x{{42.0}};
186 term<user::number> y{{3.0}};
187 auto n = yap::make_terminal(user::naxpy);
188
189 auto expr = n(a, x, y);
190 {
191 user::number result = evaluate(expr);
192 BOOST_TEST(result.value == 55);
193 }
194 }
195 }
196
197 return boost::report_errors();
198 }