bind_impl.h 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  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. #ifndef RTTR_BIND_IMPL_H_
  28. #define RTTR_BIND_IMPL_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/argument_extractor.h"
  31. #include "rttr/detail/constructor/constructor_wrapper.h"
  32. #include "rttr/detail/destructor/destructor_wrapper.h"
  33. #include "rttr/detail/enumeration/enumeration_wrapper.h"
  34. #include "rttr/detail/enumeration/enum_data.h"
  35. #include "rttr/detail/metadata/metadata.h"
  36. #include "rttr/detail/method/method_wrapper.h"
  37. #include "rttr/detail/parameter_info/parameter_infos.h"
  38. #include "rttr/detail/property/property_wrapper.h"
  39. #include "rttr/detail/type/accessor_type.h"
  40. #include "rttr/detail/misc/misc_type_traits.h"
  41. #include "rttr/detail/misc/utility.h"
  42. #include "rttr/detail/type/type_register.h"
  43. #include "rttr/detail/default_arguments/default_arguments.h"
  44. #include "rttr/detail/registration/register_base_class_from_accessor.h"
  45. #include "rttr/policy.h"
  46. #include "rttr/type.h"
  47. #include "rttr/detail/registration/registration_manager.h"
  48. #include "rttr/detail/visitor/visitor_registration.h"
  49. #include <functional>
  50. #include <string>
  51. #include <vector>
  52. namespace rttr
  53. {
  54. namespace detail
  55. {
  56. /////////////////////////////////////////////////////////////////////////////////////////
  57. template<typename... Args>
  58. static RTTR_INLINE auto get_metadata(Args&&... arg) -> decltype(forward_to_array<metadata>(std::forward<Args>(arg)...))
  59. {
  60. return forward_to_array<metadata>(std::forward<Args>(arg)...);
  61. }
  62. /////////////////////////////////////////////////////////////////////////////////////////
  63. template<typename Enum_Type, typename... Args>
  64. static RTTR_INLINE auto get_enum_values(Args&&... arg) -> decltype(forward_to_array<enum_data<Enum_Type>>(std::forward<Args>(arg)...))
  65. {
  66. return forward_to_array<enum_data<Enum_Type>>(std::forward<Args>(arg)...);
  67. }
  68. /////////////////////////////////////////////////////////////////////////////////////////
  69. template<typename T>
  70. using map_access_level_to_enum = conditional_t< std::is_same<T, detail::public_access>::value,
  71. std::integral_constant<access_levels, access_levels::public_access>,
  72. conditional_t< std::is_same<T, detail::protected_access>::value,
  73. std::integral_constant<access_levels, access_levels::protected_access>,
  74. std::integral_constant<access_levels, access_levels::private_access>
  75. >
  76. >;
  77. /////////////////////////////////////////////////////////////////////////////////////////
  78. } // end namespace detail
  79. /////////////////////////////////////////////////////////////////////////////////////////
  80. template<typename Class_Type, typename acc_level, typename Visitor_List, typename...Ctor_Args>
  81. class registration::bind<detail::ctor, Class_Type, acc_level, Visitor_List, Ctor_Args...> : public registration::class_<Class_Type>
  82. {
  83. private:
  84. // this 'as_std_shared_ptr' policy has been selected, because:
  85. // * it has automatic memory management; should not leak anything
  86. // * we can copy the object inside the variant, without invoking the copy constructor (could be disabled by user)
  87. // REMARK: For the default constructor registration will always be code instantiated, when copying is disabled, we get a compile error
  88. using default_create_policy = detail::as_std_shared_ptr;
  89. // this additional wrapper function is needed, because of not triggered static_assert in func: 'operator()(Args&&... args)'
  90. // when we create the object directly inside the operator function, seems to be a bug in MSVC
  91. template<typename Policy, std::size_t Metadata_Count, typename...TArgs, typename...Param_Args>
  92. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base>
  93. create_constructor_wrapper(std::array<detail::metadata, Metadata_Count> metadata_list,
  94. detail::default_args<TArgs...> def_args,
  95. detail::parameter_infos<Param_Args...> param_infos)
  96. {
  97. using namespace detail;
  98. return detail::make_unique<constructor_wrapper<Class_Type, class_ctor,
  99. detail::map_access_level_to_enum<acc_level>::value,
  100. Policy,
  101. Metadata_Count,
  102. default_args<TArgs...>,
  103. parameter_infos<Param_Args...>, Visitor_List,
  104. Ctor_Args...>>(std::move(metadata_list),
  105. std::move(def_args),
  106. std::move(param_infos));
  107. }
  108. template<typename Policy, std::size_t Metadata_Count, typename...Param_Args>
  109. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base>
  110. create_constructor_wrapper(std::array<detail::metadata, Metadata_Count> metadata_list,
  111. detail::default_args<> def_args,
  112. detail::parameter_infos<Param_Args...> param_infos)
  113. {
  114. using namespace detail;
  115. return detail::make_unique<constructor_wrapper<Class_Type, class_ctor,
  116. detail::map_access_level_to_enum<acc_level>::value,
  117. Policy,
  118. Metadata_Count,
  119. default_args<>,
  120. parameter_infos<Param_Args...>, Visitor_List,
  121. Ctor_Args...>>(std::move(metadata_list),
  122. std::move(param_infos));
  123. }
  124. public:
  125. bind(const std::shared_ptr<detail::registration_executer>& reg_exec)
  126. : registration::class_<Class_Type>(reg_exec), m_reg_exec(reg_exec)
  127. {
  128. m_reg_exec->add_registration_func(this);
  129. }
  130. ~bind()
  131. {
  132. using namespace detail;
  133. using param_info_t = decltype(create_param_infos<type_list<Ctor_Args...>, constructor_type>());
  134. if (!m_ctor.get())
  135. m_ctor = detail::make_unique<detail::constructor_wrapper<Class_Type, class_ctor,
  136. detail::map_access_level_to_enum<acc_level>::value, default_create_policy,
  137. 0,
  138. detail::default_args<>,
  139. param_info_t,
  140. Visitor_List,
  141. Ctor_Args...>>(std::array<detail::metadata, 0>(),
  142. param_info_t());
  143. auto wrapper = detail::make_rref(std::move(m_ctor));
  144. auto reg_func = [wrapper]()
  145. {
  146. store_item<Class_Type>(std::move(wrapper.m_value));
  147. store_item<Class_Type>(detail::make_unique<destructor_wrapper<Class_Type>>());
  148. };
  149. m_reg_exec->add_registration_func(this, std::move(reg_func));
  150. }
  151. template<typename... Args>
  152. registration::class_<Class_Type> operator()(Args&&... args)
  153. {
  154. using namespace detail;
  155. using policy_types_found = typename find_types<constructor_policy_list, as_type_list_t<raw_type_t<Args>...>>::type;
  156. static_assert(!has_double_types<policy_types_found>::value, "There are multiple policies of the same type forwarded, that is not allowed!");
  157. using has_valid_default_types = has_default_types<type_list<Ctor_Args...>, type_list<Args...>, constructor_type>;
  158. static_assert( (has_default_args<Args...>::value && has_valid_default_types::value) || !has_default_args<Args...>::value,
  159. "The provided default arguments, cannot be used with the given constructor. Please check the provided argument types."
  160. "The given arguments must match the signature from the starting position to the right most argument.");
  161. static_assert((count_default_args<Args...>::value <= 1),
  162. "Only one set of 'default_arguments' can be provided during registration of a constructor!");
  163. static_assert((count_param_names<Args...>::value <= 1),
  164. "Only one set of 'parameter_names' can be provided during registration of a constructor!");
  165. static_assert(((!has_param_names<Args...>::value) ||
  166. (param_names_count<Args...>::value == sizeof...(Ctor_Args))),
  167. "The provided amount of names in 'parameter_names' does not match argument count of the constructor signature.");
  168. // when no policy was added, we need a default policy
  169. using policy_list = conditional_t< type_list_size<policy_types_found>::value == 0,
  170. default_create_policy,
  171. policy_types_found>;
  172. // at the moment we only supported one policy
  173. using first_prop_policy = typename std::tuple_element<0, as_std_tuple_t<policy_list>>::type;
  174. m_ctor = create_constructor_wrapper<first_prop_policy>(std::move(get_metadata(std::forward<Args>(args)...)),
  175. std::move(get_default_args<type_list<Ctor_Args...>, constructor_type>(std::forward<Args>(args)...)),
  176. std::move(create_param_infos<type_list<Ctor_Args...>, constructor_type>(std::forward<Args>(args)...)));
  177. return registration::class_<Class_Type>(m_reg_exec);
  178. }
  179. private:
  180. std::shared_ptr<detail::registration_executer> m_reg_exec;
  181. std::unique_ptr<detail::constructor_wrapper_base> m_ctor;
  182. };
  183. /////////////////////////////////////////////////////////////////////////////////////////
  184. template<typename Class_Type, typename F, typename acc_level, typename Visitor_List>
  185. class registration::bind<detail::ctor_func, Class_Type, F, acc_level, Visitor_List> : public registration::class_<Class_Type>
  186. {
  187. private:
  188. template<std::size_t Metadata_Count, typename...TArgs, typename...Param_Args>
  189. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base>
  190. create_constructor_wrapper(F func,
  191. std::array<detail::metadata, Metadata_Count> metadata_list,
  192. detail::default_args<TArgs...> def_args,
  193. detail::parameter_infos<Param_Args...> param_infos)
  194. {
  195. using namespace detail;
  196. return detail::make_unique<constructor_wrapper<Class_Type, return_func,
  197. detail::map_access_level_to_enum<acc_level>::value,
  198. default_invoke,
  199. Metadata_Count,
  200. default_args<TArgs...>,
  201. parameter_infos<Param_Args...>,
  202. Visitor_List,
  203. F>>(func,
  204. std::move(metadata_list),
  205. std::move(def_args),
  206. std::move(param_infos));
  207. }
  208. template<std::size_t Metadata_Count, typename...Param_Args>
  209. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base>
  210. create_constructor_wrapper(F func,
  211. std::array<detail::metadata, Metadata_Count> metadata_list,
  212. detail::default_args<> def_args,
  213. detail::parameter_infos<Param_Args...> param_infos)
  214. {
  215. using namespace detail;
  216. return detail::make_unique<constructor_wrapper<Class_Type, return_func,
  217. detail::map_access_level_to_enum<acc_level>::value,
  218. default_invoke,
  219. Metadata_Count,
  220. default_args<>,
  221. parameter_infos<Param_Args...>,
  222. Visitor_List,
  223. F>>(func,
  224. std::move(metadata_list),
  225. std::move(param_infos));
  226. }
  227. // this indirection is necessary to delay the instantiation of the created constructor wrapper
  228. // so we can make use of static_assert and check whether the given accessor is correct or not
  229. // REMARK: this seems to be a MSVC problem...
  230. template<typename Acc_Func>
  231. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base> create_default_constructor(Acc_Func func)
  232. {
  233. using namespace detail;
  234. using param_info_t = decltype(create_param_infos<type_list<Acc_Func>, function_type>());
  235. return detail::make_unique<constructor_wrapper<Class_Type, return_func,
  236. detail::map_access_level_to_enum<acc_level>::value,
  237. default_invoke,
  238. 0,
  239. detail::default_args<>,
  240. param_info_t, Visitor_List, F>>(func, std::array<detail::metadata, 0>(), param_info_t());
  241. }
  242. template<typename Acc_Func, typename... Args>
  243. static RTTR_INLINE std::unique_ptr<detail::constructor_wrapper_base> create_custom_constructor(Acc_Func func, Args&&...args)
  244. {
  245. using namespace detail;
  246. using has_valid_default_types = has_default_types<type_list<Acc_Func>, type_list<Args...>, function_type>;
  247. static_assert( (has_default_args<Args...>::value && has_valid_default_types::value) || !has_default_args<Args...>::value,
  248. "The provided default arguments, cannot be used with the given constructor. Please check the provided argument types."
  249. "The given arguments must match the signature from the starting position to the right most argument.");
  250. static_assert((count_default_args<Args...>::value <= 1),
  251. "Only one set of 'default_arguments' can be provided during registration of a constructor!");
  252. static_assert((count_param_names<Args...>::value <= 1),
  253. "Only one set of 'parameter_names' can be provided during registration of a constructor!");
  254. static_assert(((!has_param_names<Args...>::value) ||
  255. (param_names_count<Args...>::value == function_traits<Acc_Func>::arg_count)),
  256. "The provided amount of names in 'parameter_names' does not match argument count of the function signature.");
  257. return create_constructor_wrapper(func,
  258. get_metadata(std::forward<Args>(args)...),
  259. get_default_args<type_list<Acc_Func>, function_type>(std::forward<Args>(args)...),
  260. create_param_infos<type_list<F>, function_type>(std::forward<Args>(args)...));
  261. }
  262. public:
  263. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, F func)
  264. : registration::class_<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_func(func)
  265. {
  266. m_reg_exec->add_registration_func(this);
  267. }
  268. ~bind()
  269. {
  270. using namespace detail;
  271. if (!m_ctor.get())
  272. m_ctor = create_default_constructor(m_func);
  273. auto wrapper = detail::make_rref(std::move(m_ctor));
  274. auto reg_func = [wrapper]()
  275. {
  276. store_item<Class_Type>(std::move(wrapper.m_value));
  277. store_item<Class_Type>(detail::make_unique<destructor_wrapper<Class_Type>>());
  278. };
  279. m_reg_exec->add_registration_func(this, reg_func);
  280. }
  281. template<typename... Args>
  282. registration::class_<Class_Type> operator()(Args&&... args)
  283. {
  284. m_ctor = create_custom_constructor(m_func, std::forward<Args>(args)...);
  285. return registration::class_<Class_Type>(m_reg_exec);
  286. }
  287. private:
  288. std::shared_ptr<detail::registration_executer> m_reg_exec;
  289. F m_func;
  290. std::unique_ptr<detail::constructor_wrapper_base> m_ctor;
  291. };
  292. /////////////////////////////////////////////////////////////////////////////////////////
  293. template<typename T>
  294. using registration_derived_t = detail::conditional_t< std::is_same<T, void>::value,
  295. registration,
  296. registration::class_<T>
  297. >;
  298. /////////////////////////////////////////////////////////////////////////////////////////
  299. template<typename Class_Type, typename A, typename acc_level, typename Visitor_List>
  300. class registration::bind<detail::prop, Class_Type, A, acc_level, Visitor_List> : public registration_derived_t<Class_Type>
  301. {
  302. private:
  303. using default_getter_policy = detail::return_as_copy;
  304. using default_setter_policy = detail::set_value;
  305. template<typename Acc>
  306. static RTTR_INLINE
  307. std::unique_ptr<detail::property_wrapper_base> create_default_property(string_view name, Acc acc)
  308. {
  309. using namespace detail;
  310. using acc_type = typename property_type<Acc>::type;
  311. return detail::make_unique<property_wrapper<acc_type,
  312. Class_Type,
  313. A,
  314. void,
  315. detail::map_access_level_to_enum<acc_level>::value,
  316. default_getter_policy, default_setter_policy,
  317. 0,
  318. Visitor_List>
  319. >(name, acc, std::array<detail::metadata, 0>());
  320. }
  321. template<typename Acc, std::size_t Metadata_Count, typename... Args>
  322. static RTTR_INLINE
  323. std::unique_ptr<detail::property_wrapper_base> create_custom_property(string_view name,
  324. Acc acc,
  325. std::array<detail::metadata, Metadata_Count> metadata_list,
  326. Args&&...args)
  327. {
  328. using namespace detail;
  329. using policy_types_found = typename find_types<property_policy_list, as_type_list_t<raw_type_t<Args>...>>::type;
  330. static_assert(!has_double_types<policy_types_found>::value, "There are multiple policies of the same type forwarded, that is not allowed!");
  331. // when no policy was added, we need a default policy
  332. using policy_list = conditional_t< type_list_size<policy_types_found>::value == 0,
  333. default_getter_policy,
  334. policy_types_found>;
  335. // at the moment we only supported one policy
  336. using first_prop_policy = typename std::tuple_element<0, as_std_tuple_t<policy_list>>::type;
  337. using getter_policy = typename get_getter_policy<first_prop_policy>::type;
  338. using setter_policy = typename get_setter_policy<first_prop_policy>::type;
  339. using acc_type = typename property_type<Acc>::type;
  340. return detail::make_unique<property_wrapper<acc_type,
  341. Class_Type,
  342. Acc,
  343. void,
  344. detail::map_access_level_to_enum<acc_level>::value,
  345. getter_policy, setter_policy,
  346. Metadata_Count,
  347. Visitor_List>>(name, acc, std::move(metadata_list));
  348. }
  349. public:
  350. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, string_view name, A acc)
  351. : registration_derived_t<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_name(name), m_acc(acc)
  352. {
  353. detail::register_accessor_class_type_when_needed<Class_Type, A>();
  354. m_reg_exec->add_registration_func(this);
  355. }
  356. ~bind()
  357. {
  358. using namespace detail;
  359. if (!m_prop.get())
  360. m_prop = create_default_property(m_name, m_acc);
  361. auto wrapper = detail::make_rref(std::move(m_prop));
  362. auto reg_func = [wrapper]()
  363. {
  364. store_item<Class_Type>(std::move(wrapper.m_value));
  365. };
  366. m_reg_exec->add_registration_func(this, std::move(reg_func));
  367. }
  368. template<typename... Args>
  369. registration_derived_t<Class_Type> operator()(Args&&... args)
  370. {
  371. m_prop = create_custom_property(m_name, m_acc, std::move(get_metadata(std::forward<Args>(args)...)), std::forward<Args>(args)...);
  372. return registration_derived_t<Class_Type>(m_reg_exec);
  373. }
  374. private:
  375. std::shared_ptr<detail::registration_executer> m_reg_exec;
  376. string_view m_name;
  377. A m_acc;
  378. std::unique_ptr<detail::property_wrapper_base> m_prop;
  379. };
  380. /////////////////////////////////////////////////////////////////////////////////////////
  381. template<typename Class_Type, typename A1, typename A2, typename acc_level, typename Visitor_List>
  382. class registration::bind<detail::prop, Class_Type, A1, A2, acc_level, Visitor_List> : public registration_derived_t<Class_Type>
  383. {
  384. private:
  385. using default_getter_policy = detail::return_as_copy;
  386. using default_setter_policy = detail::set_value;
  387. template<typename Acc1, typename Acc2>
  388. static RTTR_INLINE
  389. std::unique_ptr<detail::property_wrapper_base> create_default_property(string_view name,
  390. Acc1 getter, Acc2 setter)
  391. {
  392. using namespace detail;
  393. using acc_type = typename property_type<A1>::type;
  394. return detail::make_unique<property_wrapper<acc_type,
  395. Class_Type,
  396. Acc1, Acc2,
  397. detail::map_access_level_to_enum<acc_level>::value,
  398. default_getter_policy, default_setter_policy, 0, Visitor_List
  399. >
  400. >(name, getter, setter, std::array<detail::metadata, 0>());
  401. }
  402. template<typename Acc1, typename Acc2, std::size_t Metadata_Count, typename... Args>
  403. static RTTR_INLINE
  404. std::unique_ptr<detail::property_wrapper_base> create_custom_property(string_view name,
  405. Acc1 getter, Acc2 setter,
  406. std::array<detail::metadata, Metadata_Count> metadata_list,
  407. Args&&...args)
  408. {
  409. using namespace detail;
  410. using policy_types_found = typename find_types<property_policy_list, as_type_list_t<raw_type_t<Args>...>>::type;
  411. static_assert(!has_double_types<policy_types_found>::value, "There are multiple policies of the same type forwarded, that is not allowed!");
  412. // when no policy was added, we need a default policy
  413. using policy_list = conditional_t< type_list_size<policy_types_found>::value == 0,
  414. default_getter_policy,
  415. policy_types_found>;
  416. // at the moment we only supported one policy
  417. using first_prop_policy = typename std::tuple_element<0, as_std_tuple_t<policy_list>>::type;
  418. using getter_policy = typename get_getter_policy<first_prop_policy>::type;
  419. using setter_policy = typename get_setter_policy<first_prop_policy>::type;
  420. using acc_type = typename property_type<A1>::type;
  421. return detail::make_unique<property_wrapper<acc_type,
  422. Class_Type,
  423. Acc1, Acc2,
  424. detail::map_access_level_to_enum<acc_level>::value,
  425. getter_policy, setter_policy,
  426. Metadata_Count, Visitor_List
  427. >
  428. >(name, getter, setter, std::move(metadata_list));
  429. }
  430. public:
  431. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, string_view name, A1 getter, A2 setter)
  432. : registration_derived_t<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_name(name), m_getter(getter), m_setter(setter)
  433. {
  434. detail::register_accessor_class_type_when_needed<Class_Type, A1>();
  435. detail::register_accessor_class_type_when_needed<Class_Type, A2>();
  436. m_reg_exec->add_registration_func(this);
  437. }
  438. ~bind()
  439. {
  440. using namespace detail;
  441. if (!m_prop.get())
  442. m_prop = create_default_property(m_name, m_getter, m_setter);
  443. auto wrapper = detail::make_rref(std::move(m_prop));
  444. auto reg_func = [wrapper]()
  445. {
  446. store_item<Class_Type>(std::move(wrapper.m_value));
  447. };
  448. m_reg_exec->add_registration_func(this, std::move(reg_func));
  449. }
  450. template<typename... Args>
  451. registration_derived_t<Class_Type> operator()(Args&&... args)
  452. {
  453. m_prop = create_custom_property(m_name,
  454. m_getter, m_setter,
  455. std::move(get_metadata(std::forward<Args>(args)...)), std::forward<Args>(args)...);
  456. return registration_derived_t<Class_Type>(m_reg_exec);
  457. }
  458. private:
  459. std::shared_ptr<detail::registration_executer> m_reg_exec;
  460. string_view m_name;
  461. A1 m_getter;
  462. A2 m_setter;
  463. std::unique_ptr<detail::property_wrapper_base> m_prop;
  464. };
  465. /////////////////////////////////////////////////////////////////////////////////////////
  466. template<typename Class_Type, typename A, typename acc_level, typename Visitor_List>
  467. class registration::bind<detail::prop_readonly, Class_Type, A, acc_level, Visitor_List> : public registration_derived_t<Class_Type>
  468. {
  469. private:
  470. using default_getter_policy = detail::return_as_copy;
  471. using default_setter_policy = detail::read_only;
  472. template<typename Acc>
  473. static RTTR_INLINE
  474. std::unique_ptr<detail::property_wrapper_base> create_default_property(string_view name, Acc acc)
  475. {
  476. using namespace detail;
  477. using acc_type = typename property_type<Acc>::type;
  478. return detail::make_unique<property_wrapper<acc_type, Class_Type, A, void,
  479. detail::map_access_level_to_enum<acc_level>::value,
  480. default_getter_policy, default_setter_policy, 0, Visitor_List
  481. >
  482. >(name, acc, std::array<detail::metadata, 0>());
  483. }
  484. template<typename Acc, std::size_t Metadata_Count, typename... Args>
  485. static RTTR_INLINE
  486. std::unique_ptr<detail::property_wrapper_base> create_custom_property(string_view name,
  487. Acc acc,
  488. std::array<detail::metadata,
  489. Metadata_Count> metadata_list,
  490. Args&&...args)
  491. {
  492. using namespace detail;
  493. using policy_types_found = typename find_types<property_policy_list, as_type_list_t<raw_type_t<Args>...>>::type;
  494. static_assert(!has_double_types<policy_types_found>::value, "There are multiple policies of the same type forwarded, that is not allowed!");
  495. // when no policy was added, we need a default policy
  496. using policy_list = conditional_t< type_list_size<policy_types_found>::value == 0,
  497. default_getter_policy,
  498. policy_types_found>;
  499. // at the moment we only supported one policy
  500. using first_prop_policy = typename std::tuple_element<0, as_std_tuple_t<policy_list>>::type;
  501. using getter_policy = typename get_getter_policy<first_prop_policy>::type;
  502. using acc_type = typename property_type<Acc>::type;
  503. return detail::make_unique<property_wrapper<acc_type, Class_Type, Acc, void,
  504. detail::map_access_level_to_enum<acc_level>::value,
  505. getter_policy, default_setter_policy, Metadata_Count, Visitor_List
  506. >
  507. >(name, acc, std::move(metadata_list));
  508. }
  509. public:
  510. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, string_view name, A acc)
  511. : registration_derived_t<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_name(name), m_acc(acc)
  512. {
  513. detail::register_accessor_class_type_when_needed<Class_Type, A>();
  514. m_reg_exec->add_registration_func(this);
  515. }
  516. ~bind()
  517. {
  518. using namespace detail;
  519. if (!m_prop.get())
  520. m_prop = create_default_property(m_name, m_acc);
  521. auto wrapper = detail::make_rref(std::move(m_prop));
  522. auto reg_func = [wrapper]()
  523. {
  524. store_item<Class_Type>(std::move(wrapper.m_value));
  525. };
  526. m_reg_exec->add_registration_func(this, std::move(reg_func));
  527. }
  528. template<typename... Args>
  529. registration_derived_t<Class_Type> operator()(Args&&... args)
  530. {
  531. m_prop = create_custom_property(m_name, m_acc,
  532. std::move(get_metadata(std::forward<Args>(args)...)),
  533. std::forward<Args>(args)...);
  534. return registration_derived_t<Class_Type>(m_reg_exec);
  535. }
  536. private:
  537. std::shared_ptr<detail::registration_executer> m_reg_exec;
  538. string_view m_name;
  539. A m_acc;
  540. std::unique_ptr<detail::property_wrapper_base> m_prop;
  541. };
  542. /////////////////////////////////////////////////////////////////////////////////////////
  543. template<typename Class_Type, typename F, typename acc_level, typename Visitor_List>
  544. class registration::bind<detail::meth, Class_Type, F, acc_level, Visitor_List> : public registration_derived_t<Class_Type>
  545. {
  546. private:
  547. template<typename Acc_Func>
  548. static RTTR_INLINE std::unique_ptr<detail::method_wrapper_base> create_default_method(string_view name, Acc_Func func)
  549. {
  550. using namespace detail;
  551. using param_info_t = decltype(create_param_infos<type_list<F>, function_type>());
  552. return detail::make_unique<method_wrapper<Acc_Func,
  553. Class_Type,
  554. map_access_level_to_enum<acc_level>::value,
  555. default_invoke,
  556. default_args<>,
  557. param_info_t,
  558. 0,
  559. Visitor_List>>(name, func, std::array<detail::metadata, 0>(), param_info_t());
  560. }
  561. template<typename Acc_Func, typename... Args>
  562. static RTTR_INLINE std::unique_ptr<detail::method_wrapper_base> create_custom_method(string_view name, Acc_Func func, Args&&...args)
  563. {
  564. using namespace detail;
  565. using policy_types_found = typename find_types<method_policy_list, as_type_list_t<raw_type_t<Args>...>>::type;
  566. static_assert(!has_double_types<policy_types_found>::value, "There are multiple policies of the same type forwarded, that is not allowed!");
  567. using has_valid_default_types = has_default_types<type_list<Acc_Func>, type_list<Args...>, function_type>;
  568. static_assert( (has_default_args<Args...>::value && has_valid_default_types::value) || !has_default_args<Args...>::value,
  569. "The provided default arguments, cannot be used with the given method. Please check the provided argument types."
  570. "The given arguments must match the signature from the starting position to the right most argument.");
  571. static_assert((count_default_args<Args...>::value <= 1),
  572. "Only one set of 'default_arguments' can be provided during registration of a method!");
  573. static_assert((count_param_names<Args...>::value <= 1),
  574. "Only one set of 'parameter_names' can be provided during registration of a method!");
  575. static_assert(((!has_param_names<Args...>::value) ||
  576. (param_names_count<Args...>::value == function_traits<Acc_Func>::arg_count)),
  577. "The provided amount of names in 'parameter_names' does not match argument count of the function signature.");
  578. // when no policy was added, we need a default policy
  579. using policy_list = conditional_t< type_list_size<policy_types_found>::value == 0,
  580. default_invoke,
  581. policy_types_found>;
  582. using policy = typename std::tuple_element<0, as_std_tuple_t<policy_list>>::type;
  583. using metadata_count = count_type<::rttr::detail::metadata, type_list<Args...>>;
  584. return create_method_wrapper<policy,
  585. metadata_count::value>(name, func,
  586. get_metadata(std::forward<Args>(args)...),
  587. get_default_args<type_list<Acc_Func>, function_type>(std::forward<Args>(args)...),
  588. create_param_infos<type_list<F>, function_type>(std::forward<Args>(args)...) );
  589. }
  590. template<typename Policy, std::size_t Metadata_Count, typename...TArgs, typename...Param_Args>
  591. static RTTR_INLINE std::unique_ptr<detail::method_wrapper_base>
  592. create_method_wrapper(string_view name, F func,
  593. std::array<detail::metadata, Metadata_Count> metadata_list,
  594. detail::default_args<TArgs...> def_args,
  595. detail::parameter_infos<Param_Args...> param_infos)
  596. {
  597. return detail::make_unique<detail::method_wrapper<F,
  598. Class_Type,
  599. detail::map_access_level_to_enum<acc_level>::value,
  600. Policy,
  601. detail::default_args<TArgs...>,
  602. detail::parameter_infos<Param_Args...>,
  603. Metadata_Count,
  604. Visitor_List>>(name,
  605. func,
  606. std::move(metadata_list),
  607. std::move(def_args),
  608. std::move(param_infos));
  609. }
  610. template<typename Policy, std::size_t Metadata_Count, typename...Param_Args>
  611. static RTTR_INLINE std::unique_ptr<detail::method_wrapper_base>
  612. create_method_wrapper(string_view name, F func,
  613. std::array<detail::metadata, Metadata_Count> metadata_list,
  614. detail::default_args<> def_args,
  615. detail::parameter_infos<Param_Args...> param_infos)
  616. {
  617. return detail::make_unique<detail::method_wrapper<F,
  618. Class_Type,
  619. detail::map_access_level_to_enum<acc_level>::value,
  620. Policy,
  621. detail::default_args<>,
  622. detail::parameter_infos<Param_Args...>,
  623. Metadata_Count,
  624. Visitor_List>>(name,
  625. func,
  626. std::move(metadata_list),
  627. std::move(param_infos));
  628. }
  629. public:
  630. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, string_view name, F f)
  631. : registration_derived_t<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_name(name), m_func(f)
  632. {
  633. detail::register_accessor_class_type_when_needed<Class_Type, F>();
  634. m_reg_exec->add_registration_func(this);
  635. }
  636. ~bind()
  637. {
  638. using namespace detail;
  639. if (!m_meth.get())
  640. m_meth = create_default_method(m_name, m_func);
  641. auto wrapper = detail::make_rref(std::move(m_meth));
  642. auto reg_func = [wrapper]()
  643. {
  644. store_item<Class_Type>(std::move(wrapper.m_value));
  645. };
  646. m_reg_exec->add_registration_func(this, std::move(reg_func));
  647. }
  648. public:
  649. template<typename... Args>
  650. registration_derived_t<Class_Type> operator()(Args&&... args)
  651. {
  652. m_meth = create_custom_method(m_name, m_func, std::forward<Args>(args)...);
  653. return registration_derived_t<Class_Type>(m_reg_exec);
  654. }
  655. private:
  656. std::shared_ptr<detail::registration_executer> m_reg_exec;
  657. string_view m_name;
  658. F m_func;
  659. std::unique_ptr<detail::method_wrapper_base> m_meth;
  660. };
  661. /////////////////////////////////////////////////////////////////////////////////////////
  662. template<typename Class_Type, typename Enum_Type>
  663. class registration::bind<detail::enum_, Class_Type, Enum_Type> : public registration_derived_t<Class_Type>
  664. {
  665. private:
  666. template<typename E_Type>
  667. static RTTR_INLINE std::unique_ptr<detail::enumeration_wrapper_base> create_default_enum()
  668. {
  669. using namespace detail;
  670. return detail::make_unique<enumeration_wrapper<E_Type, 0, 0>>(get_enum_values<E_Type>(), std::array<detail::metadata, 0>());
  671. }
  672. template<typename E_Type, typename... Args>
  673. static RTTR_INLINE std::unique_ptr<detail::enumeration_wrapper_base> create_custom_enum(Args&&...args)
  674. {
  675. using namespace detail;
  676. static RTTR_CONSTEXPR_OR_CONST std::size_t enum_count = count_type<enum_data<Enum_Type>, type_list<raw_type_t<Args>...>>::value;
  677. static RTTR_CONSTEXPR_OR_CONST std::size_t global_enum_count = count_if<is_enum_data, raw_type_t<Args>...>::value;
  678. static_assert(enum_count == global_enum_count, "Invalid 'value' pair for enumeration type provided, please specify values only for enums of type 'Enum_Type'.");
  679. using metadata_count = count_type<::rttr::detail::metadata, type_list<Args...>>;
  680. return detail::make_unique<enumeration_wrapper<E_Type,
  681. enum_count,
  682. metadata_count::value>>(get_enum_values<E_Type>(std::forward<Args>(args)...),
  683. get_metadata(std::forward<Args>(args)...));
  684. }
  685. public:
  686. bind(const std::shared_ptr<detail::registration_executer>& reg_exec, string_view name)
  687. : registration_derived_t<Class_Type>(reg_exec), m_reg_exec(reg_exec), m_declared_type(type::template get<Class_Type>())
  688. {
  689. using namespace detail;
  690. m_reg_exec->add_registration_func(this);
  691. auto t = type::template get<Enum_Type>();
  692. type_register::custom_name(t, name);
  693. }
  694. ~bind()
  695. {
  696. using namespace detail;
  697. if (!m_enum.get())
  698. m_enum = create_default_enum<Enum_Type>();
  699. m_enum->set_declaring_type(m_declared_type);
  700. // register the underlying type with the following call:
  701. m_enum->get_type();
  702. auto wrapper = detail::make_rref(std::move(m_enum));
  703. auto reg_func = [wrapper]()
  704. {
  705. store_item<Class_Type>(std::move(wrapper.m_value));
  706. };
  707. m_reg_exec->add_registration_func(this, std::move(reg_func));
  708. }
  709. template<typename... Args>
  710. registration_derived_t<Class_Type> operator()(Args&&... arg)
  711. {
  712. m_enum = create_custom_enum<Enum_Type>(std::forward<Args>(arg)...);
  713. return registration_derived_t<Class_Type>(m_reg_exec);
  714. }
  715. private:
  716. std::shared_ptr<detail::registration_executer> m_reg_exec;
  717. type m_declared_type;
  718. std::unique_ptr<detail::enumeration_wrapper_base> m_enum;
  719. };
  720. } // end namespace rttr
  721. #endif // RTTR_BIND_REFLECTION_IMPL_H_