property_wrapper_member_func.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  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_PROPERTY_WRAPPER_MEMBER_FUNC_H_
  28. #define RTTR_PROPERTY_WRAPPER_MEMBER_FUNC_H_
  29. /////////////////////////////////////////////////////////////////////////////////////////
  30. /////////////////////////////////////////////////////////////////////////////////////////
  31. // Getter/Setter - pointer to member function
  32. template<typename Declaring_Typ, typename Getter, typename Setter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  33. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, Setter, Acc_Level, return_as_copy, set_value, Metadata_Count, Visitor_List>
  34. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  35. {
  36. using return_type = typename function_traits<Getter>::return_type;
  37. using arg_type = typename param_types<Setter, 0>::type;
  38. using class_type = typename function_traits<Getter>::class_type;
  39. public:
  40. property_wrapper(string_view name,
  41. Getter get, Setter set,
  42. std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  43. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  44. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  45. m_getter(get), m_setter(set)
  46. {
  47. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  48. static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-member-function with exactly one argument.");
  49. static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
  50. init();
  51. }
  52. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  53. bool is_valid() const RTTR_NOEXCEPT { return true; }
  54. bool is_readonly() const RTTR_NOEXCEPT { return false; }
  55. bool is_static() const RTTR_NOEXCEPT { return false; }
  56. type get_type() const RTTR_NOEXCEPT { return type::get<return_type>(); }
  57. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  58. bool set_value(instance& object, argument& arg) const
  59. {
  60. class_type* ptr = object.try_convert<class_type>();
  61. if (ptr && arg.is_type<arg_type>() )
  62. {
  63. (ptr->*m_setter)(arg.get_value<arg_type>());
  64. return true;
  65. }
  66. return false;
  67. }
  68. variant get_value(instance& object) const
  69. {
  70. if (class_type* ptr = object.try_convert<class_type>())
  71. return variant((ptr->*m_getter)());
  72. else
  73. return variant();
  74. }
  75. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  76. {
  77. auto obj = make_property_getter_setter_info<Declaring_Typ, return_as_copy, Getter, Setter>(prop, m_getter, m_setter);
  78. visitor_iterator<Visitor_List>::visit(visitor, make_property_getter_setter_visitor_invoker(obj));
  79. }
  80. private:
  81. Getter m_getter;
  82. Setter m_setter;
  83. };
  84. /////////////////////////////////////////////////////////////////////////////////////////
  85. /////////////////////////////////////////////////////////////////////////////////////////
  86. // Getter - pointer to member function
  87. template<typename Declaring_Typ, typename Getter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  88. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, void, Acc_Level, return_as_copy, read_only, Metadata_Count, Visitor_List>
  89. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  90. {
  91. using return_type = typename function_traits<Getter>::return_type;
  92. using class_type = typename function_traits<Getter>::class_type;
  93. public:
  94. property_wrapper(string_view name,
  95. Getter get, std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  96. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  97. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  98. m_getter(get)
  99. {
  100. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  101. init();
  102. }
  103. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  104. bool is_valid() const RTTR_NOEXCEPT { return true; }
  105. bool is_readonly() const RTTR_NOEXCEPT { return true; }
  106. bool is_static() const RTTR_NOEXCEPT { return false; }
  107. type get_type() const RTTR_NOEXCEPT { return type::get<return_type>(); }
  108. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  109. bool set_value(instance& object, argument& arg) const
  110. {
  111. return false;
  112. }
  113. variant get_value(instance& object) const
  114. {
  115. if (class_type* ptr = object.try_convert<class_type>())
  116. return variant((ptr->*m_getter)());
  117. else
  118. return variant();
  119. }
  120. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  121. {
  122. auto obj = make_property_info<Declaring_Typ, return_as_copy, Getter>(prop, m_getter);
  123. visitor_iterator<Visitor_List>::visit(visitor, make_property_visitor_invoker<read_only>(obj));
  124. }
  125. private:
  126. Getter m_getter;
  127. };
  128. /////////////////////////////////////////////////////////////////////////////////////////
  129. // Policy return_as_ptr
  130. /////////////////////////////////////////////////////////////////////////////////////////
  131. // Getter/Setter pointer to member function
  132. template<typename Declaring_Typ, typename Getter, typename Setter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  133. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, Setter, Acc_Level, return_as_ptr, set_as_ptr, Metadata_Count, Visitor_List>
  134. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  135. {
  136. using return_type = typename function_traits<Getter>::return_type;
  137. using arg_type = typename param_types<Setter, 0>::type;
  138. using class_type = typename function_traits<Getter>::class_type;
  139. public:
  140. property_wrapper(string_view name,
  141. Getter get, Setter set,
  142. std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  143. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  144. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  145. m_getter(get), m_setter(set)
  146. {
  147. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  148. static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-member-function with exactly one argument.");
  149. static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
  150. static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
  151. static_assert(std::is_reference<arg_type>::value, "Please provide a setter-member-function with a reference as return value!");
  152. init();
  153. }
  154. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  155. bool is_valid() const RTTR_NOEXCEPT { return true; }
  156. bool is_readonly() const RTTR_NOEXCEPT { return false; }
  157. bool is_static() const RTTR_NOEXCEPT { return false; }
  158. type get_type() const RTTR_NOEXCEPT { return type::get<typename std::remove_reference<return_type>::type*>(); }
  159. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  160. bool set_value(instance& object, argument& arg) const
  161. {
  162. using arg_type_t = remove_reference_t<arg_type>;
  163. class_type* ptr = object.try_convert<class_type>();
  164. if (ptr && arg.is_type<arg_type_t*>())
  165. {
  166. (ptr->*m_setter)(*arg.get_value<arg_type_t*>());
  167. return true;
  168. }
  169. return false;
  170. }
  171. variant get_value(instance& object) const
  172. {
  173. if (class_type* ptr = object.try_convert<class_type>())
  174. return variant(&(ptr->*m_getter)());
  175. else
  176. return variant();
  177. }
  178. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  179. {
  180. auto obj = make_property_getter_setter_info<Declaring_Typ, return_as_ptr, Getter, Setter>(prop, m_getter, m_setter);
  181. visitor_iterator<Visitor_List>::visit(visitor, make_property_getter_setter_visitor_invoker(obj));
  182. }
  183. private:
  184. Getter m_getter;
  185. Setter m_setter;
  186. };
  187. /////////////////////////////////////////////////////////////////////////////////////////
  188. /////////////////////////////////////////////////////////////////////////////////////////
  189. // Getter - pointer to member function
  190. template<typename Declaring_Typ, typename Getter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  191. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, void, Acc_Level, return_as_ptr, read_only, Metadata_Count, Visitor_List>
  192. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  193. {
  194. using return_type = typename function_traits<Getter>::return_type;
  195. using class_type = typename function_traits<Getter>::class_type;
  196. using policy_type = add_pointer_t<add_const_t<remove_reference_t<return_type>>>;
  197. public:
  198. property_wrapper(string_view name,
  199. Getter get,
  200. std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  201. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  202. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  203. m_getter(get)
  204. {
  205. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  206. static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
  207. init();
  208. }
  209. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  210. bool is_valid() const RTTR_NOEXCEPT { return true; }
  211. bool is_readonly() const RTTR_NOEXCEPT { return true; }
  212. bool is_static() const RTTR_NOEXCEPT { return false; }
  213. type get_type() const RTTR_NOEXCEPT { return type::get<policy_type>(); }
  214. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  215. bool set_value(instance& object, argument& arg) const
  216. {
  217. return false;
  218. }
  219. variant get_value(instance& object) const
  220. {
  221. if (class_type* ptr = object.try_convert<class_type>())
  222. return variant(const_cast<policy_type>(&(ptr->*m_getter)()));
  223. else
  224. return variant();
  225. }
  226. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  227. {
  228. auto obj = make_property_info<Declaring_Typ, return_as_ptr, Getter>(prop, m_getter);
  229. visitor_iterator<Visitor_List>::visit(visitor, make_property_visitor_invoker<read_only>(obj));
  230. }
  231. private:
  232. Getter m_getter;
  233. };
  234. /////////////////////////////////////////////////////////////////////////////////////////
  235. // Policy return_as_ptr
  236. /////////////////////////////////////////////////////////////////////////////////////////
  237. // Getter/Setter pointer to member function
  238. template<typename Declaring_Typ, typename Getter, typename Setter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  239. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, Setter, Acc_Level, get_as_ref_wrapper, set_as_ref_wrapper, Metadata_Count, Visitor_List>
  240. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  241. {
  242. using return_type = typename function_traits<Getter>::return_type;
  243. using arg_type = typename param_types<Setter, 0>::type;
  244. using class_type = typename function_traits<Getter>::class_type;
  245. public:
  246. property_wrapper(string_view name,
  247. Getter get, Setter set,
  248. std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  249. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  250. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  251. m_getter(get), m_setter(set)
  252. {
  253. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  254. static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-member-function with exactly one argument.");
  255. static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
  256. static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
  257. static_assert(std::is_reference<arg_type>::value, "Please provide a setter-member-function with a reference as return value!");
  258. init();
  259. }
  260. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  261. bool is_valid() const RTTR_NOEXCEPT { return true; }
  262. bool is_readonly() const RTTR_NOEXCEPT { return false; }
  263. bool is_static() const RTTR_NOEXCEPT { return false; }
  264. type get_type() const RTTR_NOEXCEPT { return type::get< std::reference_wrapper<remove_reference_t<return_type>> >(); }
  265. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  266. bool set_value(instance& object, argument& arg) const
  267. {
  268. using arg_type_t = remove_reference_t<arg_type>;
  269. class_type* ptr = object.try_convert<class_type>();
  270. if (ptr && arg.is_type<std::reference_wrapper<arg_type_t>>())
  271. {
  272. (ptr->*m_setter)(arg.get_value<std::reference_wrapper<arg_type_t>>().get());
  273. return true;
  274. }
  275. return false;
  276. }
  277. variant get_value(instance& object) const
  278. {
  279. if (class_type* ptr = object.try_convert<class_type>())
  280. return variant(std::ref((ptr->*m_getter)()));
  281. else
  282. return variant();
  283. }
  284. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  285. {
  286. auto obj = make_property_getter_setter_info<Declaring_Typ, get_as_ref_wrapper, Getter, Setter>(prop, m_getter, m_setter);
  287. visitor_iterator<Visitor_List>::visit(visitor, make_property_getter_setter_visitor_invoker(obj));
  288. }
  289. private:
  290. Getter m_getter;
  291. Setter m_setter;
  292. };
  293. /////////////////////////////////////////////////////////////////////////////////////////
  294. /////////////////////////////////////////////////////////////////////////////////////////
  295. // Getter - pointer to member function
  296. template<typename Declaring_Typ, typename Getter, access_levels Acc_Level, std::size_t Metadata_Count, typename Visitor_List>
  297. class property_wrapper<member_func_ptr, Declaring_Typ, Getter, void, Acc_Level, get_as_ref_wrapper, read_only, Metadata_Count, Visitor_List>
  298. : public property_wrapper_base, public metadata_handler<Metadata_Count>
  299. {
  300. using return_type = typename function_traits<Getter>::return_type;
  301. using class_type = typename function_traits<Getter>::class_type;
  302. using policy_type = std::reference_wrapper<add_const_t<remove_reference_t<return_type>>>;
  303. public:
  304. property_wrapper(string_view name,
  305. Getter get,
  306. std::array<metadata, Metadata_Count> metadata_list) RTTR_NOEXCEPT
  307. : property_wrapper_base(name, type::get<Declaring_Typ>()),
  308. metadata_handler<Metadata_Count>(std::move(metadata_list)),
  309. m_getter(get)
  310. {
  311. static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
  312. static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
  313. init();
  314. }
  315. access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; }
  316. bool is_valid() const RTTR_NOEXCEPT { return true; }
  317. bool is_readonly() const RTTR_NOEXCEPT { return true; }
  318. bool is_static() const RTTR_NOEXCEPT { return false; }
  319. type get_type() const RTTR_NOEXCEPT { return type::get<policy_type>(); }
  320. variant get_metadata(const variant& key) const { return metadata_handler<Metadata_Count>::get_metadata(key); }
  321. bool set_value(instance& object, argument& arg) const
  322. {
  323. return false;
  324. }
  325. variant get_value(instance& object) const
  326. {
  327. if (class_type* ptr = object.try_convert<class_type>())
  328. return variant(std::cref((ptr->*m_getter)()));
  329. else
  330. return variant();
  331. }
  332. void visit(visitor& visitor, property prop) const RTTR_NOEXCEPT
  333. {
  334. auto obj = make_property_info<Declaring_Typ, get_as_ref_wrapper, Getter>(prop, m_getter);
  335. visitor_iterator<Visitor_List>::visit(visitor, make_property_visitor_invoker<read_only>(obj));
  336. }
  337. private:
  338. Getter m_getter;
  339. };
  340. #endif // RTTR_PROPERTY_WRAPPER_MEMBER_FUNC_H_