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/tag_of.hpp>
6 #include <boost/hana/core/when.hpp>
7 
8 #include <type_traits>
9 namespace hana = boost::hana;
10 
11 
12 template <typename T, typename ExpectedDatatype>
13 struct test {
14     static_assert(std::is_same<hana::tag_of_t<T>, ExpectedDatatype>::value, "");
15     static_assert(std::is_same<hana::tag_of_t<T const>, ExpectedDatatype>::value, "");
16     static_assert(std::is_same<hana::tag_of_t<T volatile>, ExpectedDatatype>::value, "");
17     static_assert(std::is_same<hana::tag_of_t<T const volatile>, ExpectedDatatype>::value, "");
18 
19     static_assert(std::is_same<hana::tag_of_t<T&>, ExpectedDatatype>::value, "");
20     static_assert(std::is_same<hana::tag_of_t<T const&>, ExpectedDatatype>::value, "");
21     static_assert(std::is_same<hana::tag_of_t<T volatile&>, ExpectedDatatype>::value, "");
22     static_assert(std::is_same<hana::tag_of_t<T const volatile&>, ExpectedDatatype>::value, "");
23 
24     static_assert(std::is_same<hana::tag_of_t<T&&>, ExpectedDatatype>::value, "");
25     static_assert(std::is_same<hana::tag_of_t<T const&&>, ExpectedDatatype>::value, "");
26     static_assert(std::is_same<hana::tag_of_t<T volatile&&>, ExpectedDatatype>::value, "");
27     static_assert(std::is_same<hana::tag_of_t<T const volatile&&>, ExpectedDatatype>::value, "");
28 };
29 
30 struct NestedDatatype;
31 struct Nested { struct hana_tag; };
32 template struct test<Nested, Nested::hana_tag>;
33 
34 struct NoNestedDatatype { };
35 template struct test<NoNestedDatatype, NoNestedDatatype>;
36 
37 struct NoNestedHana { };
38 template struct test<NoNestedHana, NoNestedHana>;
39 
40 
41 struct FullySpecializedDatatype;
42 struct FullySpecialized;
43 namespace boost { namespace hana {
44     template <>
45     struct tag_of<FullySpecialized> {
46         using type = FullySpecializedDatatype;
47     };
48 }}
49 template struct test<FullySpecialized, FullySpecializedDatatype>;
50 
51 
52 struct PartiallySpecializedDatatype;
53 template <typename> struct PartiallySpecialized;
54 namespace boost { namespace hana {
55     template <typename T>
56     struct tag_of<PartiallySpecialized<T>> {
57         using type = PartiallySpecializedDatatype;
58     };
59 }}
60 template struct test<PartiallySpecialized<struct anything>, PartiallySpecializedDatatype>;
61 
62 
63 struct PredicatedDatatype;
64 struct Predicated { static constexpr bool predicate = true; };
65 namespace boost { namespace hana {
66     template <typename T>
67     struct tag_of<T, hana::when<T::predicate>> {
68         using type = PredicatedDatatype;
69     };
70 }}
71 template struct test<Predicated, PredicatedDatatype>;
72 
73 
main()74 int main() { }
75