policy.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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_POLICY_H_
  28. #define RTTR_POLICY_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/misc_type_traits.h"
  31. #include "rttr/detail/policies/ctor_policies.h"
  32. #include "rttr/detail/policies/meth_policies.h"
  33. #include "rttr/detail/policies/prop_policies.h"
  34. namespace rttr
  35. {
  36. /*!
  37. * The \ref policy class contains all policies that can be used during the registration of reflection information.
  38. *
  39. * For easier usage, the policies are subdivided into following groups:
  40. * - for methods: \ref policy::meth
  41. * - for properties: \ref policy::prop
  42. * - for constructors: \ref policy::ctor
  43. *
  44. */
  45. struct RTTR_API policy
  46. {
  47. /*!
  48. * The \ref meth class groups all policies that can be used during registration of methods.
  49. *
  50. * \endcode
  51. */
  52. struct RTTR_API meth
  53. {
  54. /*!
  55. * This policy can be used when a method return a reference to an object
  56. * and the caller should be able to access this object via the returned variant.
  57. * Reference cannot be copied directly in a variant, therefore it is possible transform the reference
  58. * to a pointer.
  59. *
  60. * See following example code:
  61. * \code{.cpp}
  62. *
  63. * std::string& get_text() { static std:string text("hello world"); return text; }
  64. *
  65. * RTTR_REGISTRATION
  66. * {
  67. * registration::method("get_text", &get_text)
  68. * (
  69. * policy::meth::return_ref_as_ptr
  70. * );
  71. * }
  72. * int main()
  73. * {
  74. * method meth = type::get_global_method("get_text");
  75. * std::cout << meth.get_return_type().get_name(); // prints "std::string*"
  76. * variant var = meth.invoke(instance());
  77. * std::cout << var.is_type<std::string*>(); // prints "true"
  78. * return 0;
  79. * }
  80. * \endcode
  81. */
  82. static const detail::return_as_ptr return_ref_as_ptr;
  83. /*!
  84. * This policy should be used when the return value of a method should not be forwarded to the caller.
  85. * For the caller it looks like the method has no return value, the return type will be *void*.
  86. *
  87. * See following example code:
  88. * \code{.cpp}
  89. *
  90. * using namespace rttr;
  91. * int my_func() { return 42; }
  92. *
  93. * RTTR_REGISTRATION
  94. * {
  95. * registration::method("my_func", &my_func)
  96. * (
  97. * policy::meth::discard_return
  98. * );
  99. * }
  100. *
  101. * int main()
  102. * {
  103. * method meth = type::get_global_method("my_func");
  104. * std::cout << meth.get_return_type().get_name(); // prints "void"
  105. * variant var = meth.invoke(instance());
  106. * std::cout << var.is_type<void>(); // prints "true"
  107. * return 0;
  108. * }
  109. * \endcode
  110. */
  111. static const detail::discard_return discard_return;
  112. };
  113. /*!
  114. * The \ref prop class groups all policies that can be used during registration of properties.
  115. *
  116. */
  117. struct RTTR_API prop
  118. {
  119. /*!
  120. * The \ref bind_as_ptr policy will bind a member object as *pointer* type.
  121. *
  122. * This can be useful when binding big data types, like arrays, to avoid copies during get/set of the property.
  123. *
  124. * See following example code:
  125. * \code{.cpp}
  126. * using namespace rttr;
  127. * struct Foo
  128. * {
  129. * std::vector<int> vec;
  130. * };
  131. *
  132. * RTTR_REGISTRATION
  133. * {
  134. * registration::class_<Foo>("Foo")
  135. * .property("vec", &Foo::vec)
  136. * (
  137. * policy::prop::bind_as_ptr
  138. * );
  139. * }
  140. *
  141. * int main()
  142. * {
  143. * Foo obj;
  144. * property prop = type::get<Foo>().get_property("vec");
  145. * variant var = prop.get_value(obj);
  146. * std::cout << var.is_type<std::vector<int>*>(); // prints "true"
  147. * prop.set_value(obj, var); // not really necessary, but remark that now a std::vector<int>* is expected
  148. * return 0;
  149. * }
  150. * \endcode
  151. */
  152. static const detail::bind_as_ptr bind_as_ptr;
  153. /*!
  154. * The \ref as_reference_wrapper policy will bind a member object as *std::reference_wrapper* type.
  155. *
  156. * This can be useful when binding big data types, like arrays, to avoid copies during get/set of the property.
  157. *
  158. * See following example code:
  159. * \code{.cpp}
  160. * using namespace rttr;
  161. * struct Foo
  162. * {
  163. * std::vector<int> vec;
  164. * };
  165. *
  166. * RTTR_REGISTRATION
  167. * {
  168. * registration::class_<Foo>("Foo")
  169. * .property("vec", &Foo::vec)
  170. * (
  171. * policy::prop::as_reference_wrapper
  172. * );
  173. * }
  174. *
  175. * int main()
  176. * {
  177. * Foo obj;
  178. * property prop = type::get<Foo>().get_property("vec");
  179. * variant var = prop.get_value(obj);
  180. * std::cout << var.is_type<std::reference_wrapper<std::vector<int>>>(); // prints "true"
  181. * prop.set_value(obj, var); // not really necessary, but remark that now a std::reference_wrapper<std::vector<int>> is expected
  182. * return 0;
  183. * }
  184. * \endcode
  185. */
  186. static const detail::as_reference_wrapper as_reference_wrapper;
  187. };
  188. /*!
  189. * The \ref ctor class groups all policies that can be used during registration of constructors.
  190. *
  191. */
  192. struct RTTR_API ctor
  193. {
  194. /*!
  195. * The \ref as_raw_ptr policy will create an instance of a class as raw pointer.
  196. *
  197. * That means the object is created with a *new*-expression and its lifetime lasts
  198. * until it is destroyed using a *delete*-expression.
  199. * In order to invoke the delete expression use the corresponding \ref destructor.
  200. *
  201. * See following example code:
  202. * \code{.cpp}
  203. * using namespace rttr;
  204. * struct Foo
  205. * {
  206. * };
  207. *
  208. * RTTR_REGISTRATION
  209. * {
  210. * registration::class_<Foo>("Foo")
  211. * .constructor<>()
  212. * (
  213. * policy::ctor::as_raw_ptr
  214. * );
  215. * }
  216. *
  217. * int main()
  218. * {
  219. * variant var = type::get<Foo>().create();
  220. * std::cout << var.is_type<Foo*>(); // prints "true"
  221. * var.get_type().destroy(var); // free's the memory with 'delete'
  222. * std::cout << var.is_valid(); // prints "false"
  223. * return 0;
  224. * }
  225. * \endcode
  226. */
  227. static const detail::as_raw_pointer as_raw_ptr;
  228. /*!
  229. * The \ref as_std_shared_ptr policy will create an instance of a class through *std::make_shared<T>*.
  230. *
  231. * That means the object is \ref type::is_wrapper() "wrapped" into a *std::shared_ptr<T>*.
  232. * The wrapped object is destroyed and its memory deallocated when either of the following happens:
  233. * - the last remaining variant owning the *shared_ptr* is destroyed
  234. * - the last remaining variant owning the *shared_ptr* is assigned another data or variant
  235. *
  236. * The object is destroyed using the default deleter of *std::shared_ptr*.
  237. *
  238. * See following example code:
  239. * \code{.cpp}
  240. * using namespace rttr;
  241. * struct Foo
  242. * {
  243. * };
  244. *
  245. * RTTR_REGISTRATION
  246. * {
  247. * registration::class_<Foo>("Foo")
  248. * .constructor<>()
  249. * (
  250. * policy::ctor::as_std_shared_ptr
  251. * );
  252. * }
  253. *
  254. * int main()
  255. * {
  256. * variant var = type::get<Foo>().create();
  257. * std::cout << var.is_type<std::shared_ptr<Foo>>(); // prints "true"
  258. * return 0; // the memory for contained 'Foo' instance is freed automatically,
  259. * } // because the var object is gone out of scope
  260. * \endcode
  261. */
  262. static const detail::as_std_shared_ptr as_std_shared_ptr;
  263. /*!
  264. * The \ref as_object policy will create an instance of a class with automatic storage.
  265. *
  266. * Objects with automatic storage duration are automatically destroyed when the block in which they are created exits.
  267. * Which is in our case the \ref variant.
  268. * However, that means also you don't have to deal with pointers or wrappers. In order to use this creation policy,
  269. * the object must be *copy constructible*.
  270. *
  271. * See following example code:
  272. * \code{.cpp}
  273. * using namespace rttr;
  274. * struct Foo
  275. * {
  276. * };
  277. *
  278. * RTTR_REGISTRATION
  279. * {
  280. * registration::class_<Foo>("Foo")
  281. * .constructor<>()
  282. * (
  283. * policy::ctor::as_object
  284. * );
  285. * }
  286. *
  287. * int main()
  288. * {
  289. * variant var = type::get<Foo>().create(); // creates a new instance of 'Foo' and moves the content into variant 'var'
  290. * std::cout << var.is_type<Foo>(); // prints "true"
  291. * variant var2 = var; // creates a new instance of 'Foo', through copy construction
  292. * return 0; // the memory of the two 'Foo' instances is freed automatically
  293. * }
  294. * \endcode
  295. */
  296. static const detail::as_object as_object;
  297. };
  298. };
  299. } // end namespace rttr
  300. #endif // RTTR_POLICY_H_