property_wrapper_member_object.h 17 KB

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