property_wrapper_func.h 18 KB

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