method_wrapper.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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_METHOD_WRAPPER_H_
  28. #define RTTR_METHOD_WRAPPER_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/method/method_wrapper_base.h"
  31. #include "rttr/detail/misc/function_traits.h"
  32. #include "rttr/detail/type/accessor_type.h"
  33. #include "rttr/detail/method/method_accessor.h"
  34. #include "rttr/detail/default_arguments/default_arguments.h"
  35. #include "rttr/detail/default_arguments/invoke_with_defaults.h"
  36. #include "rttr/detail/parameter_info/parameter_infos.h"
  37. #include "rttr/argument.h"
  38. #include "rttr/instance.h"
  39. #include "rttr/variant.h"
  40. #include "rttr/array_range.h"
  41. #include "rttr/detail/visitor/visitor_iterator.h"
  42. #include "rttr/detail/visitor/method_visitor_invoker.h"
  43. #include <functional>
  44. #include <string>
  45. #include <array>
  46. namespace rttr
  47. {
  48. namespace detail
  49. {
  50. template<typename F, typename Declaring_Type, access_levels Acc_Level, typename Policy, typename Default_Args, typename Parameter_Infos, std::size_t Metadata_Count, typename Visitor_List>
  51. class method_wrapper;
  52. /////////////////////////////////////////////////////////////////////////////////////////
  53. /////////////////////////////////////////////////////////////////////////////////////////
  54. /////////////////////////////////////////////////////////////////////////////////////////
  55. template<typename F, typename Declaring_Type, access_levels Acc_Level, typename Policy, typename... Param_Args, std::size_t Metadata_Count, typename Visitor_List>
  56. class method_wrapper<F, Declaring_Type, Acc_Level, Policy, default_args<>, parameter_infos<Param_Args...>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler<Metadata_Count>
  57. {
  58. public:
  59. method_wrapper(string_view name,
  60. F func_acc,
  61. std::array<metadata, Metadata_Count> metadata_list,
  62. parameter_infos<Param_Args...> param_infos) RTTR_NOEXCEPT
  63. : method_wrapper_base(name, type::get<Declaring_Type>()),
  64. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  65. m_func_acc(func_acc),
  66. m_param_infos(std::move(param_infos)),
  67. m_param_info_list(create_paramter_info_array(m_param_infos))
  68. {
  69. init();
  70. }
  71. bool is_valid() const RTTR_NOEXCEPT { return true; }
  72. bool is_static() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::is_static(); }
  73. type get_return_type() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_return_type(); }
  74. std::vector<bool> get_is_reference() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_reference(); }
  75. std::vector<bool> get_is_const() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_const(); }
  76. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  77. array_range<parameter_info> get_parameter_infos() const RTTR_NOEXCEPT { return array_range<parameter_info>(const_cast<decltype(m_param_info_list)&>(m_param_info_list).data(),
  78. m_param_info_list.size()); }
  79. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  80. variant invoke(instance& object) const
  81. {
  82. return method_accessor<F, Policy>::invoke(m_func_acc, object);
  83. }
  84. variant invoke(instance& object, argument& arg1) const
  85. {
  86. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1);
  87. }
  88. variant invoke(instance& object, argument& arg1, argument& arg2) const
  89. {
  90. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2);
  91. }
  92. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const
  93. {
  94. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3);
  95. }
  96. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const
  97. {
  98. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4);
  99. }
  100. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const
  101. {
  102. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5);
  103. }
  104. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const
  105. {
  106. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5, arg6);
  107. }
  108. variant invoke_variadic(const instance& object, std::vector<argument>& args) const
  109. {
  110. return method_accessor<F, Policy>::invoke_variadic(m_func_acc, object, args);
  111. }
  112. void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT
  113. {
  114. auto obj = make_method_info<Declaring_Type, Policy, F>(meth, m_func_acc);
  115. visitor_iterator<Visitor_List>::visit(visitor, make_method_visitor_invoker(obj));
  116. }
  117. private:
  118. F m_func_acc;
  119. parameter_infos<Param_Args...> m_param_infos;
  120. std::array<parameter_info, sizeof...(Param_Args)> m_param_info_list;
  121. };
  122. /////////////////////////////////////////////////////////////////////////////////////////
  123. template<typename F, typename Declaring_Type, access_levels Acc_Level, typename Policy, typename...Default_Args, typename...Param_Args, std::size_t Metadata_Count, typename Visitor_List>
  124. class method_wrapper<F, Declaring_Type, Acc_Level, Policy, default_args<Default_Args...>, parameter_infos<Param_Args...>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler<Metadata_Count>
  125. {
  126. using method_type = typename detail::method_type<F>::type;
  127. using arg_index_sequence = make_index_sequence<function_traits<F>::arg_count>;
  128. using invoker_class = method_invoker<F, Policy, method_type, arg_index_sequence>;
  129. using invoke_with_defaults = invoke_defaults_helper<invoker_class, F>;
  130. public:
  131. method_wrapper(string_view name,
  132. F func_acc,
  133. std::array<metadata, Metadata_Count> metadata_list,
  134. default_args<Default_Args...> default_args,
  135. parameter_infos<Param_Args...> param_infos) RTTR_NOEXCEPT
  136. : method_wrapper_base(name, type::get<Declaring_Type>()),
  137. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  138. m_func_acc(func_acc),
  139. m_def_args(std::move(default_args)),
  140. m_param_infos(std::move(param_infos)),
  141. m_param_info_list(create_paramter_info_array(m_param_infos))
  142. {
  143. store_default_args_in_param_infos(m_param_infos, m_def_args);
  144. init();
  145. }
  146. bool is_valid() const RTTR_NOEXCEPT { return true; }
  147. bool is_static() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::is_static(); }
  148. type get_return_type() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_return_type(); }
  149. std::vector<bool> get_is_reference() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_reference(); }
  150. std::vector<bool> get_is_const() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_const(); }
  151. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  152. array_range<parameter_info> get_parameter_infos() const RTTR_NOEXCEPT { return array_range<parameter_info>(const_cast<decltype(m_param_info_list)&>(m_param_info_list).data(),
  153. m_param_info_list.size()); }
  154. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  155. variant invoke(instance& object) const
  156. {
  157. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args);
  158. }
  159. variant invoke(instance& object, argument& arg1) const
  160. {
  161. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1);
  162. }
  163. variant invoke(instance& object, argument& arg1, argument& arg2) const
  164. {
  165. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2);
  166. }
  167. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const
  168. {
  169. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3);
  170. }
  171. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const
  172. {
  173. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4);
  174. }
  175. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const
  176. {
  177. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5);
  178. }
  179. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const
  180. {
  181. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5, arg6);
  182. }
  183. variant invoke_variadic(const instance& object, std::vector<argument>& args) const
  184. {
  185. if (args.size() <= function_traits<F>::arg_count)
  186. return invoke_variadic_helper<invoke_with_defaults, arg_index_sequence>::invoke(args, m_func_acc, object, m_def_args.m_args);
  187. else
  188. return variant();
  189. }
  190. void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT
  191. {
  192. auto obj = make_method_info<Declaring_Type, Policy, F>(meth, m_func_acc);
  193. visitor_iterator<Visitor_List>::visit(visitor, make_method_visitor_invoker(obj));
  194. }
  195. private:
  196. F m_func_acc;
  197. default_args<Default_Args...> m_def_args;
  198. parameter_infos<Param_Args...> m_param_infos;
  199. std::array<parameter_info, sizeof...(Param_Args)> m_param_info_list;
  200. };
  201. /////////////////////////////////////////////////////////////////////////////////////////
  202. template<typename F, typename Declaring_Type, access_levels Acc_Level, typename Policy, std::size_t Metadata_Count, typename Visitor_List>
  203. class method_wrapper<F, Declaring_Type, Acc_Level, Policy, default_args<>, parameter_infos<>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler<Metadata_Count>
  204. {
  205. public:
  206. method_wrapper(string_view name,
  207. F func_acc,
  208. std::array<metadata, Metadata_Count> metadata_list,
  209. parameter_infos<> param_infos) RTTR_NOEXCEPT
  210. : method_wrapper_base(name, type::get<Declaring_Type>()),
  211. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  212. m_func_acc(func_acc)
  213. {
  214. init();
  215. }
  216. bool is_valid() const RTTR_NOEXCEPT { return true; }
  217. bool is_static() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::is_static(); }
  218. type get_return_type() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_return_type(); }
  219. std::vector<bool> get_is_reference() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_reference(); }
  220. std::vector<bool> get_is_const() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_const(); }
  221. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  222. array_range<parameter_info> get_parameter_infos() const RTTR_NOEXCEPT { return array_range<parameter_info>(); }
  223. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  224. variant invoke(instance& object) const
  225. {
  226. return method_accessor<F, Policy>::invoke(m_func_acc, object);
  227. }
  228. variant invoke(instance& object, argument& arg1) const
  229. {
  230. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1);
  231. }
  232. variant invoke(instance& object, argument& arg1, argument& arg2) const
  233. {
  234. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2);
  235. }
  236. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const
  237. {
  238. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3);
  239. }
  240. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const
  241. {
  242. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4);
  243. }
  244. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const
  245. {
  246. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5);
  247. }
  248. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const
  249. {
  250. return method_accessor<F, Policy>::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5, arg6);
  251. }
  252. variant invoke_variadic(const instance& object, std::vector<argument>& args) const
  253. {
  254. return method_accessor<F, Policy>::invoke_variadic(m_func_acc, object, args);
  255. }
  256. void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT
  257. {
  258. auto obj = make_method_info<Declaring_Type, Policy, F>(meth, m_func_acc);
  259. visitor_iterator<Visitor_List>::visit(visitor, make_method_visitor_invoker(obj));
  260. }
  261. private:
  262. F m_func_acc;
  263. };
  264. /////////////////////////////////////////////////////////////////////////////////////////
  265. template<typename F, typename Declaring_Type, access_levels Acc_Level, typename Policy, typename...Default_Args, std::size_t Metadata_Count, typename Visitor_List>
  266. class method_wrapper<F, Declaring_Type, Acc_Level, Policy, default_args<Default_Args...>, parameter_infos<>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler<Metadata_Count>
  267. {
  268. using method_type = typename detail::method_type<F>::type;
  269. using arg_index_sequence = make_index_sequence<function_traits<F>::arg_count>;
  270. using invoker_class = method_invoker<F, Policy, method_type, arg_index_sequence>;
  271. using invoke_with_defaults = invoke_defaults_helper<invoker_class, F>;
  272. public:
  273. method_wrapper(string_view name,
  274. F func_acc,
  275. std::array<metadata, Metadata_Count> metadata_list,
  276. default_args<Default_Args...> default_args,
  277. parameter_infos<> param_infos)
  278. : method_wrapper_base(name, type::get<Declaring_Type>()),
  279. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  280. m_func_acc(func_acc),
  281. m_def_args(std::move(default_args))
  282. {
  283. init();
  284. }
  285. bool is_valid() const RTTR_NOEXCEPT { return true; }
  286. bool is_static() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::is_static(); }
  287. type get_return_type() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_return_type(); }
  288. std::vector<bool> get_is_reference() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_reference(); }
  289. std::vector<bool> get_is_const() const RTTR_NOEXCEPT { return method_accessor<F, Policy>::get_is_const(); }
  290. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  291. array_range<parameter_info> get_parameter_infos() const RTTR_NOEXCEPT { return array_range<parameter_info>(); }
  292. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  293. variant invoke(instance& object) const
  294. {
  295. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args);
  296. }
  297. variant invoke(instance& object, argument& arg1) const
  298. {
  299. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1);
  300. }
  301. variant invoke(instance& object, argument& arg1, argument& arg2) const
  302. {
  303. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2);
  304. }
  305. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const
  306. {
  307. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3);
  308. }
  309. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const
  310. {
  311. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4);
  312. }
  313. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const
  314. {
  315. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5);
  316. }
  317. variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const
  318. {
  319. return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5, arg6);
  320. }
  321. variant invoke_variadic(const instance& object, std::vector<argument>& args) const
  322. {
  323. if (args.size() <= function_traits<F>::arg_count)
  324. return invoke_variadic_helper<invoke_with_defaults, arg_index_sequence>::invoke(args, m_func_acc, object, m_def_args.m_args);
  325. else
  326. return variant();
  327. }
  328. void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT
  329. {
  330. auto obj = make_method_info<Declaring_Type, Policy, F>(meth, m_func_acc);
  331. visitor_iterator<Visitor_List>::visit(visitor, make_method_visitor_invoker(obj));
  332. }
  333. private:
  334. F m_func_acc;
  335. default_args<Default_Args...> m_def_args;
  336. };
  337. /////////////////////////////////////////////////////////////////////////////////////////
  338. } // end namespace detail
  339. } // end namespace rttr
  340. #endif // RTTR_METHOD_WRAPPER_H_