type_index_test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. //
  2. // Copyright 2012-2019 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. #include <boost/type_index.hpp>
  8. #include <boost/lexical_cast.hpp>
  9. #include <boost/core/lightweight_test.hpp>
  10. namespace my_namespace1 {
  11. class my_class{};
  12. }
  13. namespace my_namespace2 {
  14. class my_class{};
  15. }
  16. void names_matches_type_id()
  17. {
  18. using namespace boost::typeindex;
  19. BOOST_TEST_EQ(type_id<int>().pretty_name(), "int");
  20. BOOST_TEST_EQ(type_id<double>().pretty_name(), "double");
  21. BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name());
  22. BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name());
  23. BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name());
  24. BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name());
  25. }
  26. void default_construction()
  27. {
  28. using namespace boost::typeindex;
  29. type_index ti1, ti2;
  30. BOOST_TEST_EQ(ti1, ti2);
  31. BOOST_TEST_EQ(type_id<void>(), ti1);
  32. BOOST_TEST_EQ(type_id<void>().name(), ti1.name());
  33. BOOST_TEST_NE(type_id<int>(), ti1);
  34. }
  35. void copy_construction()
  36. {
  37. using namespace boost::typeindex;
  38. type_index ti1, ti2 = type_id<int>();
  39. BOOST_TEST_NE(ti1, ti2);
  40. ti1 = ti2;
  41. BOOST_TEST_EQ(ti2, ti1);
  42. const type_index ti3(ti1);
  43. BOOST_TEST_EQ(ti3, ti1);
  44. }
  45. void comparators_type_id()
  46. {
  47. using namespace boost::typeindex;
  48. type_index t_int = type_id<int>();
  49. type_index t_double = type_id<double>();
  50. BOOST_TEST_EQ(t_int, t_int);
  51. BOOST_TEST_LE(t_int, t_int);
  52. BOOST_TEST_GE(t_int, t_int);
  53. BOOST_TEST_NE(t_int, t_double);
  54. BOOST_TEST_LE(t_double, t_double);
  55. BOOST_TEST_GE(t_double, t_double);
  56. BOOST_TEST_NE(t_double, t_int);
  57. BOOST_TEST(t_double < t_int || t_int < t_double);
  58. BOOST_TEST(t_double > t_int || t_int > t_double);
  59. }
  60. void hash_code_type_id()
  61. {
  62. using namespace boost::typeindex;
  63. std::size_t t_int1 = type_id<int>().hash_code();
  64. std::size_t t_double1 = type_id<double>().hash_code();
  65. std::size_t t_int2 = type_id<int>().hash_code();
  66. std::size_t t_double2 = type_id<double>().hash_code();
  67. BOOST_TEST_EQ(t_int1, t_int2);
  68. BOOST_TEST_NE(t_int1, t_double2);
  69. BOOST_TEST_LE(t_double1, t_double2);
  70. }
  71. template <class T1, class T2>
  72. static void test_with_modofiers() {
  73. using namespace boost::typeindex;
  74. type_index t1 = type_id_with_cvr<T1>();
  75. type_index t2 = type_id_with_cvr<T2>();
  76. BOOST_TEST_NE(t2, t1);
  77. BOOST_TEST(t2 != t1.type_info());
  78. BOOST_TEST(t2.type_info() != t1);
  79. BOOST_TEST(t1 < t2 || t2 < t1);
  80. BOOST_TEST(t1 > t2 || t2 > t1);
  81. BOOST_TEST(t1.type_info() < t2 || t2.type_info() < t1);
  82. BOOST_TEST(t1.type_info() > t2 || t2.type_info() > t1);
  83. BOOST_TEST(t1 < t2.type_info() || t2 < t1.type_info());
  84. BOOST_TEST(t1 > t2.type_info() || t2 > t1.type_info());
  85. // Chaecking that comparison operators overloads compile
  86. BOOST_TEST(t1 <= t2 || t2 <= t1);
  87. BOOST_TEST(t1 >= t2 || t2 >= t1);
  88. BOOST_TEST(t1.type_info() <= t2 || t2.type_info() <= t1);
  89. BOOST_TEST(t1.type_info() >= t2 || t2.type_info() >= t1);
  90. BOOST_TEST(t1 <= t2.type_info() || t2 <= t1.type_info());
  91. BOOST_TEST(t1 >= t2.type_info() || t2 >= t1.type_info());
  92. BOOST_TEST_EQ(t1, type_id_with_cvr<T1>());
  93. BOOST_TEST_EQ(t2, type_id_with_cvr<T2>());
  94. BOOST_TEST(t1 == type_id_with_cvr<T1>().type_info());
  95. BOOST_TEST(t2 == type_id_with_cvr<T2>().type_info());
  96. BOOST_TEST(t1.type_info() == type_id_with_cvr<T1>());
  97. BOOST_TEST(t2.type_info() == type_id_with_cvr<T2>());
  98. BOOST_TEST_EQ(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
  99. BOOST_TEST_EQ(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
  100. BOOST_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
  101. BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
  102. }
  103. void type_id_storing_modifiers()
  104. {
  105. test_with_modofiers<int, const int>();
  106. test_with_modofiers<int, const int&>();
  107. test_with_modofiers<int, int&>();
  108. test_with_modofiers<int, volatile int>();
  109. test_with_modofiers<int, volatile int&>();
  110. test_with_modofiers<int, const volatile int>();
  111. test_with_modofiers<int, const volatile int&>();
  112. test_with_modofiers<const int, int>();
  113. test_with_modofiers<const int, const int&>();
  114. test_with_modofiers<const int, int&>();
  115. test_with_modofiers<const int, volatile int>();
  116. test_with_modofiers<const int, volatile int&>();
  117. test_with_modofiers<const int, const volatile int>();
  118. test_with_modofiers<const int, const volatile int&>();
  119. test_with_modofiers<const int&, int>();
  120. test_with_modofiers<const int&, const int>();
  121. test_with_modofiers<const int&, int&>();
  122. test_with_modofiers<const int&, volatile int>();
  123. test_with_modofiers<const int&, volatile int&>();
  124. test_with_modofiers<const int&, const volatile int>();
  125. test_with_modofiers<const int&, const volatile int&>();
  126. test_with_modofiers<int&, const int>();
  127. test_with_modofiers<int&, const int&>();
  128. test_with_modofiers<int&, int>();
  129. test_with_modofiers<int&, volatile int>();
  130. test_with_modofiers<int&, volatile int&>();
  131. test_with_modofiers<int&, const volatile int>();
  132. test_with_modofiers<int&, const volatile int&>();
  133. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  134. test_with_modofiers<int&&, const int>();
  135. test_with_modofiers<int&&, const int&>();
  136. test_with_modofiers<int&&, const int&&>();
  137. test_with_modofiers<int&&, int>();
  138. test_with_modofiers<int&&, volatile int>();
  139. test_with_modofiers<int&&, volatile int&>();
  140. test_with_modofiers<int&&, volatile int&&>();
  141. test_with_modofiers<int&&, const volatile int>();
  142. test_with_modofiers<int&&, const volatile int&>();
  143. test_with_modofiers<int&&, const volatile int&&>();
  144. #endif
  145. }
  146. template <class T>
  147. static void test_storing_nonstoring_modifiers_templ() {
  148. using namespace boost::typeindex;
  149. type_index t1 = type_id_with_cvr<T>();
  150. type_index t2 = type_id<T>();
  151. BOOST_TEST_EQ(t2, t1);
  152. BOOST_TEST_EQ(t1, t2);
  153. BOOST_TEST(t1 <= t2);
  154. BOOST_TEST(t1 >= t2);
  155. BOOST_TEST(t2 <= t1);
  156. BOOST_TEST(t2 >= t1);
  157. BOOST_TEST_EQ(t2.pretty_name(), t1.pretty_name());
  158. }
  159. void type_id_storing_modifiers_vs_nonstoring()
  160. {
  161. test_storing_nonstoring_modifiers_templ<int>();
  162. test_storing_nonstoring_modifiers_templ<my_namespace1::my_class>();
  163. test_storing_nonstoring_modifiers_templ<my_namespace2::my_class>();
  164. boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>();
  165. boost::typeindex::type_index t2 = boost::typeindex::type_id<int>();
  166. BOOST_TEST_NE(t2, t1);
  167. BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
  168. }
  169. void type_index_stream_operator_via_lexical_cast_testing()
  170. {
  171. using namespace boost::typeindex;
  172. std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
  173. BOOST_TEST_EQ(s_int2, "int");
  174. std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
  175. BOOST_TEST_EQ(s_double2, "double");
  176. }
  177. void type_index_stripping_cvr_test()
  178. {
  179. using namespace boost::typeindex;
  180. BOOST_TEST_EQ(type_id<int>(), type_id<const int>());
  181. BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int>());
  182. BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int&>());
  183. BOOST_TEST_EQ(type_id<int>(), type_id<int&>());
  184. BOOST_TEST_EQ(type_id<int>(), type_id<volatile int>());
  185. BOOST_TEST_EQ(type_id<int>(), type_id<volatile int&>());
  186. BOOST_TEST_EQ(type_id<double>(), type_id<const double>());
  187. BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double>());
  188. BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double&>());
  189. BOOST_TEST_EQ(type_id<double>(), type_id<double&>());
  190. BOOST_TEST_EQ(type_id<double>(), type_id<volatile double>());
  191. BOOST_TEST_EQ(type_id<double>(), type_id<volatile double&>());
  192. }
  193. void type_index_user_defined_class_test()
  194. {
  195. using namespace boost::typeindex;
  196. BOOST_TEST_EQ(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
  197. BOOST_TEST_EQ(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
  198. #ifndef BOOST_NO_RTTI
  199. BOOST_TEST(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
  200. BOOST_TEST(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
  201. BOOST_TEST(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
  202. BOOST_TEST(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
  203. #endif
  204. BOOST_TEST_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
  205. BOOST_TEST_NE(
  206. type_id<my_namespace1::my_class>().pretty_name().find("my_namespace1::my_class"),
  207. std::string::npos);
  208. }
  209. struct A {
  210. public:
  211. BOOST_TYPE_INDEX_REGISTER_CLASS
  212. virtual ~A(){}
  213. };
  214. struct B: public A {
  215. BOOST_TYPE_INDEX_REGISTER_CLASS
  216. };
  217. struct C: public B {
  218. BOOST_TYPE_INDEX_REGISTER_CLASS
  219. };
  220. void comparators_type_id_runtime()
  221. {
  222. C c1;
  223. B b1;
  224. A* pc1 = &c1;
  225. A& rc1 = c1;
  226. A* pb1 = &b1;
  227. A& rb1 = b1;
  228. #ifndef BOOST_NO_RTTI
  229. BOOST_TEST(typeid(rc1) == typeid(*pc1));
  230. BOOST_TEST(typeid(rb1) == typeid(*pb1));
  231. BOOST_TEST(typeid(rc1) != typeid(*pb1));
  232. BOOST_TEST(typeid(rb1) != typeid(*pc1));
  233. BOOST_TEST(typeid(&rc1) == typeid(pb1));
  234. BOOST_TEST(typeid(&rb1) == typeid(pc1));
  235. #else
  236. BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
  237. #endif
  238. BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1));
  239. BOOST_TEST_EQ(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1));
  240. BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1));
  241. BOOST_TEST_EQ(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1));
  242. BOOST_TEST_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1));
  243. BOOST_TEST_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1));
  244. #ifndef BOOST_NO_RTTI
  245. BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1));
  246. BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1));
  247. BOOST_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
  248. BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
  249. BOOST_TEST(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1));
  250. BOOST_TEST(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1));
  251. BOOST_TEST(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1));
  252. BOOST_TEST(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1));
  253. #endif
  254. }
  255. #ifndef BOOST_NO_RTTI
  256. void comparators_type_id_vs_type_info()
  257. {
  258. using namespace boost::typeindex;
  259. type_index t_int = type_id<int>();
  260. BOOST_TEST(t_int == typeid(int));
  261. BOOST_TEST(typeid(int) == t_int);
  262. BOOST_TEST(t_int <= typeid(int));
  263. BOOST_TEST(typeid(int) <= t_int);
  264. BOOST_TEST(t_int >= typeid(int));
  265. BOOST_TEST(typeid(int) >= t_int);
  266. type_index t_double = type_id<double>();
  267. BOOST_TEST(t_double == typeid(double));
  268. BOOST_TEST(typeid(double) == t_double);
  269. BOOST_TEST(t_double <= typeid(double));
  270. BOOST_TEST(typeid(double) <= t_double);
  271. BOOST_TEST(t_double >= typeid(double));
  272. BOOST_TEST(typeid(double) >= t_double);
  273. if (t_double < t_int) {
  274. BOOST_TEST(t_double < typeid(int));
  275. BOOST_TEST(typeid(double) < t_int);
  276. BOOST_TEST(typeid(int) > t_double);
  277. BOOST_TEST(t_int > typeid(double));
  278. BOOST_TEST(t_double <= typeid(int));
  279. BOOST_TEST(typeid(double) <= t_int);
  280. BOOST_TEST(typeid(int) >= t_double);
  281. BOOST_TEST(t_int >= typeid(double));
  282. } else {
  283. BOOST_TEST(t_double > typeid(int));
  284. BOOST_TEST(typeid(double) > t_int);
  285. BOOST_TEST(typeid(int) < t_double);
  286. BOOST_TEST(t_int < typeid(double));
  287. BOOST_TEST(t_double >= typeid(int));
  288. BOOST_TEST(typeid(double) >= t_int);
  289. BOOST_TEST(typeid(int) <= t_double);
  290. BOOST_TEST(t_int <= typeid(double));
  291. }
  292. }
  293. #endif // BOOST_NO_RTTI
  294. int main() {
  295. names_matches_type_id();
  296. default_construction();
  297. copy_construction();
  298. comparators_type_id();
  299. hash_code_type_id();
  300. type_id_storing_modifiers();
  301. type_id_storing_modifiers_vs_nonstoring();
  302. type_index_stream_operator_via_lexical_cast_testing();
  303. type_index_stripping_cvr_test();
  304. type_index_user_defined_class_test();
  305. comparators_type_id_runtime();
  306. #ifndef BOOST_NO_RTTI
  307. comparators_type_id_vs_type_info();
  308. #endif
  309. return boost::report_errors();
  310. }