• 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/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>
operator ==(X x,Y 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>
applyboost::hana::to_impl45         static constexpr auto apply(T t)
46         { return specialized_to{t.value}; }
47     };
48 }}
49 
50 template <typename F, typename T>
check_convert(F f,T 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>
check_variable_template_in_dependent_context(X x)83 void check_variable_template_in_dependent_context(X x) {
84     hana::to<int>(x);
85 }
86 
main()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 }
107