1#include <c10/util/Metaprogramming.h>
2#include <c10/util/TypeIndex.h>
3#include <gtest/gtest.h>
4
5using c10::string_view;
6using c10::util::get_fully_qualified_type_name;
7using c10::util::get_type_index;
8
9namespace {
10
11static_assert(get_type_index<int>() == get_type_index<int>(), "");
12static_assert(get_type_index<float>() == get_type_index<float>(), "");
13static_assert(get_type_index<int>() != get_type_index<float>(), "");
14static_assert(
15 get_type_index<int(double, double)>() ==
16 get_type_index<int(double, double)>(),
17 "");
18static_assert(
19 get_type_index<int(double, double)>() != get_type_index<int(double)>(),
20 "");
21static_assert(
22 get_type_index<int(double, double)>() ==
23 get_type_index<int (*)(double, double)>(),
24 "");
25static_assert(
26 get_type_index<std::function<int(double, double)>>() ==
27 get_type_index<std::function<int(double, double)>>(),
28 "");
29static_assert(
30 get_type_index<std::function<int(double, double)>>() !=
31 get_type_index<std::function<int(double)>>(),
32 "");
33
34static_assert(get_type_index<int>() == get_type_index<int&>(), "");
35static_assert(get_type_index<int>() == get_type_index<int&&>(), "");
36static_assert(get_type_index<int>() == get_type_index<const int&>(), "");
37static_assert(get_type_index<int>() == get_type_index<const int>(), "");
38static_assert(get_type_index<const int>() == get_type_index<int&>(), "");
39static_assert(get_type_index<int>() != get_type_index<int*>(), "");
40static_assert(get_type_index<int*>() != get_type_index<int**>(), "");
41static_assert(
42 get_type_index<int(double&, double)>() !=
43 get_type_index<int(double, double)>(),
44 "");
45
46struct Dummy final {};
47struct Functor final {
48 int64_t operator()(uint32_t, Dummy&&, const Dummy&) const;
49};
50static_assert(
51 get_type_index<int64_t(uint32_t, Dummy&&, const Dummy&)>() ==
52 get_type_index<
53 c10::guts::infer_function_traits_t<Functor>::func_type>(),
54 "");
55
56namespace test_top_level_name {
57#if C10_TYPENAME_SUPPORTS_CONSTEXPR
58static_assert(
59 string_view::npos != get_fully_qualified_type_name<Dummy>().find("Dummy"),
60 "");
61#endif
62TEST(TypeIndex, TopLevelName) {
63 EXPECT_NE(
64 string_view::npos, get_fully_qualified_type_name<Dummy>().find("Dummy"));
65}
66} // namespace test_top_level_name
67
68namespace test_nested_name {
69struct Dummy final {};
70
71#if C10_TYPENAME_SUPPORTS_CONSTEXPR
72static_assert(
73 string_view::npos !=
74 get_fully_qualified_type_name<Dummy>().find("test_nested_name::Dummy"),
75 "");
76#endif
77TEST(TypeIndex, NestedName) {
78 EXPECT_NE(
79 string_view::npos,
80 get_fully_qualified_type_name<Dummy>().find("test_nested_name::Dummy"));
81}
82} // namespace test_nested_name
83
84namespace test_type_template_parameter {
85template <class T>
86struct Outer final {};
87struct Inner final {};
88
89#if C10_TYPENAME_SUPPORTS_CONSTEXPR
90static_assert(
91 string_view::npos !=
92 get_fully_qualified_type_name<Outer<Inner>>().find(
93 "test_type_template_parameter::Outer"),
94 "");
95static_assert(
96 string_view::npos !=
97 get_fully_qualified_type_name<Outer<Inner>>().find(
98 "test_type_template_parameter::Inner"),
99 "");
100#endif
101TEST(TypeIndex, TypeTemplateParameter) {
102 EXPECT_NE(
103 string_view::npos,
104 get_fully_qualified_type_name<Outer<Inner>>().find(
105 "test_type_template_parameter::Outer"));
106 EXPECT_NE(
107 string_view::npos,
108 get_fully_qualified_type_name<Outer<Inner>>().find(
109 "test_type_template_parameter::Inner"));
110}
111} // namespace test_type_template_parameter
112
113namespace test_nontype_template_parameter {
114template <size_t N>
115struct Class final {};
116
117#if C10_TYPENAME_SUPPORTS_CONSTEXPR
118static_assert(
119 string_view::npos !=
120 get_fully_qualified_type_name<Class<38474355>>().find("38474355"),
121 "");
122#endif
123TEST(TypeIndex, NonTypeTemplateParameter) {
124 EXPECT_NE(
125 string_view::npos,
126 get_fully_qualified_type_name<Class<38474355>>().find("38474355"));
127}
128} // namespace test_nontype_template_parameter
129
130namespace test_type_computations_are_resolved {
131template <class T>
132struct Type final {
133 using type = const T*;
134};
135
136#if C10_TYPENAME_SUPPORTS_CONSTEXPR
137static_assert(
138 string_view::npos !=
139 get_fully_qualified_type_name<typename Type<int>::type>().find("int"),
140 "");
141static_assert(
142 string_view::npos !=
143 get_fully_qualified_type_name<typename Type<int>::type>().find("*"),
144 "");
145
146// but with remove_pointer applied, there is no '*' in the type name anymore
147static_assert(
148 string_view::npos ==
149 get_fully_qualified_type_name<
150 typename std::remove_pointer<typename Type<int>::type>::type>()
151 .find("*"),
152 "");
153#endif
154TEST(TypeIndex, TypeComputationsAreResolved) {
155 EXPECT_NE(
156 string_view::npos,
157 get_fully_qualified_type_name<typename Type<int>::type>().find("int"));
158 EXPECT_NE(
159 string_view::npos,
160 get_fully_qualified_type_name<typename Type<int>::type>().find("*"));
161 // but with remove_pointer applied, there is no '*' in the type name anymore
162 EXPECT_EQ(
163 string_view::npos,
164 get_fully_qualified_type_name<
165 typename std::remove_pointer<typename Type<int>::type>::type>()
166 .find("*"));
167}
168
169struct Functor final {
170 std::string operator()(int64_t a, const Type<int>& b) const;
171};
172#if C10_TYPENAME_SUPPORTS_CONSTEXPR
173static_assert(
174 get_fully_qualified_type_name<std::string(int64_t, const Type<int>&)>() ==
175 get_fully_qualified_type_name<
176 typename c10::guts::infer_function_traits_t<Functor>::func_type>(),
177 "");
178#endif
179TEST(TypeIndex, FunctionTypeComputationsAreResolved) {
180 EXPECT_EQ(
181 get_fully_qualified_type_name<std::string(int64_t, const Type<int>&)>(),
182 get_fully_qualified_type_name<
183 typename c10::guts::infer_function_traits_t<Functor>::func_type>());
184}
185} // namespace test_type_computations_are_resolved
186
187namespace test_function_arguments_and_returns {
188class Dummy final {};
189
190#if C10_TYPENAME_SUPPORTS_CONSTEXPR
191static_assert(
192 string_view::npos !=
193 get_fully_qualified_type_name<Dummy(int)>().find(
194 "test_function_arguments_and_returns::Dummy"),
195 "");
196static_assert(
197 string_view::npos !=
198 get_fully_qualified_type_name<void(Dummy)>().find(
199 "test_function_arguments_and_returns::Dummy"),
200 "");
201#endif
202TEST(TypeIndex, FunctionArgumentsAndReturns) {
203 EXPECT_NE(
204 string_view::npos,
205 get_fully_qualified_type_name<Dummy(int)>().find(
206 "test_function_arguments_and_returns::Dummy"));
207 EXPECT_NE(
208 string_view::npos,
209 get_fully_qualified_type_name<void(Dummy)>().find(
210 "test_function_arguments_and_returns::Dummy"));
211}
212} // namespace test_function_arguments_and_returns
213} // namespace
214