• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     lazy.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/lazy.hpp>
8 #include <memory>
9 #include "test.hpp"
10 
11 template<int N>
12 struct test_placeholder
13 {};
14 
15 namespace std {
16     template<int N>
17     struct is_placeholder<test_placeholder<N>>
18     : std::integral_constant<int, N>
19     {};
20 }
21 
BOOST_HOF_TEST_CASE()22 BOOST_HOF_TEST_CASE()
23 {
24     int i = 5;
25 
26     static_assert(std::is_reference<decltype(boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
27     static_assert(std::is_reference<decltype(boost::hof::detail::pick_transformer(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
28     static_assert(std::is_reference<decltype(boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)))>::value, "Reference wrapper failed");
29 
30     BOOST_HOF_TEST_CHECK(&boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0) == &i);
31     BOOST_HOF_TEST_CHECK(&boost::hof::detail::pick_transformer(std::ref(i))(0,0,0) == &i);
32     BOOST_HOF_TEST_CHECK(&boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)) == &i);
33 }
34 
BOOST_HOF_TEST_CASE()35 BOOST_HOF_TEST_CASE()
36 {
37     int i = 5;
38 
39     BOOST_HOF_TEST_CHECK(boost::hof::detail::id_transformer()(i)(0,0,0) == i);
40     BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(i)(0,0,0) == i);
41     BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(i, boost::hof::pack_basic(0,0,0)) == i);
42 }
43 
BOOST_HOF_TEST_CASE()44 BOOST_HOF_TEST_CASE()
45 {
46     auto id =[](int i){ return i;};
47     auto fi = std::bind(id, 5);
48 
49     BOOST_HOF_TEST_CHECK(boost::hof::detail::bind_transformer()(fi)(0,0,0) == id(5));
50     BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(fi)(0,0,0) == id(5));
51     BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(fi, boost::hof::pack_basic(0,0,0)) == id(5));
52 }
53 
54 struct f_0 {
operator ()f_055 constexpr long operator()() const
56 {
57     return 17041L;
58 }
59 };
60 
61 struct f_1 {
operator ()f_162 constexpr long operator()(long a) const
63 {
64     return a;
65 }
66 };
67 
68 struct f_2 {
operator ()f_269 constexpr long operator()(long a, long b) const
70 {
71     return a + 10 * b;
72 }
73 };
74 
75 static long global_result;
76 
77 struct fv_0 {
operator ()fv_078 void operator()() const
79 {
80     global_result = 17041L;
81 }
82 };
83 
84 struct fv_1 {
operator ()fv_185 void operator()(long a) const
86 {
87     global_result = a;
88 }
89 };
90 
91 struct fv_2 {
operator ()fv_292 void operator()(long a, long b) const
93 {
94     global_result = a + 10 * b;
95 }
96 };
97 
98 struct Y
99 {
operator ()Y100     short operator()(short & r) const { return ++r; }
operator ()Y101     int operator()(int a, int b) const { return a + 10 * b; }
operator ()Y102     long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; }
operator ()Y103     void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; }
104 };
105 
BOOST_HOF_TEST_CASE()106 BOOST_HOF_TEST_CASE()
107 {
108     short i(6);
109 
110     int const k = 3;
111 
112     BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 7 );
113     BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 8 );
114     BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1)(k) == 38 );
115     BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1, 9)(k) == 938 );
116 
117     global_result = 0;
118     boost::hof::lazy(Y())( i,std::placeholders::_1, 9, 4)(k);
119     BOOST_HOF_TEST_CHECK( global_result == 4938 );
120 
121 }
122 
BOOST_HOF_TEST_CASE()123 BOOST_HOF_TEST_CASE()
124 {
125     int const x = 1;
126     int const y = 2;
127 
128     BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 1L );
129     BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y) == 21L );
130     BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 11L );
131     BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y) == 21L );
132     BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
133 
134     BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 1L );
135     BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(test_placeholder<1>(), test_placeholder<2>()))(x, y) == 21L );
136     BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 11L );
137     BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())( test_placeholder<2>()))(x, y) == 21L );
138     BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
139 
140     BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 1L)) );
141     BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y), (global_result == 21L)) );
142     BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 11L)) );
143     BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y), (global_result == 21L)) );
144     BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_0())())(), (global_result == 17041L)) );
145 }
146 
147 
148 struct X
149 {
150     mutable unsigned int hash;
151 
XX152     X(): hash(0) {}
153 
f0X154     int f0() { f1(17); return 0; }
g0X155     int g0() const { g1(17); return 0; }
156 
f1X157     int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
g1X158     int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
159 
f2X160     int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
g2X161     int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
162 
f3X163     int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
g3X164     int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
165 
f4X166     int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
g4X167     int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
168 
f5X169     int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
g5X170     int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
171 
f6X172     int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
g6X173     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; }
174 
f7X175     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; }
g7X176     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; }
177 
f8X178     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; }
g8X179     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; }
180 };
181 
182 struct V
183 {
184     mutable unsigned int hash;
185 
VV186     V(): hash(0) {}
187 
f0V188     void f0() { f1(17); }
g0V189     void g0() const { g1(17); }
190 
f1V191     void f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
g1V192     void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
193 
f2V194     void f2(int a1, int a2) { f1(a1); f1(a2); }
g2V195     void g2(int a1, int a2) const { g1(a1); g1(a2); }
196 
f3V197     void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
g3V198     void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
199 
f4V200     void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
g4V201     void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
202 
f5V203     void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
g5V204     void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
205 
f6V206     void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
g6V207     void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
208 
f7V209     void f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
g7V210     void 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); }
211 
f8V212     void 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); }
g8V213     void 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); }
214 };
215 
BOOST_HOF_TEST_CASE()216 BOOST_HOF_TEST_CASE()
217 {
218 
219     X x;
220 
221     // 0
222 
223     boost::hof::lazy(&X::f0)(&x)();
224     boost::hof::lazy(&X::f0)(std::ref(x))();
225 
226     boost::hof::lazy(&X::g0)(&x)();
227     boost::hof::lazy(&X::g0)(x)();
228     boost::hof::lazy(&X::g0)(std::ref(x))();
229 
230     // 1
231 
232     boost::hof::lazy(&X::f1)(&x, 1)();
233     boost::hof::lazy(&X::f1)(std::ref(x), 1)();
234 
235     boost::hof::lazy(&X::g1)(&x, 1)();
236     boost::hof::lazy(&X::g1)(x, 1)();
237     boost::hof::lazy(&X::g1)(std::ref(x), 1)();
238 
239     // 2
240 
241     boost::hof::lazy(&X::f2)(&x, 1, 2)();
242     boost::hof::lazy(&X::f2)(std::ref(x), 1, 2)();
243 
244     boost::hof::lazy(&X::g2)(&x, 1, 2)();
245     boost::hof::lazy(&X::g2)(x, 1, 2)();
246     boost::hof::lazy(&X::g2)(std::ref(x), 1, 2)();
247 
248     // 3
249 
250     boost::hof::lazy(&X::f3)(&x, 1, 2, 3)();
251     boost::hof::lazy(&X::f3)(std::ref(x), 1, 2, 3)();
252 
253     boost::hof::lazy(&X::g3)(&x, 1, 2, 3)();
254     boost::hof::lazy(&X::g3)(x, 1, 2, 3)();
255     boost::hof::lazy(&X::g3)(std::ref(x), 1, 2, 3)();
256 
257     // 4
258 
259     boost::hof::lazy(&X::f4)(&x, 1, 2, 3, 4)();
260     boost::hof::lazy(&X::f4)(std::ref(x), 1, 2, 3, 4)();
261 
262     boost::hof::lazy(&X::g4)(&x, 1, 2, 3, 4)();
263     boost::hof::lazy(&X::g4)(x, 1, 2, 3, 4)();
264     boost::hof::lazy(&X::g4)(std::ref(x), 1, 2, 3, 4)();
265 
266     // 5
267 
268     boost::hof::lazy(&X::f5)(&x, 1, 2, 3, 4, 5)();
269     boost::hof::lazy(&X::f5)(std::ref(x), 1, 2, 3, 4, 5)();
270 
271     boost::hof::lazy(&X::g5)(&x, 1, 2, 3, 4, 5)();
272     boost::hof::lazy(&X::g5)(x, 1, 2, 3, 4, 5)();
273     boost::hof::lazy(&X::g5)(std::ref(x), 1, 2, 3, 4, 5)();
274 
275     // 6
276 
277     boost::hof::lazy(&X::f6)(&x, 1, 2, 3, 4, 5, 6)();
278     boost::hof::lazy(&X::f6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
279 
280     boost::hof::lazy(&X::g6)(&x, 1, 2, 3, 4, 5, 6)();
281     boost::hof::lazy(&X::g6)(x, 1, 2, 3, 4, 5, 6)();
282     boost::hof::lazy(&X::g6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
283 
284     // 7
285 
286     boost::hof::lazy(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7)();
287     boost::hof::lazy(&X::f7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
288 
289     boost::hof::lazy(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7)();
290     boost::hof::lazy(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7)();
291     boost::hof::lazy(&X::g7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
292 
293     // 8
294 
295     boost::hof::lazy(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
296     boost::hof::lazy(&X::f8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
297 
298     boost::hof::lazy(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
299     boost::hof::lazy(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8)();
300     boost::hof::lazy(&X::g8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
301 
302     BOOST_HOF_TEST_CHECK( x.hash == 23558 );
303 }
304 
BOOST_HOF_TEST_CASE()305 BOOST_HOF_TEST_CASE()
306 {
307     V v;
308 
309     // 0
310 
311     boost::hof::lazy(&V::f0)(&v)();
312     boost::hof::lazy(&V::f0)(std::ref(v))();
313 
314     boost::hof::lazy(&V::g0)(&v)();
315     boost::hof::lazy(&V::g0)(v)();
316     boost::hof::lazy(&V::g0)(std::ref(v))();
317 
318     // 1
319 
320     boost::hof::lazy(&V::f1)(&v, 1)();
321     boost::hof::lazy(&V::f1)(std::ref(v), 1)();
322 
323     boost::hof::lazy(&V::g1)(&v, 1)();
324     boost::hof::lazy(&V::g1)(v, 1)();
325     boost::hof::lazy(&V::g1)(std::ref(v), 1)();
326 
327     // 2
328 
329     boost::hof::lazy(&V::f2)(&v, 1, 2)();
330     boost::hof::lazy(&V::f2)(std::ref(v), 1, 2)();
331 
332     boost::hof::lazy(&V::g2)(&v, 1, 2)();
333     boost::hof::lazy(&V::g2)(v, 1, 2)();
334     boost::hof::lazy(&V::g2)(std::ref(v), 1, 2)();
335 
336     // 3
337 
338     boost::hof::lazy(&V::f3)(&v, 1, 2, 3)();
339     boost::hof::lazy(&V::f3)(std::ref(v), 1, 2, 3)();
340 
341     boost::hof::lazy(&V::g3)(&v, 1, 2, 3)();
342     boost::hof::lazy(&V::g3)(v, 1, 2, 3)();
343     boost::hof::lazy(&V::g3)(std::ref(v), 1, 2, 3)();
344 
345     // 4
346 
347     boost::hof::lazy(&V::f4)(&v, 1, 2, 3, 4)();
348     boost::hof::lazy(&V::f4)(std::ref(v), 1, 2, 3, 4)();
349 
350     boost::hof::lazy(&V::g4)(&v, 1, 2, 3, 4)();
351     boost::hof::lazy(&V::g4)(v, 1, 2, 3, 4)();
352     boost::hof::lazy(&V::g4)(std::ref(v), 1, 2, 3, 4)();
353 
354     // 5
355 
356     boost::hof::lazy(&V::f5)(&v, 1, 2, 3, 4, 5)();
357     boost::hof::lazy(&V::f5)(std::ref(v), 1, 2, 3, 4, 5)();
358 
359     boost::hof::lazy(&V::g5)(&v, 1, 2, 3, 4, 5)();
360     boost::hof::lazy(&V::g5)(v, 1, 2, 3, 4, 5)();
361     boost::hof::lazy(&V::g5)(std::ref(v), 1, 2, 3, 4, 5)();
362 
363     // 6
364 
365     boost::hof::lazy(&V::f6)(&v, 1, 2, 3, 4, 5, 6)();
366     boost::hof::lazy(&V::f6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
367 
368     boost::hof::lazy(&V::g6)(&v, 1, 2, 3, 4, 5, 6)();
369     boost::hof::lazy(&V::g6)(v, 1, 2, 3, 4, 5, 6)();
370     boost::hof::lazy(&V::g6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
371 
372     // 7
373 
374     boost::hof::lazy(&V::f7)(&v, 1, 2, 3, 4, 5, 6, 7)();
375     boost::hof::lazy(&V::f7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
376 
377     boost::hof::lazy(&V::g7)(&v, 1, 2, 3, 4, 5, 6, 7)();
378     boost::hof::lazy(&V::g7)(v, 1, 2, 3, 4, 5, 6, 7)();
379     boost::hof::lazy(&V::g7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
380 
381     // 8
382 
383     boost::hof::lazy(&V::f8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
384     boost::hof::lazy(&V::f8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
385 
386     boost::hof::lazy(&V::g8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
387     boost::hof::lazy(&V::g8)(v, 1, 2, 3, 4, 5, 6, 7, 8)();
388     boost::hof::lazy(&V::g8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
389 
390     BOOST_HOF_TEST_CHECK( v.hash == 23558 );
391 }
392 
393 struct id
394 {
operator ()id395     int operator()(int i) const
396     {
397         return i;
398     }
399 };
400 
BOOST_HOF_TEST_CASE()401 BOOST_HOF_TEST_CASE()
402 {
403     BOOST_HOF_TEST_CHECK(boost::hof::lazy(id())(3)() == 3);
404 }
405 
406 struct deref
407 {
operator ()deref408     int operator()(const std::unique_ptr<int>& i) const
409     {
410         return *i;
411     }
412 };
413 
BOOST_HOF_TEST_CASE()414 BOOST_HOF_TEST_CASE()
415 {
416     BOOST_HOF_TEST_CHECK(boost::hof::lazy(deref())(std::unique_ptr<int>(new int(3)))() == 3);
417 }
418 
fv1(std::unique_ptr<int> p1)419 void fv1( std::unique_ptr<int> p1 )
420 {
421     BOOST_HOF_TEST_CHECK( *p1 == 1 );
422 }
423 
fv2(std::unique_ptr<int> p1,std::unique_ptr<int> p2)424 void fv2( std::unique_ptr<int> p1, std::unique_ptr<int> p2 )
425 {
426     BOOST_HOF_TEST_CHECK( *p1 == 1 );
427     BOOST_HOF_TEST_CHECK( *p2 == 2 );
428 }
429 
fv3(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3)430 void fv3( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3 )
431 {
432     BOOST_HOF_TEST_CHECK( *p1 == 1 );
433     BOOST_HOF_TEST_CHECK( *p2 == 2 );
434     BOOST_HOF_TEST_CHECK( *p3 == 3 );
435 }
436 
fv4(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4)437 void fv4( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4 )
438 {
439     BOOST_HOF_TEST_CHECK( *p1 == 1 );
440     BOOST_HOF_TEST_CHECK( *p2 == 2 );
441     BOOST_HOF_TEST_CHECK( *p3 == 3 );
442     BOOST_HOF_TEST_CHECK( *p4 == 4 );
443 }
444 
fv5(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4,std::unique_ptr<int> p5)445 void fv5( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5 )
446 {
447     BOOST_HOF_TEST_CHECK( *p1 == 1 );
448     BOOST_HOF_TEST_CHECK( *p2 == 2 );
449     BOOST_HOF_TEST_CHECK( *p3 == 3 );
450     BOOST_HOF_TEST_CHECK( *p4 == 4 );
451     BOOST_HOF_TEST_CHECK( *p5 == 5 );
452 }
453 
fv6(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4,std::unique_ptr<int> p5,std::unique_ptr<int> p6)454 void fv6( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6 )
455 {
456     BOOST_HOF_TEST_CHECK( *p1 == 1 );
457     BOOST_HOF_TEST_CHECK( *p2 == 2 );
458     BOOST_HOF_TEST_CHECK( *p3 == 3 );
459     BOOST_HOF_TEST_CHECK( *p4 == 4 );
460     BOOST_HOF_TEST_CHECK( *p5 == 5 );
461     BOOST_HOF_TEST_CHECK( *p6 == 6 );
462 }
463 
fv7(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4,std::unique_ptr<int> p5,std::unique_ptr<int> p6,std::unique_ptr<int> p7)464 void fv7( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7 )
465 {
466     BOOST_HOF_TEST_CHECK( *p1 == 1 );
467     BOOST_HOF_TEST_CHECK( *p2 == 2 );
468     BOOST_HOF_TEST_CHECK( *p3 == 3 );
469     BOOST_HOF_TEST_CHECK( *p4 == 4 );
470     BOOST_HOF_TEST_CHECK( *p5 == 5 );
471     BOOST_HOF_TEST_CHECK( *p6 == 6 );
472     BOOST_HOF_TEST_CHECK( *p7 == 7 );
473 }
474 
fv8(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4,std::unique_ptr<int> p5,std::unique_ptr<int> p6,std::unique_ptr<int> p7,std::unique_ptr<int> p8)475 void fv8( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8 )
476 {
477     BOOST_HOF_TEST_CHECK( *p1 == 1 );
478     BOOST_HOF_TEST_CHECK( *p2 == 2 );
479     BOOST_HOF_TEST_CHECK( *p3 == 3 );
480     BOOST_HOF_TEST_CHECK( *p4 == 4 );
481     BOOST_HOF_TEST_CHECK( *p5 == 5 );
482     BOOST_HOF_TEST_CHECK( *p6 == 6 );
483     BOOST_HOF_TEST_CHECK( *p7 == 7 );
484     BOOST_HOF_TEST_CHECK( *p8 == 8 );
485 }
486 
fv9(std::unique_ptr<int> p1,std::unique_ptr<int> p2,std::unique_ptr<int> p3,std::unique_ptr<int> p4,std::unique_ptr<int> p5,std::unique_ptr<int> p6,std::unique_ptr<int> p7,std::unique_ptr<int> p8,std::unique_ptr<int> p9)487 void fv9( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8, std::unique_ptr<int> p9 )
488 {
489     BOOST_HOF_TEST_CHECK( *p1 == 1 );
490     BOOST_HOF_TEST_CHECK( *p2 == 2 );
491     BOOST_HOF_TEST_CHECK( *p3 == 3 );
492     BOOST_HOF_TEST_CHECK( *p4 == 4 );
493     BOOST_HOF_TEST_CHECK( *p5 == 5 );
494     BOOST_HOF_TEST_CHECK( *p6 == 6 );
495     BOOST_HOF_TEST_CHECK( *p7 == 7 );
496     BOOST_HOF_TEST_CHECK( *p8 == 8 );
497     BOOST_HOF_TEST_CHECK( *p9 == 9 );
498 }
499 
BOOST_HOF_TEST_CASE()500 BOOST_HOF_TEST_CASE()
501 {
502     std::unique_ptr<int> p1( new int(1) );
503 
504     boost::hof::lazy( fv1 )( std::placeholders::_1 )( std::move( p1 ) );
505 }
BOOST_HOF_TEST_CASE()506 BOOST_HOF_TEST_CASE()
507 {
508     std::unique_ptr<int> p1( new int(1) );
509     std::unique_ptr<int> p2( new int(2) );
510 
511     boost::hof::lazy( fv2 )( std::placeholders::_1, std::placeholders::_2 )( std::move( p1 ), std::move( p2 ) );
512 }
BOOST_HOF_TEST_CASE()513 BOOST_HOF_TEST_CASE()
514 {
515     std::unique_ptr<int> p1( new int(1) );
516     std::unique_ptr<int> p2( new int(2) );
517     std::unique_ptr<int> p3( new int(3) );
518 
519     boost::hof::lazy( fv3 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 )( std::move( p1 ), std::move( p2 ), std::move( p3 ) );
520 }
BOOST_HOF_TEST_CASE()521 BOOST_HOF_TEST_CASE()
522 {
523     std::unique_ptr<int> p1( new int(1) );
524     std::unique_ptr<int> p2( new int(2) );
525     std::unique_ptr<int> p3( new int(3) );
526     std::unique_ptr<int> p4( new int(4) );
527 
528     boost::hof::lazy( fv4 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ) );
529 }
BOOST_HOF_TEST_CASE()530 BOOST_HOF_TEST_CASE()
531 {
532     std::unique_ptr<int> p1( new int(1) );
533     std::unique_ptr<int> p2( new int(2) );
534     std::unique_ptr<int> p3( new int(3) );
535     std::unique_ptr<int> p4( new int(4) );
536     std::unique_ptr<int> p5( new int(5) );
537 
538     boost::hof::lazy( fv5 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ) );
539 }
BOOST_HOF_TEST_CASE()540 BOOST_HOF_TEST_CASE()
541 {
542     std::unique_ptr<int> p1( new int(1) );
543     std::unique_ptr<int> p2( new int(2) );
544     std::unique_ptr<int> p3( new int(3) );
545     std::unique_ptr<int> p4( new int(4) );
546     std::unique_ptr<int> p5( new int(5) );
547     std::unique_ptr<int> p6( new int(6) );
548 
549     boost::hof::lazy( fv6 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ) );
550 }
BOOST_HOF_TEST_CASE()551 BOOST_HOF_TEST_CASE()
552 {
553     std::unique_ptr<int> p1( new int(1) );
554     std::unique_ptr<int> p2( new int(2) );
555     std::unique_ptr<int> p3( new int(3) );
556     std::unique_ptr<int> p4( new int(4) );
557     std::unique_ptr<int> p5( new int(5) );
558     std::unique_ptr<int> p6( new int(6) );
559     std::unique_ptr<int> p7( new int(7) );
560 
561     boost::hof::lazy( fv7 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ) );
562 }
BOOST_HOF_TEST_CASE()563 BOOST_HOF_TEST_CASE()
564 {
565     std::unique_ptr<int> p1( new int(1) );
566     std::unique_ptr<int> p2( new int(2) );
567     std::unique_ptr<int> p3( new int(3) );
568     std::unique_ptr<int> p4( new int(4) );
569     std::unique_ptr<int> p5( new int(5) );
570     std::unique_ptr<int> p6( new int(6) );
571     std::unique_ptr<int> p7( new int(7) );
572     std::unique_ptr<int> p8( new int(8) );
573 
574     boost::hof::lazy( fv8 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ) );
575 }
BOOST_HOF_TEST_CASE()576 BOOST_HOF_TEST_CASE()
577 {
578     std::unique_ptr<int> p1( new int(1) );
579     std::unique_ptr<int> p2( new int(2) );
580     std::unique_ptr<int> p3( new int(3) );
581     std::unique_ptr<int> p4( new int(4) );
582     std::unique_ptr<int> p5( new int(5) );
583     std::unique_ptr<int> p6( new int(6) );
584     std::unique_ptr<int> p7( new int(7) );
585     std::unique_ptr<int> p8( new int(8) );
586     std::unique_ptr<int> p9( new int(9) );
587 
588     boost::hof::lazy( fv9 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ), std::move( p9 ) );
589 }
590 
591 
592 struct X_ref
593 {
fX_ref594     int f( int x )
595     {
596         return x;
597     }
598 
gX_ref599     int g( int x ) const
600     {
601         return -x;
602     }
603 };
604 
BOOST_HOF_TEST_CASE()605 BOOST_HOF_TEST_CASE()
606 {
607     X_ref x;
608 
609     BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::f )( std::ref( x ), std::placeholders::_1 )( 1 ) == 1 );
610     BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::g )( std::cref( x ), std::placeholders::_1 )( 2 ) == -2 );
611 }
612 
BOOST_HOF_TEST_CASE()613 BOOST_HOF_TEST_CASE()
614 {
615     auto lazy_f_1 = boost::hof::lazy(f_1())(std::placeholders::_1);
616     static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long>::value, "Invocable");
617     static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long, long>::value, "Invocable");
618 
619     auto lazy_f_2 = boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2);
620     static_assert(boost::hof::is_invocable<decltype(lazy_f_2), long, long>::value, "Invocable");
621     static_assert(!boost::hof::is_invocable<decltype(lazy_f_2), long>::value, "Not SFINAE-friendly");
622 }
623 
624 struct dummy_unary_fn
625 {
626     template <typename S>
operator ()dummy_unary_fn627     int operator()(S const &) const { return 0; }
628 };
629 
630 struct bad_unary_fn
631 {
632     template <typename S>
operator ()bad_unary_fn633     constexpr int operator()(S const &) const
634     {
635         static_assert(!std::is_same<S, S>::value, "Failure");
636         return 0;
637     }
638 };
639 
BOOST_HOF_TEST_CASE()640 BOOST_HOF_TEST_CASE()
641 {
642     auto b = boost::hof::lazy(dummy_unary_fn())(bad_unary_fn());
643     b(0);
644 }
645 
646 
647 struct by_value_fn
648 {
649     template<typename T, typename U>
operator ()by_value_fn650     void operator()(T &&, U &&) const
651     {
652         static_assert(std::is_same<U, int>::value, "");
653     }
654 };
655 
BOOST_HOF_TEST_CASE()656 BOOST_HOF_TEST_CASE()
657 {
658     boost::hof::lazy(by_value_fn{})(std::placeholders::_1, 42)("hello");
659 }
660 
661 #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
662 struct copy_throws
663 {
copy_throwscopy_throws664     copy_throws() {}
copy_throwscopy_throws665     copy_throws(copy_throws const&) {}
copy_throwscopy_throws666     copy_throws(copy_throws&&) noexcept {}
667 };
668 
669 struct no_throw_fo
670 {
operator ()no_throw_fo671     void operator()() const noexcept {}
operator ()no_throw_fo672     void operator()(int) const noexcept {}
operator ()no_throw_fo673     void operator()(copy_throws) const noexcept {}
674 };
675 
676 struct throws_fo
677 {
operator ()throws_fo678     void operator()() const {}
679 };
680 
681 struct member_obj
682 {
683     int x;
684 };
685 
BOOST_HOF_TEST_CASE()686 BOOST_HOF_TEST_CASE()
687 {
688     no_throw_fo obj;
689     copy_throws arg;
690     static_assert(noexcept(boost::hof::lazy(no_throw_fo{})()()), "noexcept lazy");
691     static_assert(noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
692     static_assert(!noexcept(boost::hof::lazy(obj)(arg)()), "noexcept lazy");
693     static_assert(noexcept(boost::hof::lazy(obj)(1)()), "noexcept lazy");
694     static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)), "noexcept lazy");
695     // static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)()), "noexcept lazy");
696     static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(1)), "noexcept lazy");
697     static_assert(!noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(arg)), "noexcept lazy");
698 
699     static_assert(noexcept(boost::hof::lazy(obj)(std::move(arg))), "noexcept lazy");
700     static_assert(!noexcept(boost::hof::lazy(obj)(std::move(arg))()), "noexcept lazy");
701 }
BOOST_HOF_TEST_CASE()702 BOOST_HOF_TEST_CASE()
703 {
704     throws_fo obj;
705     static_assert(!noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
706 }
BOOST_HOF_TEST_CASE()707 BOOST_HOF_TEST_CASE()
708 {
709     member_obj obj{42};
710     static_assert(noexcept(boost::hof::lazy(&member_obj::x)(obj)()), "noexcept lazy");
711     static_assert(noexcept(boost::hof::lazy(&member_obj::x)(std::placeholders::_1)(obj)), "noexcept lazy");
712 }
713 #endif
714