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/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>
12namespace hana = boost::hana;
13
14
15struct x1; struct x2; struct x3;
16struct y1 { }; struct y2 { }; struct y3 { };
17template <typename ...> struct f { struct type; };
18
19template <typename F, typename ...T>
20constexpr auto valid_call(F f, T ...t) -> decltype(((void)f(t...)), true)
21{ return true; }
22constexpr auto valid_call(...)
23{ return false; }
24
25BOOST_HANA_CONSTANT_CHECK(hana::equal(
26 hana::metafunction<f>(),
27 hana::type_c<f<>::type>
28));
29
30BOOST_HANA_CONSTANT_CHECK(hana::equal(
31 hana::metafunction<f>(hana::type_c<x1>),
32 hana::type_c<f<x1>::type>
33));
34
35BOOST_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
40BOOST_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
45using F = decltype(hana::metafunction<f>);
46static_assert(std::is_same<F::apply<>, f<>>::value, "");
47static_assert(std::is_same<F::apply<x1>, f<x1>>::value, "");
48static_assert(std::is_same<F::apply<x1, x2>, f<x1, x2>>::value, "");
49static_assert(std::is_same<F::apply<x1, x2, x3>, f<x1, x2, x3>>::value, "");
50
51// Make sure we're SFINAE-friendly
52template <typename ...T> struct no_type { };
53static_assert(!valid_call(hana::metafunction<no_type>), "");
54static_assert(!valid_call(hana::metafunction<no_type>, hana::type_c<x1>), "");
55
56// Make sure we model the Metafunction concept
57static_assert(hana::Metafunction<decltype(hana::metafunction<f>)>::value, "");
58static_assert(hana::Metafunction<decltype(hana::metafunction<f>)&>::value, "");
59
60// Make sure metafunction is SFINAE-friendly
61template <typename T> struct not_a_metafunction { };
62BOOST_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
68int main() {
69 auto t = hana::type_c<x1>;
70 constexpr auto r = hana::metafunction<f>(t);
71 (void)r;
72}
73

source code of boost/libs/hana/test/type/metafunction.cpp