]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // |
92f5a8d4 | 2 | // Copyright 2012-2019 Antony Polukhin. |
7c673cae FG |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. (See | |
5 | // accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #include <boost/type_index.hpp> | |
9 | ||
7c673cae FG |
10 | #include <boost/lexical_cast.hpp> |
11 | ||
12 | #include <boost/core/lightweight_test.hpp> | |
7c673cae FG |
13 | |
14 | namespace my_namespace1 { | |
15 | class my_class{}; | |
16 | } | |
17 | ||
18 | ||
19 | namespace my_namespace2 { | |
20 | class my_class{}; | |
21 | } | |
22 | ||
23 | ||
24 | void names_matches_type_id() | |
25 | { | |
26 | using namespace boost::typeindex; | |
27 | BOOST_TEST_EQ(type_id<int>().pretty_name(), "int"); | |
28 | BOOST_TEST_EQ(type_id<double>().pretty_name(), "double"); | |
29 | ||
30 | BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name()); | |
31 | BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name()); | |
32 | BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name()); | |
33 | BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name()); | |
34 | } | |
35 | ||
36 | void default_construction() | |
37 | { | |
38 | using namespace boost::typeindex; | |
39 | type_index ti1, ti2; | |
40 | BOOST_TEST_EQ(ti1, ti2); | |
41 | BOOST_TEST_EQ(type_id<void>(), ti1); | |
42 | ||
43 | BOOST_TEST_EQ(type_id<void>().name(), ti1.name()); | |
44 | BOOST_TEST_NE(type_id<int>(), ti1); | |
45 | } | |
46 | ||
47 | ||
48 | void copy_construction() | |
49 | { | |
50 | using namespace boost::typeindex; | |
51 | type_index ti1, ti2 = type_id<int>(); | |
52 | BOOST_TEST_NE(ti1, ti2); | |
53 | ti1 = ti2; | |
54 | BOOST_TEST_EQ(ti2, ti1); | |
55 | ||
56 | const type_index ti3(ti1); | |
57 | BOOST_TEST_EQ(ti3, ti1); | |
58 | } | |
59 | ||
60 | void comparators_type_id() | |
61 | { | |
62 | using namespace boost::typeindex; | |
63 | type_index t_int = type_id<int>(); | |
64 | type_index t_double = type_id<double>(); | |
65 | ||
66 | BOOST_TEST_EQ(t_int, t_int); | |
67 | BOOST_TEST_LE(t_int, t_int); | |
68 | BOOST_TEST_GE(t_int, t_int); | |
69 | BOOST_TEST_NE(t_int, t_double); | |
70 | ||
71 | BOOST_TEST_LE(t_double, t_double); | |
72 | BOOST_TEST_GE(t_double, t_double); | |
73 | BOOST_TEST_NE(t_double, t_int); | |
74 | ||
75 | BOOST_TEST(t_double < t_int || t_int < t_double); | |
76 | BOOST_TEST(t_double > t_int || t_int > t_double); | |
77 | } | |
78 | ||
79 | void hash_code_type_id() | |
80 | { | |
81 | using namespace boost::typeindex; | |
82 | std::size_t t_int1 = type_id<int>().hash_code(); | |
83 | std::size_t t_double1 = type_id<double>().hash_code(); | |
84 | ||
85 | std::size_t t_int2 = type_id<int>().hash_code(); | |
86 | std::size_t t_double2 = type_id<double>().hash_code(); | |
87 | ||
88 | BOOST_TEST_EQ(t_int1, t_int2); | |
89 | BOOST_TEST_NE(t_int1, t_double2); | |
90 | BOOST_TEST_LE(t_double1, t_double2); | |
91 | } | |
92 | ||
93 | ||
94 | ||
95 | template <class T1, class T2> | |
96 | static void test_with_modofiers() { | |
97 | using namespace boost::typeindex; | |
98 | ||
99 | type_index t1 = type_id_with_cvr<T1>(); | |
100 | type_index t2 = type_id_with_cvr<T2>(); | |
101 | ||
102 | BOOST_TEST_NE(t2, t1); | |
103 | BOOST_TEST(t2 != t1.type_info()); | |
104 | BOOST_TEST(t2.type_info() != t1); | |
105 | ||
106 | BOOST_TEST(t1 < t2 || t2 < t1); | |
107 | BOOST_TEST(t1 > t2 || t2 > t1); | |
108 | BOOST_TEST(t1.type_info() < t2 || t2.type_info() < t1); | |
109 | BOOST_TEST(t1.type_info() > t2 || t2.type_info() > t1); | |
110 | BOOST_TEST(t1 < t2.type_info() || t2 < t1.type_info()); | |
111 | BOOST_TEST(t1 > t2.type_info() || t2 > t1.type_info()); | |
112 | ||
113 | // Chaecking that comparison operators overloads compile | |
114 | BOOST_TEST(t1 <= t2 || t2 <= t1); | |
115 | BOOST_TEST(t1 >= t2 || t2 >= t1); | |
116 | BOOST_TEST(t1.type_info() <= t2 || t2.type_info() <= t1); | |
117 | BOOST_TEST(t1.type_info() >= t2 || t2.type_info() >= t1); | |
118 | BOOST_TEST(t1 <= t2.type_info() || t2 <= t1.type_info()); | |
119 | BOOST_TEST(t1 >= t2.type_info() || t2 >= t1.type_info()); | |
120 | ||
121 | BOOST_TEST_EQ(t1, type_id_with_cvr<T1>()); | |
122 | BOOST_TEST_EQ(t2, type_id_with_cvr<T2>()); | |
123 | BOOST_TEST(t1 == type_id_with_cvr<T1>().type_info()); | |
124 | BOOST_TEST(t2 == type_id_with_cvr<T2>().type_info()); | |
125 | BOOST_TEST(t1.type_info() == type_id_with_cvr<T1>()); | |
126 | BOOST_TEST(t2.type_info() == type_id_with_cvr<T2>()); | |
127 | ||
128 | BOOST_TEST_EQ(t1.hash_code(), type_id_with_cvr<T1>().hash_code()); | |
129 | BOOST_TEST_EQ(t2.hash_code(), type_id_with_cvr<T2>().hash_code()); | |
130 | ||
131 | BOOST_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code()); | |
132 | BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code()); | |
133 | } | |
134 | ||
135 | void type_id_storing_modifiers() | |
136 | { | |
137 | test_with_modofiers<int, const int>(); | |
138 | test_with_modofiers<int, const int&>(); | |
139 | test_with_modofiers<int, int&>(); | |
140 | test_with_modofiers<int, volatile int>(); | |
141 | test_with_modofiers<int, volatile int&>(); | |
142 | test_with_modofiers<int, const volatile int>(); | |
143 | test_with_modofiers<int, const volatile int&>(); | |
144 | ||
145 | test_with_modofiers<const int, int>(); | |
146 | test_with_modofiers<const int, const int&>(); | |
147 | test_with_modofiers<const int, int&>(); | |
148 | test_with_modofiers<const int, volatile int>(); | |
149 | test_with_modofiers<const int, volatile int&>(); | |
150 | test_with_modofiers<const int, const volatile int>(); | |
151 | test_with_modofiers<const int, const volatile int&>(); | |
152 | ||
153 | test_with_modofiers<const int&, int>(); | |
154 | test_with_modofiers<const int&, const int>(); | |
155 | test_with_modofiers<const int&, int&>(); | |
156 | test_with_modofiers<const int&, volatile int>(); | |
157 | test_with_modofiers<const int&, volatile int&>(); | |
158 | test_with_modofiers<const int&, const volatile int>(); | |
159 | test_with_modofiers<const int&, const volatile int&>(); | |
160 | ||
161 | test_with_modofiers<int&, const int>(); | |
162 | test_with_modofiers<int&, const int&>(); | |
163 | test_with_modofiers<int&, int>(); | |
164 | test_with_modofiers<int&, volatile int>(); | |
165 | test_with_modofiers<int&, volatile int&>(); | |
166 | test_with_modofiers<int&, const volatile int>(); | |
167 | test_with_modofiers<int&, const volatile int&>(); | |
168 | ||
169 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
170 | test_with_modofiers<int&&, const int>(); | |
171 | test_with_modofiers<int&&, const int&>(); | |
172 | test_with_modofiers<int&&, const int&&>(); | |
173 | test_with_modofiers<int&&, int>(); | |
174 | test_with_modofiers<int&&, volatile int>(); | |
175 | test_with_modofiers<int&&, volatile int&>(); | |
176 | test_with_modofiers<int&&, volatile int&&>(); | |
177 | test_with_modofiers<int&&, const volatile int>(); | |
178 | test_with_modofiers<int&&, const volatile int&>(); | |
179 | test_with_modofiers<int&&, const volatile int&&>(); | |
180 | #endif | |
181 | } | |
182 | ||
183 | template <class T> | |
184 | static void test_storing_nonstoring_modifiers_templ() { | |
185 | using namespace boost::typeindex; | |
186 | ||
187 | type_index t1 = type_id_with_cvr<T>(); | |
188 | type_index t2 = type_id<T>(); | |
189 | ||
190 | BOOST_TEST_EQ(t2, t1); | |
191 | BOOST_TEST_EQ(t1, t2); | |
192 | BOOST_TEST(t1 <= t2); | |
193 | BOOST_TEST(t1 >= t2); | |
194 | BOOST_TEST(t2 <= t1); | |
195 | BOOST_TEST(t2 >= t1); | |
196 | ||
197 | BOOST_TEST_EQ(t2.pretty_name(), t1.pretty_name()); | |
198 | } | |
199 | ||
200 | void type_id_storing_modifiers_vs_nonstoring() | |
201 | { | |
202 | test_storing_nonstoring_modifiers_templ<int>(); | |
203 | test_storing_nonstoring_modifiers_templ<my_namespace1::my_class>(); | |
204 | test_storing_nonstoring_modifiers_templ<my_namespace2::my_class>(); | |
205 | ||
206 | boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>(); | |
207 | boost::typeindex::type_index t2 = boost::typeindex::type_id<int>(); | |
208 | BOOST_TEST_NE(t2, t1); | |
209 | BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const"); | |
210 | } | |
211 | ||
212 | void type_index_stream_operator_via_lexical_cast_testing() | |
213 | { | |
214 | using namespace boost::typeindex; | |
215 | ||
216 | std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>()); | |
217 | BOOST_TEST_EQ(s_int2, "int"); | |
218 | ||
219 | std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>()); | |
220 | BOOST_TEST_EQ(s_double2, "double"); | |
221 | } | |
222 | ||
223 | void type_index_stripping_cvr_test() | |
224 | { | |
225 | using namespace boost::typeindex; | |
226 | ||
227 | BOOST_TEST_EQ(type_id<int>(), type_id<const int>()); | |
228 | BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int>()); | |
229 | BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int&>()); | |
230 | ||
231 | BOOST_TEST_EQ(type_id<int>(), type_id<int&>()); | |
232 | BOOST_TEST_EQ(type_id<int>(), type_id<volatile int>()); | |
233 | BOOST_TEST_EQ(type_id<int>(), type_id<volatile int&>()); | |
234 | ||
235 | ||
236 | BOOST_TEST_EQ(type_id<double>(), type_id<const double>()); | |
237 | BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double>()); | |
238 | BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double&>()); | |
239 | ||
240 | BOOST_TEST_EQ(type_id<double>(), type_id<double&>()); | |
241 | BOOST_TEST_EQ(type_id<double>(), type_id<volatile double>()); | |
242 | BOOST_TEST_EQ(type_id<double>(), type_id<volatile double&>()); | |
243 | } | |
244 | ||
245 | ||
246 | void type_index_user_defined_class_test() | |
247 | { | |
248 | using namespace boost::typeindex; | |
249 | ||
250 | BOOST_TEST_EQ(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>()); | |
251 | BOOST_TEST_EQ(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>()); | |
252 | ||
253 | #ifndef BOOST_NO_RTTI | |
254 | BOOST_TEST(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class)); | |
255 | BOOST_TEST(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class)); | |
256 | BOOST_TEST(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>()); | |
257 | BOOST_TEST(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>()); | |
258 | #endif | |
259 | ||
260 | BOOST_TEST_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>()); | |
261 | BOOST_TEST_NE( | |
262 | type_id<my_namespace1::my_class>().pretty_name().find("my_namespace1::my_class"), | |
263 | std::string::npos); | |
264 | } | |
265 | ||
266 | ||
267 | ||
268 | ||
269 | ||
270 | struct A { | |
271 | public: | |
272 | BOOST_TYPE_INDEX_REGISTER_CLASS | |
273 | virtual ~A(){} | |
274 | }; | |
275 | ||
276 | struct B: public A { | |
277 | BOOST_TYPE_INDEX_REGISTER_CLASS | |
278 | }; | |
279 | ||
280 | struct C: public B { | |
281 | BOOST_TYPE_INDEX_REGISTER_CLASS | |
282 | }; | |
283 | ||
284 | void comparators_type_id_runtime() | |
285 | { | |
286 | C c1; | |
287 | B b1; | |
288 | A* pc1 = &c1; | |
289 | A& rc1 = c1; | |
290 | A* pb1 = &b1; | |
291 | A& rb1 = b1; | |
292 | ||
293 | #ifndef BOOST_NO_RTTI | |
294 | BOOST_TEST(typeid(rc1) == typeid(*pc1)); | |
295 | BOOST_TEST(typeid(rb1) == typeid(*pb1)); | |
296 | ||
297 | BOOST_TEST(typeid(rc1) != typeid(*pb1)); | |
298 | BOOST_TEST(typeid(rb1) != typeid(*pc1)); | |
299 | ||
300 | BOOST_TEST(typeid(&rc1) == typeid(pb1)); | |
301 | BOOST_TEST(typeid(&rb1) == typeid(pc1)); | |
302 | #else | |
303 | BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name()); | |
304 | #endif | |
305 | ||
306 | BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1)); | |
307 | BOOST_TEST_EQ(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1)); | |
308 | BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1)); | |
309 | BOOST_TEST_EQ(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1)); | |
310 | ||
311 | BOOST_TEST_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1)); | |
312 | BOOST_TEST_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1)); | |
313 | ||
314 | #ifndef BOOST_NO_RTTI | |
315 | BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1)); | |
316 | BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1)); | |
317 | ||
318 | BOOST_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1)); | |
319 | BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1)); | |
320 | ||
321 | BOOST_TEST(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1)); | |
322 | BOOST_TEST(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1)); | |
323 | BOOST_TEST(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1)); | |
324 | BOOST_TEST(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1)); | |
325 | #endif | |
326 | } | |
327 | ||
328 | ||
329 | #ifndef BOOST_NO_RTTI | |
330 | ||
331 | void comparators_type_id_vs_type_info() | |
332 | { | |
333 | using namespace boost::typeindex; | |
334 | type_index t_int = type_id<int>(); | |
335 | ||
336 | BOOST_TEST(t_int == typeid(int)); | |
337 | BOOST_TEST(typeid(int) == t_int); | |
338 | BOOST_TEST(t_int <= typeid(int)); | |
339 | BOOST_TEST(typeid(int) <= t_int); | |
340 | BOOST_TEST(t_int >= typeid(int)); | |
341 | BOOST_TEST(typeid(int) >= t_int); | |
342 | ||
343 | type_index t_double = type_id<double>(); | |
344 | ||
345 | BOOST_TEST(t_double == typeid(double)); | |
346 | BOOST_TEST(typeid(double) == t_double); | |
347 | BOOST_TEST(t_double <= typeid(double)); | |
348 | BOOST_TEST(typeid(double) <= t_double); | |
349 | BOOST_TEST(t_double >= typeid(double)); | |
350 | BOOST_TEST(typeid(double) >= t_double); | |
351 | ||
352 | if (t_double < t_int) { | |
353 | BOOST_TEST(t_double < typeid(int)); | |
354 | BOOST_TEST(typeid(double) < t_int); | |
355 | BOOST_TEST(typeid(int) > t_double); | |
356 | BOOST_TEST(t_int > typeid(double)); | |
357 | ||
358 | ||
359 | BOOST_TEST(t_double <= typeid(int)); | |
360 | BOOST_TEST(typeid(double) <= t_int); | |
361 | BOOST_TEST(typeid(int) >= t_double); | |
362 | BOOST_TEST(t_int >= typeid(double)); | |
363 | } else { | |
364 | BOOST_TEST(t_double > typeid(int)); | |
365 | BOOST_TEST(typeid(double) > t_int); | |
366 | BOOST_TEST(typeid(int) < t_double); | |
367 | BOOST_TEST(t_int < typeid(double)); | |
368 | ||
369 | ||
370 | BOOST_TEST(t_double >= typeid(int)); | |
371 | BOOST_TEST(typeid(double) >= t_int); | |
372 | BOOST_TEST(typeid(int) <= t_double); | |
373 | BOOST_TEST(t_int <= typeid(double)); | |
374 | } | |
375 | ||
376 | } | |
377 | ||
378 | #endif // BOOST_NO_RTTI | |
379 | ||
380 | int main() { | |
381 | names_matches_type_id(); | |
382 | default_construction(); | |
383 | copy_construction(); | |
384 | comparators_type_id(); | |
385 | hash_code_type_id(); | |
386 | ||
387 | type_id_storing_modifiers(); | |
388 | type_id_storing_modifiers_vs_nonstoring(); | |
389 | type_index_stream_operator_via_lexical_cast_testing(); | |
390 | type_index_stripping_cvr_test(); | |
391 | type_index_user_defined_class_test(); | |
392 | ||
393 | comparators_type_id_runtime(); | |
394 | #ifndef BOOST_NO_RTTI | |
395 | comparators_type_id_vs_type_info(); | |
396 | #endif | |
397 | ||
398 | return boost::report_errors(); | |
399 | } | |
400 |