lazy.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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. template<int N>
  11. struct test_placeholder
  12. {};
  13. namespace std {
  14. template<int N>
  15. struct is_placeholder<test_placeholder<N>>
  16. : std::integral_constant<int, N>
  17. {};
  18. }
  19. BOOST_HOF_TEST_CASE()
  20. {
  21. int i = 5;
  22. static_assert(std::is_reference<decltype(boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
  23. static_assert(std::is_reference<decltype(boost::hof::detail::pick_transformer(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
  24. 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");
  25. BOOST_HOF_TEST_CHECK(&boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0) == &i);
  26. BOOST_HOF_TEST_CHECK(&boost::hof::detail::pick_transformer(std::ref(i))(0,0,0) == &i);
  27. BOOST_HOF_TEST_CHECK(&boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)) == &i);
  28. }
  29. BOOST_HOF_TEST_CASE()
  30. {
  31. int i = 5;
  32. BOOST_HOF_TEST_CHECK(boost::hof::detail::id_transformer()(i)(0,0,0) == i);
  33. BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(i)(0,0,0) == i);
  34. BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(i, boost::hof::pack_basic(0,0,0)) == i);
  35. }
  36. BOOST_HOF_TEST_CASE()
  37. {
  38. auto id =[](int i){ return i;};
  39. auto fi = std::bind(id, 5);
  40. BOOST_HOF_TEST_CHECK(boost::hof::detail::bind_transformer()(fi)(0,0,0) == id(5));
  41. BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(fi)(0,0,0) == id(5));
  42. BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(fi, boost::hof::pack_basic(0,0,0)) == id(5));
  43. }
  44. struct f_0 {
  45. constexpr long operator()() const
  46. {
  47. return 17041L;
  48. }
  49. };
  50. struct f_1 {
  51. constexpr long operator()(long a) const
  52. {
  53. return a;
  54. }
  55. };
  56. struct f_2 {
  57. constexpr long operator()(long a, long b) const
  58. {
  59. return a + 10 * b;
  60. }
  61. };
  62. static long global_result;
  63. struct fv_0 {
  64. void operator()() const
  65. {
  66. global_result = 17041L;
  67. }
  68. };
  69. struct fv_1 {
  70. void operator()(long a) const
  71. {
  72. global_result = a;
  73. }
  74. };
  75. struct fv_2 {
  76. void operator()(long a, long b) const
  77. {
  78. global_result = a + 10 * b;
  79. }
  80. };
  81. struct Y
  82. {
  83. short operator()(short & r) const { return ++r; }
  84. int operator()(int a, int b) const { return a + 10 * b; }
  85. long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; }
  86. void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; }
  87. };
  88. BOOST_HOF_TEST_CASE()
  89. {
  90. short i(6);
  91. int const k = 3;
  92. BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 7 );
  93. BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 8 );
  94. BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1)(k) == 38 );
  95. BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1, 9)(k) == 938 );
  96. global_result = 0;
  97. boost::hof::lazy(Y())( i,std::placeholders::_1, 9, 4)(k);
  98. BOOST_HOF_TEST_CHECK( global_result == 4938 );
  99. }
  100. BOOST_HOF_TEST_CASE()
  101. {
  102. int const x = 1;
  103. int const y = 2;
  104. BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 1L );
  105. BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y) == 21L );
  106. 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 );
  107. 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 );
  108. BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
  109. BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 1L );
  110. BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(test_placeholder<1>(), test_placeholder<2>()))(x, y) == 21L );
  111. 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 );
  112. 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 );
  113. BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
  114. BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 1L)) );
  115. 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)) );
  116. 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)) );
  117. 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)) );
  118. BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_0())())(), (global_result == 17041L)) );
  119. }
  120. struct X
  121. {
  122. mutable unsigned int hash;
  123. X(): hash(0) {}
  124. int f0() { f1(17); return 0; }
  125. int g0() const { g1(17); return 0; }
  126. int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
  127. int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
  128. int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
  129. int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
  130. int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
  131. int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
  132. int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
  133. int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
  134. int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
  135. int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
  136. int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
  137. 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; }
  138. 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; }
  139. 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; }
  140. 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; }
  141. 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; }
  142. };
  143. struct V
  144. {
  145. mutable unsigned int hash;
  146. V(): hash(0) {}
  147. void f0() { f1(17); }
  148. void g0() const { g1(17); }
  149. void f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
  150. void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
  151. void f2(int a1, int a2) { f1(a1); f1(a2); }
  152. void g2(int a1, int a2) const { g1(a1); g1(a2); }
  153. void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
  154. void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
  155. void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
  156. void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
  157. void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
  158. void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
  159. void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
  160. void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
  161. 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); }
  162. 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); }
  163. 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); }
  164. 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); }
  165. };
  166. BOOST_HOF_TEST_CASE()
  167. {
  168. X x;
  169. // 0
  170. boost::hof::lazy(&X::f0)(&x)();
  171. boost::hof::lazy(&X::f0)(std::ref(x))();
  172. boost::hof::lazy(&X::g0)(&x)();
  173. boost::hof::lazy(&X::g0)(x)();
  174. boost::hof::lazy(&X::g0)(std::ref(x))();
  175. // 1
  176. boost::hof::lazy(&X::f1)(&x, 1)();
  177. boost::hof::lazy(&X::f1)(std::ref(x), 1)();
  178. boost::hof::lazy(&X::g1)(&x, 1)();
  179. boost::hof::lazy(&X::g1)(x, 1)();
  180. boost::hof::lazy(&X::g1)(std::ref(x), 1)();
  181. // 2
  182. boost::hof::lazy(&X::f2)(&x, 1, 2)();
  183. boost::hof::lazy(&X::f2)(std::ref(x), 1, 2)();
  184. boost::hof::lazy(&X::g2)(&x, 1, 2)();
  185. boost::hof::lazy(&X::g2)(x, 1, 2)();
  186. boost::hof::lazy(&X::g2)(std::ref(x), 1, 2)();
  187. // 3
  188. boost::hof::lazy(&X::f3)(&x, 1, 2, 3)();
  189. boost::hof::lazy(&X::f3)(std::ref(x), 1, 2, 3)();
  190. boost::hof::lazy(&X::g3)(&x, 1, 2, 3)();
  191. boost::hof::lazy(&X::g3)(x, 1, 2, 3)();
  192. boost::hof::lazy(&X::g3)(std::ref(x), 1, 2, 3)();
  193. // 4
  194. boost::hof::lazy(&X::f4)(&x, 1, 2, 3, 4)();
  195. boost::hof::lazy(&X::f4)(std::ref(x), 1, 2, 3, 4)();
  196. boost::hof::lazy(&X::g4)(&x, 1, 2, 3, 4)();
  197. boost::hof::lazy(&X::g4)(x, 1, 2, 3, 4)();
  198. boost::hof::lazy(&X::g4)(std::ref(x), 1, 2, 3, 4)();
  199. // 5
  200. boost::hof::lazy(&X::f5)(&x, 1, 2, 3, 4, 5)();
  201. boost::hof::lazy(&X::f5)(std::ref(x), 1, 2, 3, 4, 5)();
  202. boost::hof::lazy(&X::g5)(&x, 1, 2, 3, 4, 5)();
  203. boost::hof::lazy(&X::g5)(x, 1, 2, 3, 4, 5)();
  204. boost::hof::lazy(&X::g5)(std::ref(x), 1, 2, 3, 4, 5)();
  205. // 6
  206. boost::hof::lazy(&X::f6)(&x, 1, 2, 3, 4, 5, 6)();
  207. boost::hof::lazy(&X::f6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
  208. boost::hof::lazy(&X::g6)(&x, 1, 2, 3, 4, 5, 6)();
  209. boost::hof::lazy(&X::g6)(x, 1, 2, 3, 4, 5, 6)();
  210. boost::hof::lazy(&X::g6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
  211. // 7
  212. boost::hof::lazy(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7)();
  213. boost::hof::lazy(&X::f7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
  214. boost::hof::lazy(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7)();
  215. boost::hof::lazy(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7)();
  216. boost::hof::lazy(&X::g7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
  217. // 8
  218. boost::hof::lazy(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
  219. boost::hof::lazy(&X::f8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
  220. boost::hof::lazy(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
  221. boost::hof::lazy(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8)();
  222. boost::hof::lazy(&X::g8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
  223. BOOST_HOF_TEST_CHECK( x.hash == 23558 );
  224. }
  225. BOOST_HOF_TEST_CASE()
  226. {
  227. V v;
  228. // 0
  229. boost::hof::lazy(&V::f0)(&v)();
  230. boost::hof::lazy(&V::f0)(std::ref(v))();
  231. boost::hof::lazy(&V::g0)(&v)();
  232. boost::hof::lazy(&V::g0)(v)();
  233. boost::hof::lazy(&V::g0)(std::ref(v))();
  234. // 1
  235. boost::hof::lazy(&V::f1)(&v, 1)();
  236. boost::hof::lazy(&V::f1)(std::ref(v), 1)();
  237. boost::hof::lazy(&V::g1)(&v, 1)();
  238. boost::hof::lazy(&V::g1)(v, 1)();
  239. boost::hof::lazy(&V::g1)(std::ref(v), 1)();
  240. // 2
  241. boost::hof::lazy(&V::f2)(&v, 1, 2)();
  242. boost::hof::lazy(&V::f2)(std::ref(v), 1, 2)();
  243. boost::hof::lazy(&V::g2)(&v, 1, 2)();
  244. boost::hof::lazy(&V::g2)(v, 1, 2)();
  245. boost::hof::lazy(&V::g2)(std::ref(v), 1, 2)();
  246. // 3
  247. boost::hof::lazy(&V::f3)(&v, 1, 2, 3)();
  248. boost::hof::lazy(&V::f3)(std::ref(v), 1, 2, 3)();
  249. boost::hof::lazy(&V::g3)(&v, 1, 2, 3)();
  250. boost::hof::lazy(&V::g3)(v, 1, 2, 3)();
  251. boost::hof::lazy(&V::g3)(std::ref(v), 1, 2, 3)();
  252. // 4
  253. boost::hof::lazy(&V::f4)(&v, 1, 2, 3, 4)();
  254. boost::hof::lazy(&V::f4)(std::ref(v), 1, 2, 3, 4)();
  255. boost::hof::lazy(&V::g4)(&v, 1, 2, 3, 4)();
  256. boost::hof::lazy(&V::g4)(v, 1, 2, 3, 4)();
  257. boost::hof::lazy(&V::g4)(std::ref(v), 1, 2, 3, 4)();
  258. // 5
  259. boost::hof::lazy(&V::f5)(&v, 1, 2, 3, 4, 5)();
  260. boost::hof::lazy(&V::f5)(std::ref(v), 1, 2, 3, 4, 5)();
  261. boost::hof::lazy(&V::g5)(&v, 1, 2, 3, 4, 5)();
  262. boost::hof::lazy(&V::g5)(v, 1, 2, 3, 4, 5)();
  263. boost::hof::lazy(&V::g5)(std::ref(v), 1, 2, 3, 4, 5)();
  264. // 6
  265. boost::hof::lazy(&V::f6)(&v, 1, 2, 3, 4, 5, 6)();
  266. boost::hof::lazy(&V::f6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
  267. boost::hof::lazy(&V::g6)(&v, 1, 2, 3, 4, 5, 6)();
  268. boost::hof::lazy(&V::g6)(v, 1, 2, 3, 4, 5, 6)();
  269. boost::hof::lazy(&V::g6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
  270. // 7
  271. boost::hof::lazy(&V::f7)(&v, 1, 2, 3, 4, 5, 6, 7)();
  272. boost::hof::lazy(&V::f7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
  273. boost::hof::lazy(&V::g7)(&v, 1, 2, 3, 4, 5, 6, 7)();
  274. boost::hof::lazy(&V::g7)(v, 1, 2, 3, 4, 5, 6, 7)();
  275. boost::hof::lazy(&V::g7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
  276. // 8
  277. boost::hof::lazy(&V::f8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
  278. boost::hof::lazy(&V::f8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
  279. boost::hof::lazy(&V::g8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
  280. boost::hof::lazy(&V::g8)(v, 1, 2, 3, 4, 5, 6, 7, 8)();
  281. boost::hof::lazy(&V::g8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
  282. BOOST_HOF_TEST_CHECK( v.hash == 23558 );
  283. }
  284. struct id
  285. {
  286. int operator()(int i) const
  287. {
  288. return i;
  289. }
  290. };
  291. BOOST_HOF_TEST_CASE()
  292. {
  293. BOOST_HOF_TEST_CHECK(boost::hof::lazy(id())(3)() == 3);
  294. }
  295. struct deref
  296. {
  297. int operator()(const std::unique_ptr<int>& i) const
  298. {
  299. return *i;
  300. }
  301. };
  302. BOOST_HOF_TEST_CASE()
  303. {
  304. BOOST_HOF_TEST_CHECK(boost::hof::lazy(deref())(std::unique_ptr<int>(new int(3)))() == 3);
  305. }
  306. void fv1( std::unique_ptr<int> p1 )
  307. {
  308. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  309. }
  310. void fv2( std::unique_ptr<int> p1, std::unique_ptr<int> p2 )
  311. {
  312. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  313. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  314. }
  315. void fv3( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3 )
  316. {
  317. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  318. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  319. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  320. }
  321. void fv4( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4 )
  322. {
  323. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  324. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  325. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  326. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  327. }
  328. 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 )
  329. {
  330. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  331. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  332. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  333. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  334. BOOST_HOF_TEST_CHECK( *p5 == 5 );
  335. }
  336. 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 )
  337. {
  338. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  339. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  340. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  341. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  342. BOOST_HOF_TEST_CHECK( *p5 == 5 );
  343. BOOST_HOF_TEST_CHECK( *p6 == 6 );
  344. }
  345. 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 )
  346. {
  347. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  348. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  349. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  350. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  351. BOOST_HOF_TEST_CHECK( *p5 == 5 );
  352. BOOST_HOF_TEST_CHECK( *p6 == 6 );
  353. BOOST_HOF_TEST_CHECK( *p7 == 7 );
  354. }
  355. 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 )
  356. {
  357. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  358. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  359. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  360. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  361. BOOST_HOF_TEST_CHECK( *p5 == 5 );
  362. BOOST_HOF_TEST_CHECK( *p6 == 6 );
  363. BOOST_HOF_TEST_CHECK( *p7 == 7 );
  364. BOOST_HOF_TEST_CHECK( *p8 == 8 );
  365. }
  366. 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 )
  367. {
  368. BOOST_HOF_TEST_CHECK( *p1 == 1 );
  369. BOOST_HOF_TEST_CHECK( *p2 == 2 );
  370. BOOST_HOF_TEST_CHECK( *p3 == 3 );
  371. BOOST_HOF_TEST_CHECK( *p4 == 4 );
  372. BOOST_HOF_TEST_CHECK( *p5 == 5 );
  373. BOOST_HOF_TEST_CHECK( *p6 == 6 );
  374. BOOST_HOF_TEST_CHECK( *p7 == 7 );
  375. BOOST_HOF_TEST_CHECK( *p8 == 8 );
  376. BOOST_HOF_TEST_CHECK( *p9 == 9 );
  377. }
  378. BOOST_HOF_TEST_CASE()
  379. {
  380. std::unique_ptr<int> p1( new int(1) );
  381. boost::hof::lazy( fv1 )( std::placeholders::_1 )( std::move( p1 ) );
  382. }
  383. BOOST_HOF_TEST_CASE()
  384. {
  385. std::unique_ptr<int> p1( new int(1) );
  386. std::unique_ptr<int> p2( new int(2) );
  387. boost::hof::lazy( fv2 )( std::placeholders::_1, std::placeholders::_2 )( std::move( p1 ), std::move( p2 ) );
  388. }
  389. BOOST_HOF_TEST_CASE()
  390. {
  391. std::unique_ptr<int> p1( new int(1) );
  392. std::unique_ptr<int> p2( new int(2) );
  393. std::unique_ptr<int> p3( new int(3) );
  394. boost::hof::lazy( fv3 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 )( std::move( p1 ), std::move( p2 ), std::move( p3 ) );
  395. }
  396. BOOST_HOF_TEST_CASE()
  397. {
  398. std::unique_ptr<int> p1( new int(1) );
  399. std::unique_ptr<int> p2( new int(2) );
  400. std::unique_ptr<int> p3( new int(3) );
  401. std::unique_ptr<int> p4( new int(4) );
  402. 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 ) );
  403. }
  404. BOOST_HOF_TEST_CASE()
  405. {
  406. std::unique_ptr<int> p1( new int(1) );
  407. std::unique_ptr<int> p2( new int(2) );
  408. std::unique_ptr<int> p3( new int(3) );
  409. std::unique_ptr<int> p4( new int(4) );
  410. std::unique_ptr<int> p5( new int(5) );
  411. 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 ) );
  412. }
  413. BOOST_HOF_TEST_CASE()
  414. {
  415. std::unique_ptr<int> p1( new int(1) );
  416. std::unique_ptr<int> p2( new int(2) );
  417. std::unique_ptr<int> p3( new int(3) );
  418. std::unique_ptr<int> p4( new int(4) );
  419. std::unique_ptr<int> p5( new int(5) );
  420. std::unique_ptr<int> p6( new int(6) );
  421. 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 ) );
  422. }
  423. BOOST_HOF_TEST_CASE()
  424. {
  425. std::unique_ptr<int> p1( new int(1) );
  426. std::unique_ptr<int> p2( new int(2) );
  427. std::unique_ptr<int> p3( new int(3) );
  428. std::unique_ptr<int> p4( new int(4) );
  429. std::unique_ptr<int> p5( new int(5) );
  430. std::unique_ptr<int> p6( new int(6) );
  431. std::unique_ptr<int> p7( new int(7) );
  432. 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 ) );
  433. }
  434. BOOST_HOF_TEST_CASE()
  435. {
  436. std::unique_ptr<int> p1( new int(1) );
  437. std::unique_ptr<int> p2( new int(2) );
  438. std::unique_ptr<int> p3( new int(3) );
  439. std::unique_ptr<int> p4( new int(4) );
  440. std::unique_ptr<int> p5( new int(5) );
  441. std::unique_ptr<int> p6( new int(6) );
  442. std::unique_ptr<int> p7( new int(7) );
  443. std::unique_ptr<int> p8( new int(8) );
  444. 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 ) );
  445. }
  446. BOOST_HOF_TEST_CASE()
  447. {
  448. std::unique_ptr<int> p1( new int(1) );
  449. std::unique_ptr<int> p2( new int(2) );
  450. std::unique_ptr<int> p3( new int(3) );
  451. std::unique_ptr<int> p4( new int(4) );
  452. std::unique_ptr<int> p5( new int(5) );
  453. std::unique_ptr<int> p6( new int(6) );
  454. std::unique_ptr<int> p7( new int(7) );
  455. std::unique_ptr<int> p8( new int(8) );
  456. std::unique_ptr<int> p9( new int(9) );
  457. 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 ) );
  458. }
  459. struct X_ref
  460. {
  461. int f( int x )
  462. {
  463. return x;
  464. }
  465. int g( int x ) const
  466. {
  467. return -x;
  468. }
  469. };
  470. BOOST_HOF_TEST_CASE()
  471. {
  472. X_ref x;
  473. BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::f )( std::ref( x ), std::placeholders::_1 )( 1 ) == 1 );
  474. BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::g )( std::cref( x ), std::placeholders::_1 )( 2 ) == -2 );
  475. }
  476. BOOST_HOF_TEST_CASE()
  477. {
  478. auto lazy_f_1 = boost::hof::lazy(f_1())(std::placeholders::_1);
  479. static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long>::value, "Invocable");
  480. static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long, long>::value, "Invocable");
  481. auto lazy_f_2 = boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2);
  482. static_assert(boost::hof::is_invocable<decltype(lazy_f_2), long, long>::value, "Invocable");
  483. static_assert(!boost::hof::is_invocable<decltype(lazy_f_2), long>::value, "Not SFINAE-friendly");
  484. }
  485. struct dummy_unary_fn
  486. {
  487. template <typename S>
  488. int operator()(S const &) const { return 0; }
  489. };
  490. struct bad_unary_fn
  491. {
  492. template <typename S>
  493. constexpr int operator()(S const &) const
  494. {
  495. static_assert(!std::is_same<S, S>::value, "Failure");
  496. return 0;
  497. }
  498. };
  499. BOOST_HOF_TEST_CASE()
  500. {
  501. auto b = boost::hof::lazy(dummy_unary_fn())(bad_unary_fn());
  502. b(0);
  503. }
  504. struct by_value_fn
  505. {
  506. template<typename T, typename U>
  507. void operator()(T &&, U &&) const
  508. {
  509. static_assert(std::is_same<U, int>::value, "");
  510. }
  511. };
  512. BOOST_HOF_TEST_CASE()
  513. {
  514. boost::hof::lazy(by_value_fn{})(std::placeholders::_1, 42)("hello");
  515. }
  516. #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
  517. struct copy_throws
  518. {
  519. copy_throws() {}
  520. copy_throws(copy_throws const&) {}
  521. copy_throws(copy_throws&&) noexcept {}
  522. };
  523. struct no_throw_fo
  524. {
  525. void operator()() const noexcept {}
  526. void operator()(int) const noexcept {}
  527. void operator()(copy_throws) const noexcept {}
  528. };
  529. struct throws_fo
  530. {
  531. void operator()() const {}
  532. };
  533. struct member_obj
  534. {
  535. int x;
  536. };
  537. BOOST_HOF_TEST_CASE()
  538. {
  539. no_throw_fo obj;
  540. copy_throws arg;
  541. static_assert(noexcept(boost::hof::lazy(no_throw_fo{})()()), "noexcept lazy");
  542. static_assert(noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
  543. static_assert(!noexcept(boost::hof::lazy(obj)(arg)()), "noexcept lazy");
  544. static_assert(noexcept(boost::hof::lazy(obj)(1)()), "noexcept lazy");
  545. static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)), "noexcept lazy");
  546. // static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)()), "noexcept lazy");
  547. static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(1)), "noexcept lazy");
  548. static_assert(!noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(arg)), "noexcept lazy");
  549. static_assert(noexcept(boost::hof::lazy(obj)(std::move(arg))), "noexcept lazy");
  550. static_assert(!noexcept(boost::hof::lazy(obj)(std::move(arg))()), "noexcept lazy");
  551. }
  552. BOOST_HOF_TEST_CASE()
  553. {
  554. throws_fo obj;
  555. static_assert(!noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
  556. }
  557. BOOST_HOF_TEST_CASE()
  558. {
  559. member_obj obj{42};
  560. static_assert(noexcept(boost::hof::lazy(&member_obj::x)(obj)()), "noexcept lazy");
  561. static_assert(noexcept(boost::hof::lazy(&member_obj::x)(std::placeholders::_1)(obj)), "noexcept lazy");
  562. }
  563. #endif