placeholder.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #include <boost/hana/assert.hpp>
  5. #include <boost/hana/functional/placeholder.hpp>
  6. #include <utility>
  7. namespace hana = boost::hana;
  8. using hana::_;
  9. struct extra_t { virtual ~extra_t() { } };
  10. extra_t extra{};
  11. constexpr struct { } invalid{};
  12. template <typename ...> using bool_t = bool;
  13. constexpr bool valid_call(...) { return false; }
  14. template <typename F, typename ...Args>
  15. constexpr auto valid_call(F&& f, Args&& ...args)
  16. -> bool_t<decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
  17. { return true; }
  18. #define BOOST_HANA_TEST_BINARY_OP(op, x, y) \
  19. static_assert((_ op _)(x, y) == (x op y), ""); \
  20. BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra) == (x op y)); \
  21. BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra, extra) == (x op y)); \
  22. static_assert(!valid_call(_ op _), ""); \
  23. static_assert(!valid_call(_ op _, invalid), ""); \
  24. static_assert(!valid_call(_ op _, invalid, invalid), ""); \
  25. \
  26. static_assert((_ op y)(x) == (x op y), ""); \
  27. BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra) == (x op y)); \
  28. BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra, extra) == (x op y)); \
  29. static_assert(!valid_call(_ op y), ""); \
  30. static_assert(!valid_call(_ op y, invalid), ""); \
  31. \
  32. static_assert((x op _)(y) == (x op y), ""); \
  33. BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra) == (x op y)); \
  34. BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra, extra) == (x op y)); \
  35. static_assert(!valid_call(x op _), ""); \
  36. static_assert(!valid_call(x op _, invalid), ""); \
  37. static_assert(!valid_call(x op _, invalid), ""); \
  38. /**/
  39. #define BOOST_HANA_TEST_UNARY_OP(op, x) \
  40. static_assert((op _)(x) == (op x), ""); \
  41. BOOST_HANA_RUNTIME_CHECK((op _)(x, extra) == (op x)); \
  42. BOOST_HANA_RUNTIME_CHECK((op _)(x, extra, extra) == (op x)); \
  43. static_assert(!valid_call(op _), ""); \
  44. static_assert(!valid_call(op _, invalid), ""); \
  45. /**/
  46. struct incr_t {
  47. template <typename X>
  48. constexpr auto operator()(X x) const -> decltype(x + 1)
  49. { return x + 1; }
  50. };
  51. constexpr incr_t incr{};
  52. int main() {
  53. // Arithmetic
  54. BOOST_HANA_TEST_UNARY_OP(+, 1)
  55. BOOST_HANA_TEST_UNARY_OP(-, 1)
  56. BOOST_HANA_TEST_BINARY_OP(+, 6, 3)
  57. BOOST_HANA_TEST_BINARY_OP(-, 6, 3)
  58. BOOST_HANA_TEST_BINARY_OP(*, 6, 3)
  59. BOOST_HANA_TEST_BINARY_OP(/, 6, 3)
  60. BOOST_HANA_TEST_BINARY_OP(%, 6, 3)
  61. // Bitwise
  62. BOOST_HANA_TEST_UNARY_OP(~, 5)
  63. BOOST_HANA_TEST_BINARY_OP(&, 6, 3)
  64. BOOST_HANA_TEST_BINARY_OP(|, 6, 3)
  65. BOOST_HANA_TEST_BINARY_OP(^, 6, 3)
  66. BOOST_HANA_TEST_BINARY_OP(<<, 6, 3)
  67. BOOST_HANA_TEST_BINARY_OP(>>, 6, 3)
  68. // Comparison
  69. BOOST_HANA_TEST_BINARY_OP(==, 6, 3)
  70. BOOST_HANA_TEST_BINARY_OP(!=, 6, 3)
  71. BOOST_HANA_TEST_BINARY_OP(<, 6, 3)
  72. BOOST_HANA_TEST_BINARY_OP(<=, 6, 3)
  73. BOOST_HANA_TEST_BINARY_OP(>, 6, 3)
  74. BOOST_HANA_TEST_BINARY_OP(>=, 6, 3)
  75. // Logical
  76. BOOST_HANA_TEST_BINARY_OP(||, true, false)
  77. BOOST_HANA_TEST_BINARY_OP(&&, true, true)
  78. BOOST_HANA_TEST_UNARY_OP(!, true)
  79. // Member access
  80. constexpr int i = 4;
  81. constexpr int array[] = {0, 1, 2};
  82. BOOST_HANA_TEST_UNARY_OP(*, &i)
  83. static_assert(_[0](array) == array[0], "");
  84. BOOST_HANA_RUNTIME_CHECK(_[0](array, extra) == array[0]);
  85. BOOST_HANA_RUNTIME_CHECK(_[0](array, extra, extra) == array[0]);
  86. static_assert(_[1](array) == array[1], "");
  87. static_assert(_[1](array) == array[1], "");
  88. static_assert(_[2](array) == array[2], "");
  89. static_assert(!valid_call(_[invalid]), "");
  90. static_assert(!valid_call(_[invalid], array), "");
  91. static_assert(!valid_call(_[invalid], invalid), "");
  92. static_assert(!valid_call(_[0], invalid), "");
  93. // Call operator
  94. static_assert(_(1)(incr) == incr(1), "");
  95. BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra) == incr(1));
  96. BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra, extra) == incr(1));
  97. static_assert(_(2)(incr) == incr(2), "");
  98. static_assert(_(3)(incr) == incr(3), "");
  99. static_assert(!valid_call(_(invalid)), "");
  100. static_assert(!valid_call(_(invalid), incr), "");
  101. static_assert(!valid_call(_(invalid), invalid), "");
  102. static_assert(!valid_call(_(1), invalid), "");
  103. }