1 | #include <c10/util/Metaprogramming.h> |
2 | #include <c10/util/TypeIndex.h> |
3 | #include <gtest/gtest.h> |
4 | |
5 | using c10::string_view; |
6 | using c10::util::get_fully_qualified_type_name; |
7 | using c10::util::get_type_index; |
8 | |
9 | namespace { |
10 | |
11 | static_assert(get_type_index<int>() == get_type_index<int>(), "" ); |
12 | static_assert(get_type_index<float>() == get_type_index<float>(), "" ); |
13 | static_assert(get_type_index<int>() != get_type_index<float>(), "" ); |
14 | static_assert( |
15 | get_type_index<int(double, double)>() == |
16 | get_type_index<int(double, double)>(), |
17 | "" ); |
18 | static_assert( |
19 | get_type_index<int(double, double)>() != get_type_index<int(double)>(), |
20 | "" ); |
21 | static_assert( |
22 | get_type_index<int(double, double)>() == |
23 | get_type_index<int (*)(double, double)>(), |
24 | "" ); |
25 | static_assert( |
26 | get_type_index<std::function<int(double, double)>>() == |
27 | get_type_index<std::function<int(double, double)>>(), |
28 | "" ); |
29 | static_assert( |
30 | get_type_index<std::function<int(double, double)>>() != |
31 | get_type_index<std::function<int(double)>>(), |
32 | "" ); |
33 | |
34 | static_assert(get_type_index<int>() == get_type_index<int&>(), "" ); |
35 | static_assert(get_type_index<int>() == get_type_index<int&&>(), "" ); |
36 | static_assert(get_type_index<int>() == get_type_index<const int&>(), "" ); |
37 | static_assert(get_type_index<int>() == get_type_index<const int>(), "" ); |
38 | static_assert(get_type_index<const int>() == get_type_index<int&>(), "" ); |
39 | static_assert(get_type_index<int>() != get_type_index<int*>(), "" ); |
40 | static_assert(get_type_index<int*>() != get_type_index<int**>(), "" ); |
41 | static_assert( |
42 | get_type_index<int(double&, double)>() != |
43 | get_type_index<int(double, double)>(), |
44 | "" ); |
45 | |
46 | struct Dummy final {}; |
47 | struct Functor final { |
48 | int64_t operator()(uint32_t, Dummy&&, const Dummy&) const; |
49 | }; |
50 | static_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 | |
56 | namespace test_top_level_name { |
57 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
58 | static_assert( |
59 | string_view::npos != get_fully_qualified_type_name<Dummy>().find("Dummy" ), |
60 | "" ); |
61 | #endif |
62 | TEST(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 | |
68 | namespace test_nested_name { |
69 | struct Dummy final {}; |
70 | |
71 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
72 | static_assert( |
73 | string_view::npos != |
74 | get_fully_qualified_type_name<Dummy>().find("test_nested_name::Dummy" ), |
75 | "" ); |
76 | #endif |
77 | TEST(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 | |
84 | namespace test_type_template_parameter { |
85 | template <class T> |
86 | struct Outer final {}; |
87 | struct Inner final {}; |
88 | |
89 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
90 | static_assert( |
91 | string_view::npos != |
92 | get_fully_qualified_type_name<Outer<Inner>>().find( |
93 | "test_type_template_parameter::Outer" ), |
94 | "" ); |
95 | static_assert( |
96 | string_view::npos != |
97 | get_fully_qualified_type_name<Outer<Inner>>().find( |
98 | "test_type_template_parameter::Inner" ), |
99 | "" ); |
100 | #endif |
101 | TEST(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 | |
113 | namespace test_nontype_template_parameter { |
114 | template <size_t N> |
115 | struct Class final {}; |
116 | |
117 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
118 | static_assert( |
119 | string_view::npos != |
120 | get_fully_qualified_type_name<Class<38474355>>().find("38474355" ), |
121 | "" ); |
122 | #endif |
123 | TEST(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 | |
130 | namespace test_type_computations_are_resolved { |
131 | template <class T> |
132 | struct Type final { |
133 | using type = const T*; |
134 | }; |
135 | |
136 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
137 | static_assert( |
138 | string_view::npos != |
139 | get_fully_qualified_type_name<typename Type<int>::type>().find("int" ), |
140 | "" ); |
141 | static_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 |
147 | static_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 |
154 | TEST(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 | |
169 | struct Functor final { |
170 | std::string operator()(int64_t a, const Type<int>& b) const; |
171 | }; |
172 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
173 | static_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 |
179 | TEST(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 | |
187 | namespace test_function_arguments_and_returns { |
188 | class Dummy final {}; |
189 | |
190 | #if C10_TYPENAME_SUPPORTS_CONSTEXPR |
191 | static_assert( |
192 | string_view::npos != |
193 | get_fully_qualified_type_name<Dummy(int)>().find( |
194 | "test_function_arguments_and_returns::Dummy" ), |
195 | "" ); |
196 | static_assert( |
197 | string_view::npos != |
198 | get_fully_qualified_type_name<void(Dummy)>().find( |
199 | "test_function_arguments_and_returns::Dummy" ), |
200 | "" ); |
201 | #endif |
202 | TEST(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 | |