type.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /************************************************************************************
  2. * *
  3. * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
  4. * *
  5. * This file is part of RTTR (Run Time Type Reflection) *
  6. * License: MIT License *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining *
  9. * a copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
  24. * SOFTWARE. *
  25. * *
  26. *************************************************************************************/
  27. #include "rttr/type.h"
  28. #include "rttr/constructor.h"
  29. #include "rttr/property.h"
  30. #include "rttr/destructor.h"
  31. #include "rttr/enumeration.h"
  32. #include "rttr/method.h"
  33. #include "rttr/detail/constructor/constructor_wrapper_base.h"
  34. #include "rttr/detail/destructor/destructor_wrapper_base.h"
  35. #include "rttr/detail/enumeration/enumeration_wrapper_base.h"
  36. #include "rttr/detail/method/method_wrapper_base.h"
  37. #include "rttr/detail/property/property_wrapper.h"
  38. #include "rttr/rttr_enable.h"
  39. #include "rttr/detail/parameter_info/parameter_infos_compare.h"
  40. #include "rttr/detail/filter/filter_item_funcs.h"
  41. #include "rttr/detail/type/type_register_p.h"
  42. #include <algorithm>
  43. #include <unordered_map>
  44. #include <vector>
  45. #include <memory>
  46. #include <set>
  47. #include <thread>
  48. #include <mutex>
  49. #include <cstring>
  50. #include <cctype>
  51. #include <utility>
  52. using namespace std;
  53. namespace rttr
  54. {
  55. /////////////////////////////////////////////////////////////////////////////////////////
  56. /////////////////////////////////////////////////////////////////////////////////////////
  57. /////////////////////////////////////////////////////////////////////////////////////////
  58. type::type() RTTR_NOEXCEPT
  59. : m_type_data(detail::get_invalid_type_data())
  60. {
  61. }
  62. /////////////////////////////////////////////////////////////////////////////////////////
  63. bool type::is_derived_from(const type& other) const RTTR_NOEXCEPT
  64. {
  65. auto& src_raw_type = m_type_data->raw_type_data;
  66. auto& tgt_raw_type = other.m_type_data->raw_type_data;
  67. if (src_raw_type == tgt_raw_type)
  68. return true;
  69. for (auto& t : src_raw_type->m_class_data.m_base_types)
  70. {
  71. if (t.m_type_data == tgt_raw_type)
  72. {
  73. return true;
  74. }
  75. }
  76. return false;
  77. }
  78. /////////////////////////////////////////////////////////////////////////////////////////
  79. bool type::is_base_of(const type& other) const RTTR_NOEXCEPT
  80. {
  81. auto& src_raw_type = m_type_data->raw_type_data;
  82. auto& tgt_raw_type = other.m_type_data->raw_type_data;
  83. if (src_raw_type == tgt_raw_type)
  84. return true;
  85. for (auto& t : src_raw_type->m_class_data.m_derived_types)
  86. {
  87. if (t.m_type_data == tgt_raw_type)
  88. {
  89. return true;
  90. }
  91. }
  92. return false;
  93. }
  94. /////////////////////////////////////////////////////////////////////////////////////////
  95. void* type::apply_offset(void* ptr, const type& source_type, const type& target_type) RTTR_NOEXCEPT
  96. {
  97. auto& src_raw_type = source_type.m_type_data->raw_type_data;
  98. auto& tgt_raw_type = target_type.m_type_data->raw_type_data;
  99. if (src_raw_type == tgt_raw_type || ptr == nullptr)
  100. return ptr;
  101. const detail::derived_info info = src_raw_type->m_class_data.m_derived_info_func(ptr);
  102. if (info.m_type.m_type_data->raw_type_data == tgt_raw_type)
  103. return info.m_ptr;
  104. auto& class_list = info.m_type.m_type_data->raw_type_data->m_class_data;
  105. int i = 0;
  106. for (auto& t : class_list.m_base_types)
  107. {
  108. if (t.m_type_data == tgt_raw_type)
  109. {
  110. return class_list.m_conversion_list[i](info.m_ptr);
  111. }
  112. ++i;
  113. }
  114. return nullptr;
  115. }
  116. /////////////////////////////////////////////////////////////////////////////////////////
  117. type type::get_derived_type(void* ptr, const type& source_type) RTTR_NOEXCEPT
  118. {
  119. if (ptr == nullptr)
  120. return type();
  121. auto& src_raw_type = source_type.m_type_data->raw_type_data;
  122. const detail::derived_info info = src_raw_type->m_class_data.m_derived_info_func(ptr);
  123. return info.m_type;
  124. }
  125. /////////////////////////////////////////////////////////////////////////////////////////
  126. array_range<type> type::get_base_classes() const RTTR_NOEXCEPT
  127. {
  128. return array_range<type>(m_type_data->m_class_data.m_base_types.data(),
  129. m_type_data->m_class_data.m_base_types.size());
  130. }
  131. /////////////////////////////////////////////////////////////////////////////////////////
  132. array_range<type> type::get_derived_classes() const RTTR_NOEXCEPT
  133. {
  134. return array_range<type>(m_type_data->m_class_data.m_derived_types.data(),
  135. m_type_data->m_class_data.m_derived_types.size());
  136. }
  137. /////////////////////////////////////////////////////////////////////////////////////////
  138. array_range<type> type::get_types() RTTR_NOEXCEPT
  139. {
  140. auto& type_list = detail::type_register_private::get_instance().get_type_storage();
  141. return array_range<type>(&type_list[1], type_list.size() - 1);
  142. }
  143. /////////////////////////////////////////////////////////////////////////////////////////
  144. array_range<type> type::get_template_arguments() const RTTR_NOEXCEPT
  145. {
  146. return array_range<type>(m_type_data->m_class_data.m_nested_types.data(),
  147. m_type_data->m_class_data.m_nested_types.size());
  148. }
  149. /////////////////////////////////////////////////////////////////////////////////////////
  150. variant type::get_metadata(const variant& key) const
  151. {
  152. return detail::type_register_private::get_metadata(*this, key);
  153. }
  154. /////////////////////////////////////////////////////////////////////////////////////////
  155. variant type::create(vector<argument> args) const
  156. {
  157. auto& ctors = m_type_data->m_class_data.m_ctors;
  158. for (const auto& ctor : ctors)
  159. {
  160. if (detail::compare_with_arg_list::compare(ctor.get_parameter_infos(), args))
  161. return ctor.invoke_variadic(std::move(args));
  162. }
  163. return variant();
  164. }
  165. /////////////////////////////////////////////////////////////////////////////////////////
  166. bool type::destroy(variant& obj) const RTTR_NOEXCEPT
  167. {
  168. return get_destructor().invoke(obj);
  169. }
  170. /////////////////////////////////////////////////////////////////////////////////////////
  171. property type::get_property(string_view name) const RTTR_NOEXCEPT
  172. {
  173. const auto raw_t = get_raw_type();
  174. const auto& vec = raw_t.m_type_data->m_class_data.m_properties;
  175. // properties are ordered from base to derived
  176. // use reverse iterator to find the most-derived propertie
  177. // when searching instance registry by name
  178. auto ret = std::find_if(vec.crbegin(), vec.crend(),
  179. [name](const property& item)
  180. {
  181. return (item.get_name() == name);
  182. });
  183. if (ret != vec.crend())
  184. return *ret;
  185. return detail::create_invalid_item<property>();
  186. }
  187. /////////////////////////////////////////////////////////////////////////////////////////
  188. variant type::get_property_value(string_view name, instance obj) const
  189. {
  190. return get_property(name).get_value(obj);
  191. }
  192. /////////////////////////////////////////////////////////////////////////////////////////
  193. variant type::get_property_value(string_view name)
  194. {
  195. const auto prop = get_global_property(name);
  196. return prop.get_value(instance());
  197. }
  198. /////////////////////////////////////////////////////////////////////////////////////////
  199. bool type::set_property_value(string_view name, instance obj, argument arg) const
  200. {
  201. const auto prop = get_property(name);
  202. return prop.set_value(obj, arg);
  203. }
  204. /////////////////////////////////////////////////////////////////////////////////////////
  205. bool type::set_property_value(string_view name, argument arg)
  206. {
  207. const auto prop = get_global_property(name);
  208. return prop.set_value(instance(), arg);
  209. }
  210. /////////////////////////////////////////////////////////////////////////////////////////
  211. array_range<property> type::get_properties() const RTTR_NOEXCEPT
  212. {
  213. auto& vec = get_raw_type().m_type_data->m_class_data.m_properties;
  214. if (!vec.empty())
  215. {
  216. return array_range<property>(vec.data(), vec.size(),
  217. detail::default_predicate<property>([](const property& prop)
  218. {
  219. return (prop.get_access_level() == access_levels::public_access);
  220. }) );
  221. }
  222. return array_range<property>();
  223. }
  224. /////////////////////////////////////////////////////////////////////////////////////////
  225. array_range<property> type::get_properties(filter_items filter) const RTTR_NOEXCEPT
  226. {
  227. const auto raw_t = get_raw_type();
  228. auto& vec = raw_t.m_type_data->m_class_data.m_properties;
  229. if (!vec.empty())
  230. return array_range<property>(vec.data(), vec.size(), detail::get_filter_predicate<property>(raw_t, filter));
  231. return array_range<property>();
  232. }
  233. /////////////////////////////////////////////////////////////////////////////////////////
  234. method type::get_method(string_view name) const RTTR_NOEXCEPT
  235. {
  236. const auto raw_t = get_raw_type();
  237. const auto& vec = raw_t.m_type_data->m_class_data.m_methods;
  238. // methods appear are ordered from base to derived
  239. // use reverse iterator to find the most-derived method
  240. // when searching instance registry by name
  241. auto ret = std::find_if(vec.crbegin(), vec.crend(),
  242. [name](const method& item)
  243. {
  244. return (item.get_name() == name);
  245. });
  246. if (ret != vec.crend())
  247. return *ret;
  248. return detail::create_invalid_item<method>();
  249. }
  250. /////////////////////////////////////////////////////////////////////////////////////////
  251. method type::get_method(string_view name, const std::vector<type>& type_list) const RTTR_NOEXCEPT
  252. {
  253. const auto raw_t = get_raw_type();
  254. const auto& methvec = raw_t.m_type_data->m_class_data.m_methods;
  255. for (auto mit = methvec.crbegin() ; mit != methvec.crend() ; ++mit)
  256. {
  257. const auto& meth = *mit ;
  258. if ( meth.get_name() == name &&
  259. detail::compare_with_type_list::compare(meth.get_parameter_infos(), type_list))
  260. {
  261. return meth;
  262. }
  263. }
  264. return detail::create_invalid_item<method>();
  265. }
  266. /////////////////////////////////////////////////////////////////////////////////////////
  267. array_range<method> type::get_methods() const RTTR_NOEXCEPT
  268. {
  269. const auto raw_t = get_raw_type();
  270. auto& vec = raw_t.m_type_data->m_class_data.m_methods;
  271. if (!vec.empty())
  272. {
  273. return array_range<method>(vec.data(), vec.size(),
  274. detail::default_predicate<method>([](const method& meth)
  275. {
  276. return (meth.get_access_level() == access_levels::public_access);
  277. }) );
  278. }
  279. return array_range<method>();
  280. }
  281. /////////////////////////////////////////////////////////////////////////////////////////
  282. array_range<method> type::get_methods(filter_items filter) const RTTR_NOEXCEPT
  283. {
  284. const auto raw_t = get_raw_type();
  285. auto& vec = raw_t.m_type_data->m_class_data.m_methods;
  286. if (!vec.empty())
  287. return array_range<method>(vec.data(), vec.size(), detail::get_filter_predicate<method>(raw_t, filter));
  288. return array_range<method>();
  289. }
  290. /////////////////////////////////////////////////////////////////////////////////////////
  291. property type::get_global_property(string_view name) RTTR_NOEXCEPT
  292. {
  293. auto& prop_list = detail::type_register_private::get_instance().get_global_property_storage();
  294. const auto ret = prop_list.find(name);
  295. if (ret != prop_list.end())
  296. return *ret;
  297. return detail::create_invalid_item<property>();
  298. }
  299. /////////////////////////////////////////////////////////////////////////////////////////
  300. method type::get_global_method(string_view name) RTTR_NOEXCEPT
  301. {
  302. auto& meth_list = detail::type_register_private::get_instance().get_global_method_storage();
  303. const auto ret = meth_list.find(name);
  304. if (ret != meth_list.end())
  305. return *ret;
  306. return detail::create_invalid_item<method>();
  307. }
  308. /////////////////////////////////////////////////////////////////////////////////////////
  309. method type::get_global_method(string_view name, const std::vector<type>& type_list) RTTR_NOEXCEPT
  310. {
  311. auto& meth_list = detail::type_register_private::get_instance().get_global_method_storage();
  312. auto itr = meth_list.find(name);
  313. while (itr != meth_list.end())
  314. {
  315. const auto& meth = *itr;
  316. if (meth.get_name() != name)
  317. break;
  318. if (detail::compare_with_type_list::compare(meth.get_parameter_infos(), type_list))
  319. return meth;
  320. ++itr;
  321. }
  322. return detail::create_invalid_item<method>();
  323. }
  324. /////////////////////////////////////////////////////////////////////////////////////////
  325. array_range<method> type::get_global_methods() RTTR_NOEXCEPT
  326. {
  327. auto& vec = detail::type_register_private::get_instance().get_global_methods();
  328. return array_range<method>(vec.data(), vec.size());
  329. }
  330. /////////////////////////////////////////////////////////////////////////////////////////
  331. array_range<property> type::get_global_properties() RTTR_NOEXCEPT
  332. {
  333. auto& vec = detail::type_register_private::get_instance().get_global_properties();
  334. return array_range<property>(vec.data(), vec.size());
  335. }
  336. /////////////////////////////////////////////////////////////////////////////////////////
  337. enumeration type::get_enumeration() const RTTR_NOEXCEPT
  338. {
  339. if (m_type_data->enum_wrapper)
  340. return detail::create_item<enumeration>(m_type_data->enum_wrapper);
  341. else
  342. return detail::create_invalid_item<enumeration>();
  343. }
  344. /////////////////////////////////////////////////////////////////////////////////////////
  345. variant type::invoke(string_view name, instance obj, std::vector<argument> args) const
  346. {
  347. const auto raw_t = get_raw_type();
  348. const auto& methvec = raw_t.m_type_data->m_class_data.m_methods;
  349. for (auto mit = methvec.crbegin() ; mit != methvec.crend() ; ++mit)
  350. {
  351. const auto& meth = *mit ;
  352. if ( meth.get_name() == name &&
  353. detail::compare_with_arg_list::compare(meth.get_parameter_infos(), args))
  354. {
  355. return meth.invoke_variadic(obj, args);
  356. }
  357. }
  358. return variant();
  359. }
  360. /////////////////////////////////////////////////////////////////////////////////////////
  361. variant type::invoke(string_view name, std::vector<argument> args)
  362. {
  363. auto& meth_list = detail::type_register_private::get_instance().get_global_method_storage();
  364. auto itr = meth_list.find(name);
  365. while (itr != meth_list.end())
  366. {
  367. const auto& meth = *itr;
  368. if (meth.get_name() != name)
  369. break;
  370. if (detail::compare_with_arg_list::compare(meth.get_parameter_infos(), args))
  371. {
  372. return meth.invoke_variadic(instance(), args);
  373. }
  374. ++itr;
  375. }
  376. return variant();
  377. }
  378. /////////////////////////////////////////////////////////////////////////////////////////
  379. type type::get_by_name(string_view name) RTTR_NOEXCEPT
  380. {
  381. auto& custom_name_to_id = detail::type_register_private::get_instance().get_custom_name_to_id();
  382. auto ret = custom_name_to_id.find(name);
  383. if (ret != custom_name_to_id.end())
  384. return (*ret);
  385. return detail::get_invalid_type();
  386. }
  387. /////////////////////////////////////////////////////////////////////////////////////////
  388. const detail::type_converter_base* type::get_type_converter(const type& target_type) const RTTR_NOEXCEPT
  389. {
  390. return detail::type_register_private::get_instance().get_converter(*this, target_type);
  391. }
  392. /////////////////////////////////////////////////////////////////////////////////////////
  393. const detail::type_comparator_base* type::get_equal_comparator() const RTTR_NOEXCEPT
  394. {
  395. return detail::type_register_private::get_instance().get_equal_comparator(*this);
  396. }
  397. /////////////////////////////////////////////////////////////////////////////////////////
  398. const detail::type_comparator_base* type::get_less_than_comparator() const RTTR_NOEXCEPT
  399. {
  400. return detail::type_register_private::get_instance().get_less_than_comparator(*this);
  401. }
  402. /////////////////////////////////////////////////////////////////////////////////////////
  403. constructor type::get_constructor(const std::vector<type>& args) const RTTR_NOEXCEPT
  404. {
  405. auto& ctors = m_type_data->m_class_data.m_ctors;
  406. for (const auto& ctor : ctors)
  407. {
  408. if (detail::compare_with_type_list::compare(ctor.get_parameter_infos(), args))
  409. return ctor;
  410. }
  411. return detail::create_invalid_item<constructor>();
  412. }
  413. /////////////////////////////////////////////////////////////////////////////////////////
  414. array_range<constructor> type::get_constructors() const RTTR_NOEXCEPT
  415. {
  416. auto& ctors = m_type_data->m_class_data.m_ctors;
  417. if (!ctors.empty())
  418. {
  419. return array_range<constructor>(ctors.data(), ctors.size(),
  420. detail::default_predicate<constructor>([](const constructor& ctor)
  421. {
  422. return (ctor.get_access_level() == access_levels::public_access);
  423. }) );
  424. }
  425. return array_range<constructor>();
  426. }
  427. /////////////////////////////////////////////////////////////////////////////////////////
  428. array_range<constructor> type::get_constructors(filter_items filter) const RTTR_NOEXCEPT
  429. {
  430. auto& ctors = m_type_data->m_class_data.m_ctors;
  431. if (!ctors.empty())
  432. return array_range<constructor>(ctors.data(), ctors.size(), detail::get_filter_predicate<constructor>(*this, filter));
  433. return array_range<constructor>();
  434. }
  435. /////////////////////////////////////////////////////////////////////////////////////////
  436. destructor type::get_destructor() const RTTR_NOEXCEPT
  437. {
  438. return get_raw_type().m_type_data->m_class_data.m_dtor;
  439. }
  440. /////////////////////////////////////////////////////////////////////////////////////////
  441. void type::create_wrapped_value(const argument& arg, variant& var) const
  442. {
  443. if (m_type_data->create_wrapper)
  444. m_type_data->create_wrapper(arg, var);
  445. }
  446. /////////////////////////////////////////////////////////////////////////////////////////
  447. void type::visit(visitor& vi, detail::type_of_visit visit_type) const RTTR_NOEXCEPT
  448. {
  449. if (m_type_data->visit_type)
  450. m_type_data->visit_type(visit_type, vi, *this);
  451. }
  452. /////////////////////////////////////////////////////////////////////////////////////////
  453. } // end namespace rttr