result_of_tests.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // result_of_tests.cpp -- The Boost Lambda Library ------------------
  2. //
  3. // Copyright (C) 2010 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // For more information, see www.boost.org
  10. // -----------------------------------------------------------------------
  11. #include <boost/test/minimal.hpp> // see "Header Implementation Option"
  12. #include <boost/lambda/bind.hpp>
  13. #include <boost/lambda/lambda.hpp>
  14. #include <boost/mpl/assert.hpp>
  15. #include <boost/type_traits/is_same.hpp>
  16. struct with_result_type {
  17. typedef int result_type;
  18. int operator()() const { return 0; }
  19. int operator()(int) const { return 1; }
  20. int operator()(int, int) const { return 2; }
  21. int operator()(int, int, int) const { return 3; }
  22. int operator()(int, int, int, int) const { return 4; }
  23. int operator()(int, int, int, int, int) const { return 5; }
  24. int operator()(int, int, int, int, int, int) const { return 6; }
  25. int operator()(int, int, int, int, int, int, int) const { return 7; }
  26. int operator()(int, int, int, int, int, int, int, int) const { return 8; }
  27. int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
  28. };
  29. struct with_result_template_value {
  30. template<class Sig>
  31. struct result;
  32. template<class This>
  33. struct result<This()> {
  34. typedef int type;
  35. };
  36. template<class This, class A1>
  37. struct result<This(A1)> {
  38. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  39. typedef int type;
  40. };
  41. template<class This, class A1, class A2>
  42. struct result<This(A1, A2)> {
  43. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  44. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  45. typedef int type;
  46. };
  47. template<class This, class A1, class A2, class A3>
  48. struct result<This(A1, A2, A3)> {
  49. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  50. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  51. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  52. typedef int type;
  53. };
  54. template<class This, class A1, class A2, class A3, class A4>
  55. struct result<This(A1, A2, A3, A4)> {
  56. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  57. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  58. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  59. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  60. typedef int type;
  61. };
  62. template<class This, class A1, class A2, class A3, class A4, class A5>
  63. struct result<This(A1, A2, A3, A4, A5)> {
  64. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  65. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  66. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  67. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  68. BOOST_MPL_ASSERT((boost::is_same<A5, int>));
  69. typedef int type;
  70. };
  71. template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
  72. struct result<This(A1, A2, A3, A4, A5, A6)> {
  73. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  74. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  75. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  76. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  77. BOOST_MPL_ASSERT((boost::is_same<A5, int>));
  78. BOOST_MPL_ASSERT((boost::is_same<A6, int>));
  79. typedef int type;
  80. };
  81. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
  82. struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
  83. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  84. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  85. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  86. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  87. BOOST_MPL_ASSERT((boost::is_same<A5, int>));
  88. BOOST_MPL_ASSERT((boost::is_same<A6, int>));
  89. BOOST_MPL_ASSERT((boost::is_same<A7, int>));
  90. typedef int type;
  91. };
  92. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
  93. struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
  94. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  95. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  96. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  97. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  98. BOOST_MPL_ASSERT((boost::is_same<A5, int>));
  99. BOOST_MPL_ASSERT((boost::is_same<A6, int>));
  100. BOOST_MPL_ASSERT((boost::is_same<A7, int>));
  101. BOOST_MPL_ASSERT((boost::is_same<A8, int>));
  102. typedef int type;
  103. };
  104. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
  105. struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
  106. BOOST_MPL_ASSERT((boost::is_same<A1, int>));
  107. BOOST_MPL_ASSERT((boost::is_same<A2, int>));
  108. BOOST_MPL_ASSERT((boost::is_same<A3, int>));
  109. BOOST_MPL_ASSERT((boost::is_same<A4, int>));
  110. BOOST_MPL_ASSERT((boost::is_same<A5, int>));
  111. BOOST_MPL_ASSERT((boost::is_same<A6, int>));
  112. BOOST_MPL_ASSERT((boost::is_same<A7, int>));
  113. BOOST_MPL_ASSERT((boost::is_same<A8, int>));
  114. BOOST_MPL_ASSERT((boost::is_same<A9, int>));
  115. typedef int type;
  116. };
  117. int operator()() const { return 0; }
  118. int operator()(int) const { return 1; }
  119. int operator()(int, int) const { return 2; }
  120. int operator()(int, int, int) const { return 3; }
  121. int operator()(int, int, int, int) const { return 4; }
  122. int operator()(int, int, int, int, int) const { return 5; }
  123. int operator()(int, int, int, int, int, int) const { return 6; }
  124. int operator()(int, int, int, int, int, int, int) const { return 7; }
  125. int operator()(int, int, int, int, int, int, int, int) const { return 8; }
  126. int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
  127. };
  128. struct with_result_template_reference {
  129. template<class Sig>
  130. struct result;
  131. template<class This>
  132. struct result<This()> {
  133. typedef int type;
  134. };
  135. template<class This, class A1>
  136. struct result<This(A1)> {
  137. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  138. typedef int type;
  139. };
  140. template<class This, class A1, class A2>
  141. struct result<This(A1, A2)> {
  142. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  143. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  144. typedef int type;
  145. };
  146. template<class This, class A1, class A2, class A3>
  147. struct result<This(A1, A2, A3)> {
  148. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  149. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  150. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  151. typedef int type;
  152. };
  153. template<class This, class A1, class A2, class A3, class A4>
  154. struct result<This(A1, A2, A3, A4)> {
  155. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  156. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  157. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  158. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  159. typedef int type;
  160. };
  161. template<class This, class A1, class A2, class A3, class A4, class A5>
  162. struct result<This(A1, A2, A3, A4, A5)> {
  163. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  164. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  165. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  166. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  167. BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
  168. typedef int type;
  169. };
  170. template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
  171. struct result<This(A1, A2, A3, A4, A5, A6)> {
  172. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  173. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  174. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  175. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  176. BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
  177. BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
  178. typedef int type;
  179. };
  180. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
  181. struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
  182. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  183. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  184. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  185. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  186. BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
  187. BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
  188. BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
  189. typedef int type;
  190. };
  191. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
  192. struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
  193. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  194. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  195. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  196. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  197. BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
  198. BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
  199. BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
  200. BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
  201. typedef int type;
  202. };
  203. template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
  204. struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
  205. BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
  206. BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
  207. BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
  208. BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
  209. BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
  210. BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
  211. BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
  212. BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
  213. BOOST_MPL_ASSERT((boost::is_same<A9, int&>));
  214. typedef int type;
  215. };
  216. int operator()() const { return 0; }
  217. int operator()(int) const { return 1; }
  218. int operator()(int, int) const { return 2; }
  219. int operator()(int, int, int) const { return 3; }
  220. int operator()(int, int, int, int) const { return 4; }
  221. int operator()(int, int, int, int, int) const { return 5; }
  222. int operator()(int, int, int, int, int, int) const { return 6; }
  223. int operator()(int, int, int, int, int, int, int) const { return 7; }
  224. int operator()(int, int, int, int, int, int, int, int) const { return 8; }
  225. int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
  226. };
  227. template<class F>
  228. typename boost::result_of<F()>::type apply0(F f) {
  229. return f();
  230. }
  231. template<class A, class F>
  232. typename boost::result_of<F(A)>::type apply1(F f, A a) {
  233. return f(a);
  234. }
  235. template<class A, class B, class F>
  236. typename boost::result_of<F(A, B)>::type apply2(F f, A a, B b) {
  237. return f(a, b);
  238. }
  239. template<class A, class B, class C, class F>
  240. typename boost::result_of<F(A, B, C)>::type apply3(F f, A a, B b, C c) {
  241. return f(a, b, c);
  242. }
  243. using namespace boost::lambda;
  244. int test_main(int, char *[]) {
  245. BOOST_CHECK(boost::lambda::bind(with_result_type())() == 0);
  246. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1)() == 1);
  247. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2)() == 2);
  248. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3)() == 3);
  249. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)() == 4);
  250. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)() == 5);
  251. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)() == 6);
  252. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)() == 7);
  253. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
  254. BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
  255. // Nullary result_of fails
  256. //BOOST_CHECK(boost::lambda::bind(with_result_template_value())() == 0);
  257. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1)() == 1);
  258. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2)() == 2);
  259. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3)() == 3);
  260. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)() == 4);
  261. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)() == 5);
  262. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)() == 6);
  263. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)() == 7);
  264. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
  265. BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
  266. int one = 1,
  267. two = 2,
  268. three = 3,
  269. four = 4,
  270. five = 5,
  271. six = 6,
  272. seven = 7,
  273. eight = 8,
  274. nine = 9;
  275. // Nullary result_of fails
  276. //BOOST_CHECK(boost::lambda::bind(with_result_template_reference())() == 0);
  277. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one))() == 1);
  278. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two))() == 2);
  279. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three))() == 3);
  280. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four))() == 4);
  281. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five))() == 5);
  282. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six))() == 6);
  283. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven))() == 7);
  284. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight))() == 8);
  285. BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight), var(nine))() == 9);
  286. // Check using result_of with lambda functors
  287. BOOST_CHECK(apply0(constant(0)) == 0);
  288. BOOST_CHECK(apply1<int>(_1, one) == 1);
  289. BOOST_CHECK(apply1<int&>(_1, one) == 1);
  290. BOOST_CHECK(apply1<const int&>(_1, one) == 1);
  291. BOOST_CHECK((apply2<int, int>(_1 + _2, one, two) == 3));
  292. BOOST_CHECK((apply2<int&, int&>(_1 + _2, one, two) == 3));
  293. BOOST_CHECK((apply2<const int&, const int&>(_1 + _2, one, two) == 3));
  294. BOOST_CHECK((apply3<int, int, int>(_1 + _2 + _3, one, two, three) == 6));
  295. BOOST_CHECK((apply3<int&, int&, int&>(_1 + _2 + _3, one, two, three) == 6));
  296. BOOST_CHECK((apply3<const int&, const int&, const int&>(_1 + _2 + _3, one, two, three) == 6));
  297. return 0;
  298. }