]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // Copyright Louis Dionne 2013-2017 |
7c673cae FG |
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 | ||
13 | struct extra_t { virtual ~extra_t() { } }; | |
14 | extra_t extra{}; | |
15 | ||
16 | constexpr struct { } invalid{}; | |
17 | ||
18 | template <typename ...> using bool_t = bool; | |
19 | constexpr bool valid_call(...) { return false; } | |
20 | template <typename F, typename ...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> | |
57 | constexpr auto operator()(X x) const -> decltype(x + 1) | |
58 | { return x + 1; } | |
59 | }; | |
60 | constexpr incr_t incr{}; | |
61 | ||
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 | } |