1 //
2 // Copyright 2012-2021 Antony Polukhin.
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 
10 #include <boost/lexical_cast.hpp>
11 
12 #include <boost/core/lightweight_test.hpp>
13 
14 namespace my_namespace1 {
15     class my_class{};
16 }
17 
18 
19 namespace my_namespace2 {
20     class my_class{};
21 }
22 
23 
names_matches_type_id()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 
default_construction()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 
copy_construction()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 
comparators_type_id()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 
hash_code_type_id()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>
test_with_modofiers()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 
type_id_storing_modifiers()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>
test_storing_nonstoring_modifiers_templ()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 
type_id_storing_modifiers_vs_nonstoring()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 
type_index_stream_operator_via_lexical_cast_testing()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 
type_index_stripping_cvr_test()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 
type_index_user_defined_class_test()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
~AA273     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 
comparators_type_id_runtime()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 
comparators_type_id_vs_type_info()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 
main()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 
401