1// Copyright Louis Dionne 2013-2022
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>
12namespace hana = boost::hana;
13
14
15template <typename X, typename Y>
16constexpr auto operator==(X x, Y y)
17{ return x.value == y.value; }
18
19struct Datatype {
20 int value;
21 using hana_tag = Datatype;
22};
23
24struct Other {
25 int value;
26 using hana_tag = Datatype;
27};
28
29struct SpecializedFrom;
30struct specialized_from {
31 int value;
32 using hana_tag = SpecializedFrom;
33};
34
35struct SpecializedTo;
36struct specialized_to {
37 int value;
38 using hana_tag = SpecializedTo;
39};
40
41namespace 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
50template <typename F, typename T>
51void 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
82template <typename X>
83void check_variable_template_in_dependent_context(X x) {
84 hana::to<int>(x);
85}
86
87int 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(x: 3);
91
92 check_convert(f: "abcdef", t: std::string{"abcdef"});
93 check_convert(f: int{1}, t: double{1});
94 check_convert(f: double{1}, t: int{1});
95 check_convert(f: std::true_type{}, t: int{1});
96 check_convert(f: std::false_type{}, t: int{0});
97 check_convert(f: Datatype{.value: 1}, t: Datatype{.value: 1});
98 check_convert(f: Other{.value: 1}, t: Other{.value: 1});
99 check_convert(f: specialized_from{.value: 1}, t: specialized_to{.value: 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}
107

source code of boost/libs/hana/test/core/to.cpp