apply.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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. {
  11. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
  12. BOOST_HOF_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
  13. }
  14. BOOST_HOF_TEST_CASE()
  15. {
  16. BOOST_HOF_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
  17. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
  18. }
  19. struct member_sum_f
  20. {
  21. int i;
  22. constexpr member_sum_f(int x) : i(x)
  23. {}
  24. constexpr int add(int x) const
  25. {
  26. return i+x;
  27. }
  28. };
  29. struct member_sum_f_derived
  30. : member_sum_f
  31. {
  32. constexpr member_sum_f_derived(int x) : member_sum_f(x)
  33. {}
  34. };
  35. BOOST_HOF_TEST_CASE()
  36. {
  37. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
  38. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
  39. #ifdef __clang__
  40. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
  41. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
  42. #endif
  43. static_assert(std::is_base_of<member_sum_f, member_sum_f>::value, "Base of failed");
  44. std::unique_ptr<member_sum_f> msp(new member_sum_f(1));
  45. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, msp, 2) == 3);
  46. std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(1));
  47. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, mspd, 2) == 3);
  48. }
  49. BOOST_HOF_TEST_CASE()
  50. {
  51. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
  52. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
  53. #ifdef __clang__
  54. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
  55. BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
  56. #endif
  57. std::unique_ptr<member_sum_f> msp(new member_sum_f(3));
  58. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, msp) == 3);
  59. std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(3));
  60. BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, mspd) == 3);
  61. }
  62. struct mem_hash
  63. {
  64. mutable unsigned int hash;
  65. mem_hash(): hash(0) {}
  66. int f0() { f1(17); return 0; }
  67. int g0() const { g1(17); return 0; }
  68. int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
  69. int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
  70. int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
  71. int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
  72. int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
  73. int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
  74. int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
  75. int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
  76. int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
  77. int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
  78. int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
  79. 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; }
  80. 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; }
  81. 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; }
  82. 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; }
  83. 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; }
  84. };
  85. BOOST_HOF_TEST_CASE()
  86. {
  87. mem_hash x;
  88. mem_hash const & rcx = x;
  89. mem_hash const * pcx = &x;
  90. std::shared_ptr<mem_hash> sp(new mem_hash);
  91. boost::hof::apply(&mem_hash::f0, x);
  92. boost::hof::apply(&mem_hash::f0, &x);
  93. boost::hof::apply(&mem_hash::f0, sp);
  94. boost::hof::apply(&mem_hash::g0, x);
  95. boost::hof::apply(&mem_hash::g0, rcx);
  96. boost::hof::apply(&mem_hash::g0, &x);
  97. boost::hof::apply(&mem_hash::g0, pcx);
  98. boost::hof::apply(&mem_hash::g0, sp);
  99. boost::hof::apply(&mem_hash::f1, x, 1);
  100. boost::hof::apply(&mem_hash::f1, &x, 1);
  101. boost::hof::apply(&mem_hash::f1, sp, 1);
  102. boost::hof::apply(&mem_hash::g1, x, 1);
  103. boost::hof::apply(&mem_hash::g1, rcx, 1);
  104. boost::hof::apply(&mem_hash::g1, &x, 1);
  105. boost::hof::apply(&mem_hash::g1, pcx, 1);
  106. boost::hof::apply(&mem_hash::g1, sp, 1);
  107. boost::hof::apply(&mem_hash::f2, x, 1, 2);
  108. boost::hof::apply(&mem_hash::f2, &x, 1, 2);
  109. boost::hof::apply(&mem_hash::f2, sp, 1, 2);
  110. boost::hof::apply(&mem_hash::g2, x, 1, 2);
  111. boost::hof::apply(&mem_hash::g2, rcx, 1, 2);
  112. boost::hof::apply(&mem_hash::g2, &x, 1, 2);
  113. boost::hof::apply(&mem_hash::g2, pcx, 1, 2);
  114. boost::hof::apply(&mem_hash::g2, sp, 1, 2);
  115. boost::hof::apply(&mem_hash::f3, x, 1, 2, 3);
  116. boost::hof::apply(&mem_hash::f3, &x, 1, 2, 3);
  117. boost::hof::apply(&mem_hash::f3, sp, 1, 2, 3);
  118. boost::hof::apply(&mem_hash::g3, x, 1, 2, 3);
  119. boost::hof::apply(&mem_hash::g3, rcx, 1, 2, 3);
  120. boost::hof::apply(&mem_hash::g3, &x, 1, 2, 3);
  121. boost::hof::apply(&mem_hash::g3, pcx, 1, 2, 3);
  122. boost::hof::apply(&mem_hash::g3, sp, 1, 2, 3);
  123. boost::hof::apply(&mem_hash::f4, x, 1, 2, 3, 4);
  124. boost::hof::apply(&mem_hash::f4, &x, 1, 2, 3, 4);
  125. boost::hof::apply(&mem_hash::f4, sp, 1, 2, 3, 4);
  126. boost::hof::apply(&mem_hash::g4, x, 1, 2, 3, 4);
  127. boost::hof::apply(&mem_hash::g4, rcx, 1, 2, 3, 4);
  128. boost::hof::apply(&mem_hash::g4, &x, 1, 2, 3, 4);
  129. boost::hof::apply(&mem_hash::g4, pcx, 1, 2, 3, 4);
  130. boost::hof::apply(&mem_hash::g4, sp, 1, 2, 3, 4);
  131. boost::hof::apply(&mem_hash::f5, x, 1, 2, 3, 4, 5);
  132. boost::hof::apply(&mem_hash::f5, &x, 1, 2, 3, 4, 5);
  133. boost::hof::apply(&mem_hash::f5, sp, 1, 2, 3, 4, 5);
  134. boost::hof::apply(&mem_hash::g5, x, 1, 2, 3, 4, 5);
  135. boost::hof::apply(&mem_hash::g5, rcx, 1, 2, 3, 4, 5);
  136. boost::hof::apply(&mem_hash::g5, &x, 1, 2, 3, 4, 5);
  137. boost::hof::apply(&mem_hash::g5, pcx, 1, 2, 3, 4, 5);
  138. boost::hof::apply(&mem_hash::g5, sp, 1, 2, 3, 4, 5);
  139. boost::hof::apply(&mem_hash::f6, x, 1, 2, 3, 4, 5, 6);
  140. boost::hof::apply(&mem_hash::f6, &x, 1, 2, 3, 4, 5, 6);
  141. boost::hof::apply(&mem_hash::f6, sp, 1, 2, 3, 4, 5, 6);
  142. boost::hof::apply(&mem_hash::g6, x, 1, 2, 3, 4, 5, 6);
  143. boost::hof::apply(&mem_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
  144. boost::hof::apply(&mem_hash::g6, &x, 1, 2, 3, 4, 5, 6);
  145. boost::hof::apply(&mem_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
  146. boost::hof::apply(&mem_hash::g6, sp, 1, 2, 3, 4, 5, 6);
  147. boost::hof::apply(&mem_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
  148. boost::hof::apply(&mem_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
  149. boost::hof::apply(&mem_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
  150. boost::hof::apply(&mem_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
  151. boost::hof::apply(&mem_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
  152. boost::hof::apply(&mem_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
  153. boost::hof::apply(&mem_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
  154. boost::hof::apply(&mem_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
  155. boost::hof::apply(&mem_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
  156. boost::hof::apply(&mem_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
  157. boost::hof::apply(&mem_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
  158. boost::hof::apply(&mem_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
  159. boost::hof::apply(&mem_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
  160. boost::hof::apply(&mem_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
  161. boost::hof::apply(&mem_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
  162. boost::hof::apply(&mem_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
  163. BOOST_HOF_TEST_CHECK(boost::hof::apply(&mem_hash::hash, x) == 17610 && boost::hof::apply(&mem_hash::hash, sp) == 2155);
  164. }
  165. struct hash_base
  166. {
  167. mutable unsigned int hash;
  168. hash_base(): hash(0) {}
  169. int f0() { f1(17); return 0; }
  170. int g0() const { g1(17); return 0; }
  171. int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
  172. int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
  173. int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
  174. int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
  175. int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
  176. int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
  177. int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
  178. int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
  179. int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
  180. int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
  181. int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
  182. 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; }
  183. 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; }
  184. 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; }
  185. 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; }
  186. 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; }
  187. };
  188. struct derived_hash: public hash_base
  189. {
  190. };
  191. BOOST_HOF_TEST_CASE()
  192. {
  193. derived_hash x;
  194. derived_hash const & rcx = x;
  195. derived_hash const * pcx = &x;
  196. std::shared_ptr<derived_hash> sp(new derived_hash);
  197. boost::hof::apply(&derived_hash::f0, x);
  198. boost::hof::apply(&derived_hash::f0, &x);
  199. boost::hof::apply(&derived_hash::f0, sp);
  200. boost::hof::apply(&derived_hash::g0, x);
  201. boost::hof::apply(&derived_hash::g0, rcx);
  202. boost::hof::apply(&derived_hash::g0, &x);
  203. boost::hof::apply(&derived_hash::g0, pcx);
  204. boost::hof::apply(&derived_hash::g0, sp);
  205. boost::hof::apply(&derived_hash::f1, x, 1);
  206. boost::hof::apply(&derived_hash::f1, &x, 1);
  207. boost::hof::apply(&derived_hash::f1, sp, 1);
  208. boost::hof::apply(&derived_hash::g1, x, 1);
  209. boost::hof::apply(&derived_hash::g1, rcx, 1);
  210. boost::hof::apply(&derived_hash::g1, &x, 1);
  211. boost::hof::apply(&derived_hash::g1, pcx, 1);
  212. boost::hof::apply(&derived_hash::g1, sp, 1);
  213. boost::hof::apply(&derived_hash::f2, x, 1, 2);
  214. boost::hof::apply(&derived_hash::f2, &x, 1, 2);
  215. boost::hof::apply(&derived_hash::f2, sp, 1, 2);
  216. boost::hof::apply(&derived_hash::g2, x, 1, 2);
  217. boost::hof::apply(&derived_hash::g2, rcx, 1, 2);
  218. boost::hof::apply(&derived_hash::g2, &x, 1, 2);
  219. boost::hof::apply(&derived_hash::g2, pcx, 1, 2);
  220. boost::hof::apply(&derived_hash::g2, sp, 1, 2);
  221. boost::hof::apply(&derived_hash::f3, x, 1, 2, 3);
  222. boost::hof::apply(&derived_hash::f3, &x, 1, 2, 3);
  223. boost::hof::apply(&derived_hash::f3, sp, 1, 2, 3);
  224. boost::hof::apply(&derived_hash::g3, x, 1, 2, 3);
  225. boost::hof::apply(&derived_hash::g3, rcx, 1, 2, 3);
  226. boost::hof::apply(&derived_hash::g3, &x, 1, 2, 3);
  227. boost::hof::apply(&derived_hash::g3, pcx, 1, 2, 3);
  228. boost::hof::apply(&derived_hash::g3, sp, 1, 2, 3);
  229. boost::hof::apply(&derived_hash::f4, x, 1, 2, 3, 4);
  230. boost::hof::apply(&derived_hash::f4, &x, 1, 2, 3, 4);
  231. boost::hof::apply(&derived_hash::f4, sp, 1, 2, 3, 4);
  232. boost::hof::apply(&derived_hash::g4, x, 1, 2, 3, 4);
  233. boost::hof::apply(&derived_hash::g4, rcx, 1, 2, 3, 4);
  234. boost::hof::apply(&derived_hash::g4, &x, 1, 2, 3, 4);
  235. boost::hof::apply(&derived_hash::g4, pcx, 1, 2, 3, 4);
  236. boost::hof::apply(&derived_hash::g4, sp, 1, 2, 3, 4);
  237. boost::hof::apply(&derived_hash::f5, x, 1, 2, 3, 4, 5);
  238. boost::hof::apply(&derived_hash::f5, &x, 1, 2, 3, 4, 5);
  239. boost::hof::apply(&derived_hash::f5, sp, 1, 2, 3, 4, 5);
  240. boost::hof::apply(&derived_hash::g5, x, 1, 2, 3, 4, 5);
  241. boost::hof::apply(&derived_hash::g5, rcx, 1, 2, 3, 4, 5);
  242. boost::hof::apply(&derived_hash::g5, &x, 1, 2, 3, 4, 5);
  243. boost::hof::apply(&derived_hash::g5, pcx, 1, 2, 3, 4, 5);
  244. boost::hof::apply(&derived_hash::g5, sp, 1, 2, 3, 4, 5);
  245. boost::hof::apply(&derived_hash::f6, x, 1, 2, 3, 4, 5, 6);
  246. boost::hof::apply(&derived_hash::f6, &x, 1, 2, 3, 4, 5, 6);
  247. boost::hof::apply(&derived_hash::f6, sp, 1, 2, 3, 4, 5, 6);
  248. boost::hof::apply(&derived_hash::g6, x, 1, 2, 3, 4, 5, 6);
  249. boost::hof::apply(&derived_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
  250. boost::hof::apply(&derived_hash::g6, &x, 1, 2, 3, 4, 5, 6);
  251. boost::hof::apply(&derived_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
  252. boost::hof::apply(&derived_hash::g6, sp, 1, 2, 3, 4, 5, 6);
  253. boost::hof::apply(&derived_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
  254. boost::hof::apply(&derived_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
  255. boost::hof::apply(&derived_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
  256. boost::hof::apply(&derived_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
  257. boost::hof::apply(&derived_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
  258. boost::hof::apply(&derived_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
  259. boost::hof::apply(&derived_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
  260. boost::hof::apply(&derived_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
  261. boost::hof::apply(&derived_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
  262. boost::hof::apply(&derived_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
  263. boost::hof::apply(&derived_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
  264. boost::hof::apply(&derived_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
  265. boost::hof::apply(&derived_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
  266. boost::hof::apply(&derived_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
  267. boost::hof::apply(&derived_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
  268. boost::hof::apply(&derived_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
  269. BOOST_HOF_TEST_CHECK(boost::hof::apply(&derived_hash::hash, x) == 17610 && boost::hof::apply(&derived_hash::hash, sp) == 2155);
  270. }
  271. struct dm_t
  272. {
  273. int m;
  274. };
  275. BOOST_HOF_TEST_CASE()
  276. {
  277. dm_t x = { 0 };
  278. boost::hof::apply( &dm_t::m, x ) = 401;
  279. BOOST_HOF_TEST_CHECK( x.m == 401 );
  280. BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, x ) == 401 );
  281. boost::hof::apply( &dm_t::m, &x ) = 502;
  282. BOOST_HOF_TEST_CHECK( x.m == 502 );
  283. BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, &x ) == 502 );
  284. dm_t * px = &x;
  285. boost::hof::apply( &dm_t::m, px ) = 603;
  286. BOOST_HOF_TEST_CHECK( x.m == 603 );
  287. BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, px ) == 603 );
  288. dm_t const & cx = x;
  289. dm_t const * pcx = &x;
  290. BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, cx ) == 603 );
  291. BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, pcx ) == 603 );
  292. }
  293. struct X_ref
  294. {
  295. int f()
  296. {
  297. return 1;
  298. }
  299. int g() const
  300. {
  301. return 2;
  302. }
  303. };
  304. BOOST_HOF_TEST_CASE()
  305. {
  306. X_ref x;
  307. BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::f, std::ref( x ) ) == 1 );
  308. BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::g, std::cref( x ) ) == 2 );
  309. }
  310. #if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
  311. struct copy_throws
  312. {
  313. copy_throws() {}
  314. copy_throws(copy_throws const&) {}
  315. copy_throws(copy_throws&&) noexcept {}
  316. };
  317. struct no_throw_fo
  318. {
  319. void operator()() noexcept {}
  320. void operator()(copy_throws) noexcept {}
  321. };
  322. struct throws_fo
  323. {
  324. void operator()() {}
  325. };
  326. struct member_obj
  327. {
  328. int x;
  329. };
  330. // Only newer versions of gcc support deducing noexcept for member function pointers
  331. #if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 8) || (__GNUC__ > 4))
  332. struct no_throw_member_fun
  333. {
  334. void foo_nullary() noexcept {}
  335. void foo_unary(copy_throws) noexcept {}
  336. };
  337. BOOST_HOF_TEST_CASE()
  338. {
  339. no_throw_member_fun obj;
  340. copy_throws arg;
  341. static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_nullary, obj)), "");
  342. static_assert(!noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, arg)), "");
  343. static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, std::move(arg))), "");
  344. }
  345. #endif
  346. BOOST_HOF_TEST_CASE()
  347. {
  348. no_throw_fo obj;
  349. copy_throws arg;
  350. static_assert(noexcept(boost::hof::apply(obj)), "");
  351. static_assert(!noexcept(boost::hof::apply(obj, arg)), "");
  352. static_assert(noexcept(boost::hof::apply(obj, std::move(arg))), "");
  353. }
  354. BOOST_HOF_TEST_CASE()
  355. {
  356. throws_fo obj;
  357. static_assert(!noexcept(boost::hof::apply(obj)), "");
  358. }
  359. BOOST_HOF_TEST_CASE()
  360. {
  361. member_obj obj{42};
  362. static_assert(noexcept(boost::hof::apply(&member_obj::x, obj)), "");
  363. }
  364. #endif