|
1 | 1 |
|
| 2 | +#include <memory> |
2 | 3 | #include <type_traits> |
3 | 4 |
|
4 | 5 | #include <catch2/catch_template_test_macros.hpp> |
|
8 | 9 |
|
9 | 10 | namespace { |
10 | 11 |
|
11 | | -template <typename T> |
12 | | -concept good_deref = requires (lf::ev<T> val, T ref) { |
| 12 | +template <typename T, typename Ref> |
| 13 | +concept deref_like = requires (T val, Ref ref) { |
13 | 14 | { *val } -> std::same_as<decltype((ref))>; |
| 15 | + { *std::move(val) } -> std::same_as<decltype(std::move(ref))>; |
14 | 16 | }; |
15 | 17 |
|
16 | | -template <typename T> |
17 | | -struct add_const : std::type_identity<T const> {}; |
| 18 | +struct non_trivial { |
| 19 | + constexpr ~non_trivial() {} |
| 20 | +}; |
18 | 21 |
|
19 | | -template <typename T> |
20 | | -struct add_const<T &> : std::type_identity<T const &> {}; |
| 22 | +static_assert(!lf::trivial_return<non_trivial>); |
21 | 23 |
|
22 | | -template <typename T> |
23 | | -struct add_const<T &&> : std::type_identity<T const &&> {}; |
| 24 | +consteval auto const_test() -> bool { |
24 | 25 |
|
25 | | -template <typename T> |
26 | | -concept good_decref = requires (lf::ev<T> const val, typename add_const<T>::type ref) { |
27 | | - { *val } -> std::same_as<decltype((ref))>; |
28 | | -}; |
| 26 | + { |
| 27 | + lf::ev<non_trivial const> x; |
| 28 | + x.emplace(); |
| 29 | + } |
29 | 30 |
|
30 | | -struct nt { |
31 | | - nt() {} |
32 | | -}; |
| 31 | + { |
| 32 | + lf::ev<int> x; |
| 33 | + int const *p = x.get(); |
| 34 | + std::construct_at(p, 3); |
| 35 | + } |
33 | 36 |
|
34 | | -static_assert(!lf::trivial_return<nt>); |
| 37 | + return true; |
| 38 | +} |
35 | 39 |
|
36 | 40 | } // namespace |
37 | 41 |
|
38 | | -TEMPLATE_TEST_CASE("Ev operator *", "[ev]", nt, int, int &, int &&, int const &, int const &&) { |
| 42 | +TEST_CASE("Ev constexpr tests", "[ev]") { REQUIRE(const_test()); } |
39 | 43 |
|
40 | | - using U = std::remove_reference_t<TestType>; |
| 44 | +TEMPLATE_TEST_CASE("Ev operator *", "[ev]", non_trivial, int) { |
41 | 45 |
|
42 | | - static_assert(good_deref<TestType>); |
43 | | - static_assert(good_decref<TestType>); |
| 46 | + using lf::ev; |
44 | 47 |
|
45 | | - lf::ev<TestType> val{}; |
46 | | - static_assert(std::same_as<decltype(*val), U &>); |
47 | | - static_assert(std::same_as<decltype(*std::move(val)), U &&>); |
| 48 | + static_assert(deref_like<ev<TestType>, TestType>); |
| 49 | + static_assert(deref_like<ev<TestType> const, TestType const>); |
48 | 50 |
|
49 | | - lf::ev<TestType> const cval{}; |
50 | | - static_assert(std::same_as<decltype(*cval), U const &>); |
51 | | - static_assert(std::same_as<decltype(*std::move(cval)), U const &&>); |
| 51 | + static_assert(deref_like<ev<TestType const>, TestType const>); |
| 52 | + static_assert(deref_like<ev<TestType const> const, TestType const>); |
| 53 | + |
| 54 | + static_assert(deref_like<ev<TestType &>, TestType &>); |
| 55 | + static_assert(deref_like<ev<TestType &> const, TestType const &>); |
| 56 | + |
| 57 | + static_assert(deref_like<ev<TestType const &>, TestType const &>); |
| 58 | + static_assert(deref_like<ev<TestType const &> const, TestType const &>); |
| 59 | + |
| 60 | + static_assert(deref_like<ev<TestType &&>, TestType &&>); |
| 61 | + static_assert(deref_like<ev<TestType &&> const, TestType const &&>); |
| 62 | + |
| 63 | + static_assert(deref_like<ev<TestType const &&>, TestType const &&>); |
| 64 | + static_assert(deref_like<ev<TestType const &&> const, TestType const &&>); |
52 | 65 | } |
53 | 66 |
|
54 | | -TEMPLATE_TEST_CASE("Eventually operator ->", "[ev]", nt, int, int &) { |
| 67 | +TEMPLATE_TEST_CASE("Eventually operator ->", "[ev]", non_trivial, non_trivial &, int, int &) { |
55 | 68 |
|
56 | | - using U = std::remove_reference_t<TestType>; |
| 69 | + using deref = std::remove_reference_t<TestType>; |
57 | 70 |
|
58 | 71 | lf::ev<TestType> val{}; |
59 | | - static_assert(std::same_as<decltype(val.operator->()), U *>); |
| 72 | + static_assert(std::same_as<decltype(val.operator->()), deref *>); |
60 | 73 |
|
61 | 74 | lf::ev<TestType> const cval{}; |
62 | | - static_assert(std::same_as<decltype(cval.operator->()), U const *>); |
| 75 | + static_assert(std::same_as<decltype(cval.operator->()), deref const *>); |
63 | 76 | } |
0 commit comments