]>
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/core/to.hpp> | |
6 | ||
7 | #include <boost/hana/assert.hpp> | |
8 | #include <boost/hana/core/tag_of.hpp> | |
9 | ||
10 | #include <string> | |
11 | #include <type_traits> | |
12 | namespace hana = boost::hana; | |
13 | ||
14 | ||
15 | template <typename X, typename Y> | |
16 | constexpr auto operator==(X x, Y y) | |
17 | { return x.value == y.value; } | |
18 | ||
19 | struct Datatype { | |
20 | int value; | |
21 | using hana_tag = Datatype; | |
22 | }; | |
23 | ||
24 | struct Other { | |
25 | int value; | |
26 | using hana_tag = Datatype; | |
27 | }; | |
28 | ||
29 | struct SpecializedFrom; | |
30 | struct specialized_from { | |
31 | int value; | |
32 | using hana_tag = SpecializedFrom; | |
33 | }; | |
34 | ||
35 | struct SpecializedTo; | |
36 | struct specialized_to { | |
37 | int value; | |
38 | using hana_tag = SpecializedTo; | |
39 | }; | |
40 | ||
41 | namespace boost { namespace hana { | |
42 | template <> | |
43 | struct to_impl<SpecializedTo, SpecializedFrom> { | |
44 | template <typename T> | |
45 | static constexpr auto apply(T t) | |
46 | { return specialized_to{t.value}; } | |
47 | }; | |
48 | }} | |
49 | ||
50 | template <typename F, typename T> | |
51 | void check_convert(F f, T t) { | |
52 | using From = hana::tag_of_t<F>; | |
53 | using To = hana::tag_of_t<T>; | |
54 | ||
55 | // Check From -> To conversion | |
56 | BOOST_HANA_RUNTIME_CHECK(hana::to<To>(f) == t); | |
57 | static_assert(std::is_same< | |
58 | hana::tag_of_t<decltype(hana::to<To>(f))>, To | |
59 | >{}, ""); | |
60 | ||
61 | static_assert(hana::is_convertible<From, To>{}, ""); | |
62 | ||
63 | ||
64 | // Make sure From -> From and To -> To are the identity. | |
65 | BOOST_HANA_RUNTIME_CHECK(hana::to<From>(f) == f); | |
66 | static_assert(std::is_same< | |
67 | hana::tag_of_t<decltype(hana::to<From>(f))>, From | |
68 | >{}, ""); | |
69 | ||
70 | BOOST_HANA_RUNTIME_CHECK(hana::to<To>(t) == t); | |
71 | static_assert(std::is_same< | |
72 | hana::tag_of_t<decltype(hana::to<To>(t))>, To | |
73 | >{}, ""); | |
74 | ||
75 | static_assert(hana::is_convertible<From, From>{}, ""); | |
76 | static_assert(hana::is_convertible<To, To>{}, ""); | |
77 | ||
78 | static_assert(hana::is_embedded<From, From>{}, ""); | |
79 | static_assert(hana::is_embedded<To, To>{}, ""); | |
80 | } | |
81 | ||
82 | template <typename X> | |
83 | void check_variable_template_in_dependent_context(X x) { | |
84 | hana::to<int>(x); | |
85 | } | |
86 | ||
87 | int main() { | |
88 | // Clang used to assert in the code generation when we used variable | |
89 | // templates inside a lambda; this is to catch this. | |
90 | check_variable_template_in_dependent_context(3); | |
91 | ||
92 | check_convert("abcdef", std::string{"abcdef"}); | |
93 | check_convert(int{1}, double{1}); | |
94 | check_convert(double{1}, int{1}); | |
95 | check_convert(std::true_type{}, int{1}); | |
96 | check_convert(std::false_type{}, int{0}); | |
97 | check_convert(Datatype{1}, Datatype{1}); | |
98 | check_convert(Other{1}, Other{1}); | |
99 | check_convert(specialized_from{1}, specialized_to{1}); | |
100 | ||
101 | static_assert(!hana::is_convertible<void, int>{}, ""); | |
102 | static_assert(!hana::is_embedded<void, int>{}, ""); | |
103 | ||
104 | static_assert(hana::is_convertible<int, void>{}, ""); | |
105 | static_assert(!hana::is_embedded<int, void>{}, ""); | |
106 | } |