• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     apply.cpp
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #include <boost/hof/apply.hpp>
8 #include "test.hpp"
9 
BOOST_HOF_TEST_CASE()10 BOOST_HOF_TEST_CASE()
11 {
12     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
13     BOOST_HOF_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
14 }
15 
BOOST_HOF_TEST_CASE()16 BOOST_HOF_TEST_CASE()
17 {
18     BOOST_HOF_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
19     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
20 }
21 
22 struct member_sum_f
23 {
24     int i;
member_sum_fmember_sum_f25     constexpr member_sum_f(int x) : i(x)
26     {}
27 
addmember_sum_f28     constexpr int add(int x) const
29     {
30         return i+x;
31     }
32 };
33 
34 struct member_sum_f_derived
35 : member_sum_f
36 {
member_sum_f_derivedmember_sum_f_derived37     constexpr member_sum_f_derived(int x) : member_sum_f(x)
38     {}
39 };
40 
BOOST_HOF_TEST_CASE()41 BOOST_HOF_TEST_CASE()
42 {
43     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
44     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
45 
46 #ifdef __clang__
47     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
48     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
49 #endif
50 
51     static_assert(std::is_base_of<member_sum_f, member_sum_f>::value, "Base of failed");
52     std::unique_ptr<member_sum_f> msp(new member_sum_f(1));
53     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, msp, 2) == 3);
54 
55     std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(1));
56     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, mspd, 2) == 3);
57 }
58 
BOOST_HOF_TEST_CASE()59 BOOST_HOF_TEST_CASE()
60 {
61     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
62     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
63 
64 #ifdef __clang__
65     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
66     BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
67 #endif
68 
69     std::unique_ptr<member_sum_f> msp(new member_sum_f(3));
70     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, msp) == 3);
71 
72     std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(3));
73     BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, mspd) == 3);
74 }
75 
76 
77 struct mem_hash
78 {
79     mutable unsigned int hash;
80 
mem_hashmem_hash81     mem_hash(): hash(0) {}
82 
f0mem_hash83     int f0() { f1(17); return 0; }
g0mem_hash84     int g0() const { g1(17); return 0; }
85 
f1mem_hash86     int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
g1mem_hash87     int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
88 
f2mem_hash89     int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
g2mem_hash90     int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
91 
f3mem_hash92     int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
g3mem_hash93     int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
94 
f4mem_hash95     int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
g4mem_hash96     int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
97 
f5mem_hash98     int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
g5mem_hash99     int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
100 
f6mem_hash101     int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
g6mem_hash102     int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
103 
f7mem_hash104     int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
g7mem_hash105     int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
106 
f8mem_hash107     int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
g8mem_hash108     int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
109 };
110 
BOOST_HOF_TEST_CASE()111 BOOST_HOF_TEST_CASE()
112 {
113 
114     mem_hash x;
115 
116     mem_hash const & rcx = x;
117     mem_hash const * pcx = &x;
118 
119     std::shared_ptr<mem_hash> sp(new mem_hash);
120 
121     boost::hof::apply(&mem_hash::f0, x);
122     boost::hof::apply(&mem_hash::f0, &x);
123     boost::hof::apply(&mem_hash::f0, sp);
124 
125     boost::hof::apply(&mem_hash::g0, x);
126     boost::hof::apply(&mem_hash::g0, rcx);
127     boost::hof::apply(&mem_hash::g0, &x);
128     boost::hof::apply(&mem_hash::g0, pcx);
129     boost::hof::apply(&mem_hash::g0, sp);
130 
131     boost::hof::apply(&mem_hash::f1, x, 1);
132     boost::hof::apply(&mem_hash::f1, &x, 1);
133     boost::hof::apply(&mem_hash::f1, sp, 1);
134 
135     boost::hof::apply(&mem_hash::g1, x, 1);
136     boost::hof::apply(&mem_hash::g1, rcx, 1);
137     boost::hof::apply(&mem_hash::g1, &x, 1);
138     boost::hof::apply(&mem_hash::g1, pcx, 1);
139     boost::hof::apply(&mem_hash::g1, sp, 1);
140 
141     boost::hof::apply(&mem_hash::f2, x, 1, 2);
142     boost::hof::apply(&mem_hash::f2, &x, 1, 2);
143     boost::hof::apply(&mem_hash::f2, sp, 1, 2);
144 
145     boost::hof::apply(&mem_hash::g2, x, 1, 2);
146     boost::hof::apply(&mem_hash::g2, rcx, 1, 2);
147     boost::hof::apply(&mem_hash::g2, &x, 1, 2);
148     boost::hof::apply(&mem_hash::g2, pcx, 1, 2);
149     boost::hof::apply(&mem_hash::g2, sp, 1, 2);
150 
151     boost::hof::apply(&mem_hash::f3, x, 1, 2, 3);
152     boost::hof::apply(&mem_hash::f3, &x, 1, 2, 3);
153     boost::hof::apply(&mem_hash::f3, sp, 1, 2, 3);
154 
155     boost::hof::apply(&mem_hash::g3, x, 1, 2, 3);
156     boost::hof::apply(&mem_hash::g3, rcx, 1, 2, 3);
157     boost::hof::apply(&mem_hash::g3, &x, 1, 2, 3);
158     boost::hof::apply(&mem_hash::g3, pcx, 1, 2, 3);
159     boost::hof::apply(&mem_hash::g3, sp, 1, 2, 3);
160 
161     boost::hof::apply(&mem_hash::f4, x, 1, 2, 3, 4);
162     boost::hof::apply(&mem_hash::f4, &x, 1, 2, 3, 4);
163     boost::hof::apply(&mem_hash::f4, sp, 1, 2, 3, 4);
164 
165     boost::hof::apply(&mem_hash::g4, x, 1, 2, 3, 4);
166     boost::hof::apply(&mem_hash::g4, rcx, 1, 2, 3, 4);
167     boost::hof::apply(&mem_hash::g4, &x, 1, 2, 3, 4);
168     boost::hof::apply(&mem_hash::g4, pcx, 1, 2, 3, 4);
169     boost::hof::apply(&mem_hash::g4, sp, 1, 2, 3, 4);
170 
171     boost::hof::apply(&mem_hash::f5, x, 1, 2, 3, 4, 5);
172     boost::hof::apply(&mem_hash::f5, &x, 1, 2, 3, 4, 5);
173     boost::hof::apply(&mem_hash::f5, sp, 1, 2, 3, 4, 5);
174 
175     boost::hof::apply(&mem_hash::g5, x, 1, 2, 3, 4, 5);
176     boost::hof::apply(&mem_hash::g5, rcx, 1, 2, 3, 4, 5);
177     boost::hof::apply(&mem_hash::g5, &x, 1, 2, 3, 4, 5);
178     boost::hof::apply(&mem_hash::g5, pcx, 1, 2, 3, 4, 5);
179     boost::hof::apply(&mem_hash::g5, sp, 1, 2, 3, 4, 5);
180 
181     boost::hof::apply(&mem_hash::f6, x, 1, 2, 3, 4, 5, 6);
182     boost::hof::apply(&mem_hash::f6, &x, 1, 2, 3, 4, 5, 6);
183     boost::hof::apply(&mem_hash::f6, sp, 1, 2, 3, 4, 5, 6);
184 
185     boost::hof::apply(&mem_hash::g6, x, 1, 2, 3, 4, 5, 6);
186     boost::hof::apply(&mem_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
187     boost::hof::apply(&mem_hash::g6, &x, 1, 2, 3, 4, 5, 6);
188     boost::hof::apply(&mem_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
189     boost::hof::apply(&mem_hash::g6, sp, 1, 2, 3, 4, 5, 6);
190 
191     boost::hof::apply(&mem_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
192     boost::hof::apply(&mem_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
193     boost::hof::apply(&mem_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
194 
195     boost::hof::apply(&mem_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
196     boost::hof::apply(&mem_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
197     boost::hof::apply(&mem_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
198     boost::hof::apply(&mem_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
199     boost::hof::apply(&mem_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
200 
201     boost::hof::apply(&mem_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
202     boost::hof::apply(&mem_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
203     boost::hof::apply(&mem_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
204 
205     boost::hof::apply(&mem_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
206     boost::hof::apply(&mem_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
207     boost::hof::apply(&mem_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
208     boost::hof::apply(&mem_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
209     boost::hof::apply(&mem_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
210 
211     BOOST_HOF_TEST_CHECK(boost::hof::apply(&mem_hash::hash, x) == 17610 && boost::hof::apply(&mem_hash::hash, sp) == 2155);
212 }
213 
214 struct hash_base
215 {
216     mutable unsigned int hash;
217 
hash_basehash_base218     hash_base(): hash(0) {}
219 
f0hash_base220     int f0() { f1(17); return 0; }
g0hash_base221     int g0() const { g1(17); return 0; }
222 
f1hash_base223     int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
g1hash_base224     int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
225 
f2hash_base226     int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
g2hash_base227     int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
228 
f3hash_base229     int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
g3hash_base230     int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
231 
f4hash_base232     int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
g4hash_base233     int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
234 
f5hash_base235     int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
g5hash_base236     int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
237 
f6hash_base238     int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
g6hash_base239     int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
240 
f7hash_base241     int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
g7hash_base242     int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
243 
f8hash_base244     int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
g8hash_base245     int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
246 };
247 
248 struct derived_hash: public hash_base
249 {
250 };
251 
BOOST_HOF_TEST_CASE()252 BOOST_HOF_TEST_CASE()
253 {
254 
255     derived_hash x;
256 
257     derived_hash const & rcx = x;
258     derived_hash const * pcx = &x;
259 
260     std::shared_ptr<derived_hash> sp(new derived_hash);
261 
262     boost::hof::apply(&derived_hash::f0, x);
263     boost::hof::apply(&derived_hash::f0, &x);
264     boost::hof::apply(&derived_hash::f0, sp);
265 
266     boost::hof::apply(&derived_hash::g0, x);
267     boost::hof::apply(&derived_hash::g0, rcx);
268     boost::hof::apply(&derived_hash::g0, &x);
269     boost::hof::apply(&derived_hash::g0, pcx);
270     boost::hof::apply(&derived_hash::g0, sp);
271 
272     boost::hof::apply(&derived_hash::f1, x, 1);
273     boost::hof::apply(&derived_hash::f1, &x, 1);
274     boost::hof::apply(&derived_hash::f1, sp, 1);
275 
276     boost::hof::apply(&derived_hash::g1, x, 1);
277     boost::hof::apply(&derived_hash::g1, rcx, 1);
278     boost::hof::apply(&derived_hash::g1, &x, 1);
279     boost::hof::apply(&derived_hash::g1, pcx, 1);
280     boost::hof::apply(&derived_hash::g1, sp, 1);
281 
282     boost::hof::apply(&derived_hash::f2, x, 1, 2);
283     boost::hof::apply(&derived_hash::f2, &x, 1, 2);
284     boost::hof::apply(&derived_hash::f2, sp, 1, 2);
285 
286     boost::hof::apply(&derived_hash::g2, x, 1, 2);
287     boost::hof::apply(&derived_hash::g2, rcx, 1, 2);
288     boost::hof::apply(&derived_hash::g2, &x, 1, 2);
289     boost::hof::apply(&derived_hash::g2, pcx, 1, 2);
290     boost::hof::apply(&derived_hash::g2, sp, 1, 2);
291 
292     boost::hof::apply(&derived_hash::f3, x, 1, 2, 3);
293     boost::hof::apply(&derived_hash::f3, &x, 1, 2, 3);
294     boost::hof::apply(&derived_hash::f3, sp, 1, 2, 3);
295 
296     boost::hof::apply(&derived_hash::g3, x, 1, 2, 3);
297     boost::hof::apply(&derived_hash::g3, rcx, 1, 2, 3);
298     boost::hof::apply(&derived_hash::g3, &x, 1, 2, 3);
299     boost::hof::apply(&derived_hash::g3, pcx, 1, 2, 3);
300     boost::hof::apply(&derived_hash::g3, sp, 1, 2, 3);
301 
302     boost::hof::apply(&derived_hash::f4, x, 1, 2, 3, 4);
303     boost::hof::apply(&derived_hash::f4, &x, 1, 2, 3, 4);
304     boost::hof::apply(&derived_hash::f4, sp, 1, 2, 3, 4);
305 
306     boost::hof::apply(&derived_hash::g4, x, 1, 2, 3, 4);
307     boost::hof::apply(&derived_hash::g4, rcx, 1, 2, 3, 4);
308     boost::hof::apply(&derived_hash::g4, &x, 1, 2, 3, 4);
309     boost::hof::apply(&derived_hash::g4, pcx, 1, 2, 3, 4);
310     boost::hof::apply(&derived_hash::g4, sp, 1, 2, 3, 4);
311 
312     boost::hof::apply(&derived_hash::f5, x, 1, 2, 3, 4, 5);
313     boost::hof::apply(&derived_hash::f5, &x, 1, 2, 3, 4, 5);
314     boost::hof::apply(&derived_hash::f5, sp, 1, 2, 3, 4, 5);
315 
316     boost::hof::apply(&derived_hash::g5, x, 1, 2, 3, 4, 5);
317     boost::hof::apply(&derived_hash::g5, rcx, 1, 2, 3, 4, 5);
318     boost::hof::apply(&derived_hash::g5, &x, 1, 2, 3, 4, 5);
319     boost::hof::apply(&derived_hash::g5, pcx, 1, 2, 3, 4, 5);
320     boost::hof::apply(&derived_hash::g5, sp, 1, 2, 3, 4, 5);
321 
322     boost::hof::apply(&derived_hash::f6, x, 1, 2, 3, 4, 5, 6);
323     boost::hof::apply(&derived_hash::f6, &x, 1, 2, 3, 4, 5, 6);
324     boost::hof::apply(&derived_hash::f6, sp, 1, 2, 3, 4, 5, 6);
325 
326     boost::hof::apply(&derived_hash::g6, x, 1, 2, 3, 4, 5, 6);
327     boost::hof::apply(&derived_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
328     boost::hof::apply(&derived_hash::g6, &x, 1, 2, 3, 4, 5, 6);
329     boost::hof::apply(&derived_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
330     boost::hof::apply(&derived_hash::g6, sp, 1, 2, 3, 4, 5, 6);
331 
332     boost::hof::apply(&derived_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
333     boost::hof::apply(&derived_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
334     boost::hof::apply(&derived_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
335 
336     boost::hof::apply(&derived_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
337     boost::hof::apply(&derived_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
338     boost::hof::apply(&derived_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
339     boost::hof::apply(&derived_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
340     boost::hof::apply(&derived_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
341 
342     boost::hof::apply(&derived_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
343     boost::hof::apply(&derived_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
344     boost::hof::apply(&derived_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
345 
346     boost::hof::apply(&derived_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
347     boost::hof::apply(&derived_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
348     boost::hof::apply(&derived_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
349     boost::hof::apply(&derived_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
350     boost::hof::apply(&derived_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
351 
352     BOOST_HOF_TEST_CHECK(boost::hof::apply(&derived_hash::hash, x) == 17610 && boost::hof::apply(&derived_hash::hash, sp) == 2155);
353 }
354 
355 struct dm_t
356 {
357     int m;
358 };
359 
BOOST_HOF_TEST_CASE()360 BOOST_HOF_TEST_CASE()
361 {
362     dm_t x = { 0 };
363 
364     boost::hof::apply( &dm_t::m, x ) = 401;
365 
366     BOOST_HOF_TEST_CHECK( x.m == 401 );
367     BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, x ) == 401 );
368 
369     boost::hof::apply( &dm_t::m, &x ) = 502;
370 
371     BOOST_HOF_TEST_CHECK( x.m == 502 );
372     BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, &x ) == 502 );
373 
374     dm_t * px = &x;
375 
376     boost::hof::apply( &dm_t::m, px ) = 603;
377 
378     BOOST_HOF_TEST_CHECK( x.m == 603 );
379     BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, px ) == 603 );
380 
381     dm_t const & cx = x;
382     dm_t const * pcx = &x;
383 
384     BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, cx ) == 603 );
385     BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, pcx ) == 603 );
386 
387 }
388 
389 
390 struct X_ref
391 {
fX_ref392     int f()
393     {
394         return 1;
395     }
396 
gX_ref397     int g() const
398     {
399         return 2;
400     }
401 };
402 
BOOST_HOF_TEST_CASE()403 BOOST_HOF_TEST_CASE()
404 {
405     X_ref x;
406 
407     BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::f, std::ref( x ) ) == 1 );
408     BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::g, std::cref( x ) ) == 2 );
409 }
410 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
411 struct copy_throws
412 {
copy_throwscopy_throws413     copy_throws() {}
copy_throwscopy_throws414     copy_throws(copy_throws const&) {}
copy_throwscopy_throws415     copy_throws(copy_throws&&) noexcept {}
416 };
417 
418 struct no_throw_fo
419 {
operator ()no_throw_fo420     void operator()() noexcept {}
operator ()no_throw_fo421     void operator()(copy_throws) noexcept {}
422 };
423 
424 struct throws_fo
425 {
operator ()throws_fo426     void operator()() {}
427 };
428 
429 struct member_obj
430 {
431     int x;
432 };
433 // Only newer versions of gcc support deducing noexcept for member function pointers
434 #if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 8) || (__GNUC__ > 4))
435 struct no_throw_member_fun
436 {
foo_nullaryno_throw_member_fun437     void foo_nullary() noexcept {}
foo_unaryno_throw_member_fun438     void foo_unary(copy_throws) noexcept {}
439 };
BOOST_HOF_TEST_CASE()440 BOOST_HOF_TEST_CASE()
441 {
442     no_throw_member_fun obj;
443     copy_throws arg;
444     static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_nullary, obj)), "");
445     static_assert(!noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, arg)), "");
446     static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, std::move(arg))), "");
447 }
448 #endif
BOOST_HOF_TEST_CASE()449 BOOST_HOF_TEST_CASE()
450 {
451     no_throw_fo obj;
452     copy_throws arg;
453     static_assert(noexcept(boost::hof::apply(obj)), "");
454     static_assert(!noexcept(boost::hof::apply(obj, arg)), "");
455     static_assert(noexcept(boost::hof::apply(obj, std::move(arg))), "");
456 }
BOOST_HOF_TEST_CASE()457 BOOST_HOF_TEST_CASE()
458 {
459     throws_fo obj;
460     static_assert(!noexcept(boost::hof::apply(obj)), "");
461 }
BOOST_HOF_TEST_CASE()462 BOOST_HOF_TEST_CASE()
463 {
464     member_obj obj{42};
465     static_assert(noexcept(boost::hof::apply(&member_obj::x, obj)), "");
466 }
467 #endif
468