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/assert.hpp>
6 #include <boost/hana/concept/metafunction.hpp>
7 #include <boost/hana/equal.hpp>
8 #include <boost/hana/not.hpp>
9 #include <boost/hana/type.hpp>
10 
11 #include <type_traits>
12 namespace hana = boost::hana;
13 
14 
15 struct x1; struct x2; struct x3;
16 struct y1 { }; struct y2 { }; struct y3 { };
17 template <typename ...> struct f { struct type; };
18 
19 template <typename F, typename ...T>
valid_call(F f,T...t)20 constexpr auto valid_call(F f, T ...t) -> decltype(((void)f(t...)), true)
21 { return true; }
valid_call(...)22 constexpr auto valid_call(...)
23 { return false; }
24 
25 BOOST_HANA_CONSTANT_CHECK(hana::equal(
26     hana::metafunction<f>(),
27     hana::type_c<f<>::type>
28 ));
29 
30 BOOST_HANA_CONSTANT_CHECK(hana::equal(
31     hana::metafunction<f>(hana::type_c<x1>),
32     hana::type_c<f<x1>::type>
33 ));
34 
35 BOOST_HANA_CONSTANT_CHECK(hana::equal(
36     hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>),
37     hana::type_c<f<x1, x2>::type>
38 ));
39 
40 BOOST_HANA_CONSTANT_CHECK(hana::equal(
41     hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>),
42     hana::type_c<f<x1, x2, x3>::type>
43 ));
44 
45 using F = decltype(hana::metafunction<f>);
46 static_assert(std::is_same<F::apply<>, f<>>::value, "");
47 static_assert(std::is_same<F::apply<x1>, f<x1>>::value, "");
48 static_assert(std::is_same<F::apply<x1, x2>, f<x1, x2>>::value, "");
49 static_assert(std::is_same<F::apply<x1, x2, x3>, f<x1, x2, x3>>::value, "");
50 
51 // Make sure we're SFINAE-friendly
52 template <typename ...T> struct no_type { };
53 static_assert(!valid_call(hana::metafunction<no_type>), "");
54 static_assert(!valid_call(hana::metafunction<no_type>, hana::type_c<x1>), "");
55 
56 // Make sure we model the Metafunction concept
57 static_assert(hana::Metafunction<decltype(hana::metafunction<f>)>::value, "");
58 static_assert(hana::Metafunction<decltype(hana::metafunction<f>)&>::value, "");
59 
60 // Make sure metafunction is SFINAE-friendly
61 template <typename T> struct not_a_metafunction { };
62 BOOST_HANA_CONSTANT_CHECK(hana::not_(
63     hana::is_valid(hana::metafunction<not_a_metafunction>)(hana::type_c<void>)
64 ));
65 
66 
67 // Make sure we don't read from a non-constexpr variable
main()68 int main() {
69     auto t = hana::type_c<x1>;
70     constexpr auto r = hana::metafunction<f>(t);
71     (void)r;
72 }
73