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
11template<int N>
12struct test_placeholder
13{};
14
15namespace std {
16 template<int N>
17 struct is_placeholder<test_placeholder<N>>
18 : std::integral_constant<int, N>
19 {};
20}
21
22BOOST_HOF_TEST_CASE()
23{
24 int i = 5;
25
26 static_assert(std::is_reference<decltype(boost::hof::detail::ref_transformer()(std::ref(t&: i))(0,0,0))>::value, "Reference wrapper failed");
27 static_assert(std::is_reference<decltype(boost::hof::detail::pick_transformer(std::ref(t&: i))(0,0,0))>::value, "Reference wrapper failed");
28 static_assert(std::is_reference<decltype(boost::hof::detail::lazy_transform(x: std::ref(t&: i), p: 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
35BOOST_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
44BOOST_HOF_TEST_CASE()
45{
46 auto id =[](int i){ return i;};
47 auto fi = std::bind(f&: id, args: 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
54struct f_0 {
55constexpr long operator()() const
56{
57 return 17041L;
58}
59};
60
61struct f_1 {
62constexpr long operator()(long a) const
63{
64 return a;
65}
66};
67
68struct f_2 {
69constexpr long operator()(long a, long b) const
70{
71 return a + 10 * b;
72}
73};
74
75static long global_result;
76
77struct fv_0 {
78void operator()() const
79{
80 global_result = 17041L;
81}
82};
83
84struct fv_1 {
85void operator()(long a) const
86{
87 global_result = a;
88}
89};
90
91struct fv_2 {
92void operator()(long a, long b) const
93{
94 global_result = a + 10 * b;
95}
96};
97
98struct Y
99{
100 short operator()(short & r) const { return ++r; }
101 int operator()(int a, int b) const { return a + 10 * b; }
102 long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; }
103 void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; }
104};
105
106BOOST_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
123BOOST_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
148struct X
149{
150 mutable unsigned int hash;
151
152 X(): hash(0) {}
153
154 int f0() { f1(a1: 17); return 0; }
155 int g0() const { g1(a1: 17); return 0; }
156
157 int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
158 int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
159
160 int f2(int a1, int a2) { f1(a1); f1(a1: a2); return 0; }
161 int g2(int a1, int a2) const { g1(a1); g1(a1: a2); return 0; }
162
163 int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a1: a3); return 0; }
164 int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a1: a3); return 0; }
165
166 int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a1: a4); return 0; }
167 int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a1: a4); return 0; }
168
169 int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a1: a5); return 0; }
170 int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a1: a5); return 0; }
171
172 int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a1: a6); return 0; }
173 int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a1: a6); return 0; }
174
175 int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a1: a7); return 0; }
176 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(a1: a7); return 0; }
177
178 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(a1: a8); return 0; }
179 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(a1: a8); return 0; }
180};
181
182struct V
183{
184 mutable unsigned int hash;
185
186 V(): hash(0) {}
187
188 void f0() { f1(a1: 17); }
189 void g0() const { g1(a1: 17); }
190
191 void f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
192 void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
193
194 void f2(int a1, int a2) { f1(a1); f1(a1: a2); }
195 void g2(int a1, int a2) const { g1(a1); g1(a1: a2); }
196
197 void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a1: a3); }
198 void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a1: a3); }
199
200 void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a1: a4); }
201 void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a1: a4); }
202
203 void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a1: a5); }
204 void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a1: a5); }
205
206 void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a1: a6); }
207 void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a1: a6); }
208
209 void f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a1: a7); }
210 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(a1: a7); }
211
212 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(a1: a8); }
213 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(a1: a8); }
214};
215
216BOOST_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(t&: x))();
225
226 boost::hof::lazy(&X::g0)(&x)();
227 boost::hof::lazy(&X::g0)(x)();
228 boost::hof::lazy(&X::g0)(std::ref(t&: x))();
229
230 // 1
231
232 boost::hof::lazy(&X::f1)(&x, 1)();
233 boost::hof::lazy(&X::f1)(std::ref(t&: 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(t&: x), 1)();
238
239 // 2
240
241 boost::hof::lazy(&X::f2)(&x, 1, 2)();
242 boost::hof::lazy(&X::f2)(std::ref(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: x), 1, 2, 3, 4, 5, 6, 7, 8)();
301
302 BOOST_HOF_TEST_CHECK( x.hash == 23558 );
303}
304
305BOOST_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(t&: v))();
313
314 boost::hof::lazy(&V::g0)(&v)();
315 boost::hof::lazy(&V::g0)(v)();
316 boost::hof::lazy(&V::g0)(std::ref(t&: v))();
317
318 // 1
319
320 boost::hof::lazy(&V::f1)(&v, 1)();
321 boost::hof::lazy(&V::f1)(std::ref(t&: 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(t&: v), 1)();
326
327 // 2
328
329 boost::hof::lazy(&V::f2)(&v, 1, 2)();
330 boost::hof::lazy(&V::f2)(std::ref(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: 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(t&: v), 1, 2, 3, 4, 5, 6, 7, 8)();
389
390 BOOST_HOF_TEST_CHECK( v.hash == 23558 );
391}
392
393struct id
394{
395 int operator()(int i) const
396 {
397 return i;
398 }
399};
400
401BOOST_HOF_TEST_CASE()
402{
403 BOOST_HOF_TEST_CHECK(boost::hof::lazy(id())(3)() == 3);
404}
405
406struct deref
407{
408 int operator()(const std::unique_ptr<int>& i) const
409 {
410 return *i;
411 }
412};
413
414BOOST_HOF_TEST_CASE()
415{
416 BOOST_HOF_TEST_CHECK(boost::hof::lazy(deref())(std::unique_ptr<int>(new int(3)))() == 3);
417}
418
419void fv1( std::unique_ptr<int> p1 )
420{
421 BOOST_HOF_TEST_CHECK( *p1 == 1 );
422}
423
424void 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
430void 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
437void 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
445void 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
454void 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
464void 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
475void 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
487void 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
500BOOST_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}
506BOOST_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}
513BOOST_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}
521BOOST_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}
530BOOST_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}
540BOOST_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}
551BOOST_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}
563BOOST_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}
576BOOST_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
592struct X_ref
593{
594 int f( int x )
595 {
596 return x;
597 }
598
599 int g( int x ) const
600 {
601 return -x;
602 }
603};
604
605BOOST_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
613BOOST_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
624struct dummy_unary_fn
625{
626 template <typename S>
627 int operator()(S const &) const { return 0; }
628};
629
630struct bad_unary_fn
631{
632 template <typename S>
633 constexpr int operator()(S const &) const
634 {
635 static_assert(!std::is_same<S, S>::value, "Failure");
636 return 0;
637 }
638};
639
640BOOST_HOF_TEST_CASE()
641{
642 auto b = boost::hof::lazy(dummy_unary_fn())(bad_unary_fn());
643 b(0);
644}
645
646
647struct by_value_fn
648{
649 template<typename T, typename U>
650 void operator()(T &&, U &&) const
651 {
652 static_assert(std::is_same<U, int>::value, "");
653 }
654};
655
656BOOST_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
662struct copy_throws
663{
664 copy_throws() {}
665 copy_throws(copy_throws const&) {}
666 copy_throws(copy_throws&&) noexcept {}
667};
668
669struct no_throw_fo
670{
671 void operator()() const noexcept {}
672 void operator()(int) const noexcept {}
673 void operator()(copy_throws) const noexcept {}
674};
675
676struct throws_fo
677{
678 void operator()() const {}
679};
680
681struct member_obj
682{
683 int x;
684};
685
686BOOST_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}
702BOOST_HOF_TEST_CASE()
703{
704 throws_fo obj;
705 static_assert(!noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
706}
707BOOST_HOF_TEST_CASE()
708{
709 member_obj obj{.x: 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

source code of boost/libs/hof/test/lazy.cpp