• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #include <boost/hana/assert.hpp>
6 #include <boost/hana/functional/placeholder.hpp>
7 
8 #include <utility>
9 namespace hana = boost::hana;
10 using hana::_;
11 
12 
~extra_textra_t13 struct extra_t { virtual ~extra_t() { } };
14 extra_t extra{};
15 
16 constexpr struct { } invalid{};
17 
18 template <typename ...> using bool_t = bool;
valid_call(...)19 constexpr bool valid_call(...) { return false; }
20 template <typename F, typename ...Args>
valid_call(F && f,Args &&...args)21 constexpr auto valid_call(F&& f, Args&& ...args)
22     -> bool_t<decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
23 { return true; }
24 
25 #define BOOST_HANA_TEST_BINARY_OP(op, x, y)                                 \
26     static_assert((_ op _)(x, y) == (x op y), "");                          \
27     BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra) == (x op y));            \
28     BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra, extra) == (x op y));     \
29     static_assert(!valid_call(_ op _), "");                                 \
30     static_assert(!valid_call(_ op _, invalid), "");                        \
31     static_assert(!valid_call(_ op _, invalid, invalid), "");               \
32                                                                             \
33     static_assert((_ op y)(x) == (x op y), "");                             \
34     BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra) == (x op y));               \
35     BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra, extra) == (x op y));        \
36     static_assert(!valid_call(_ op y), "");                                 \
37     static_assert(!valid_call(_ op y, invalid), "");                        \
38                                                                             \
39     static_assert((x op _)(y) == (x op y), "");                             \
40     BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra) == (x op y));               \
41     BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra, extra) == (x op y));        \
42     static_assert(!valid_call(x op _), "");                                 \
43     static_assert(!valid_call(x op _, invalid), "");                        \
44     static_assert(!valid_call(x op _, invalid), "");                        \
45 /**/
46 
47 #define BOOST_HANA_TEST_UNARY_OP(op, x)                                     \
48     static_assert((op _)(x) == (op x), "");                                 \
49     BOOST_HANA_RUNTIME_CHECK((op _)(x, extra) == (op x));                   \
50     BOOST_HANA_RUNTIME_CHECK((op _)(x, extra, extra) == (op x));            \
51     static_assert(!valid_call(op _), "");                                   \
52     static_assert(!valid_call(op _, invalid), "");                          \
53 /**/
54 
55 struct incr_t {
56     template <typename X>
operator ()incr_t57     constexpr auto operator()(X x) const -> decltype(x + 1)
58     { return x + 1; }
59 };
60 constexpr incr_t incr{};
61 
main()62 int main() {
63     // Arithmetic
64     BOOST_HANA_TEST_UNARY_OP(+, 1)
65     BOOST_HANA_TEST_UNARY_OP(-, 1)
66     BOOST_HANA_TEST_BINARY_OP(+, 6, 3)
67     BOOST_HANA_TEST_BINARY_OP(-, 6, 3)
68     BOOST_HANA_TEST_BINARY_OP(*, 6, 3)
69     BOOST_HANA_TEST_BINARY_OP(/, 6, 3)
70     BOOST_HANA_TEST_BINARY_OP(%, 6, 3)
71 
72     // Bitwise
73     BOOST_HANA_TEST_UNARY_OP(~, 5)
74     BOOST_HANA_TEST_BINARY_OP(&, 6, 3)
75     BOOST_HANA_TEST_BINARY_OP(|, 6, 3)
76     BOOST_HANA_TEST_BINARY_OP(^, 6, 3)
77     BOOST_HANA_TEST_BINARY_OP(<<, 6, 3)
78     BOOST_HANA_TEST_BINARY_OP(>>, 6, 3)
79 
80     // Comparison
81     BOOST_HANA_TEST_BINARY_OP(==, 6, 3)
82     BOOST_HANA_TEST_BINARY_OP(!=, 6, 3)
83     BOOST_HANA_TEST_BINARY_OP(<, 6, 3)
84     BOOST_HANA_TEST_BINARY_OP(<=, 6, 3)
85     BOOST_HANA_TEST_BINARY_OP(>, 6, 3)
86     BOOST_HANA_TEST_BINARY_OP(>=, 6, 3)
87 
88     // Logical
89     BOOST_HANA_TEST_BINARY_OP(||, true, false)
90     BOOST_HANA_TEST_BINARY_OP(&&, true, true)
91     BOOST_HANA_TEST_UNARY_OP(!, true)
92 
93     // Member access
94     constexpr int i = 4;
95     constexpr int array[] = {0, 1, 2};
96     BOOST_HANA_TEST_UNARY_OP(*, &i)
97 
98     static_assert(_[0](array) == array[0], "");
99     BOOST_HANA_RUNTIME_CHECK(_[0](array, extra) == array[0]);
100     BOOST_HANA_RUNTIME_CHECK(_[0](array, extra, extra) == array[0]);
101     static_assert(_[1](array) == array[1], "");
102     static_assert(_[1](array) == array[1], "");
103     static_assert(_[2](array) == array[2], "");
104     static_assert(!valid_call(_[invalid]), "");
105     static_assert(!valid_call(_[invalid], array), "");
106     static_assert(!valid_call(_[invalid], invalid), "");
107     static_assert(!valid_call(_[0], invalid), "");
108 
109     // Call operator
110     static_assert(_(1)(incr) == incr(1), "");
111     BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra) == incr(1));
112     BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra, extra) == incr(1));
113     static_assert(_(2)(incr) == incr(2), "");
114     static_assert(_(3)(incr) == incr(3), "");
115     static_assert(!valid_call(_(invalid)), "");
116     static_assert(!valid_call(_(invalid), incr), "");
117     static_assert(!valid_call(_(invalid), invalid), "");
118     static_assert(!valid_call(_(1), invalid), "");
119 }
120