method.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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_H_
  28. #define RTTR_METHOD_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/class_item_mapper.h"
  31. #include "rttr/parameter_info.h"
  32. #include "rttr/access_levels.h"
  33. #include "rttr/array_range.h"
  34. #include "rttr/string_view.h"
  35. #include <string>
  36. #include <vector>
  37. namespace rttr
  38. {
  39. class variant;
  40. class type;
  41. class instance;
  42. class argument;
  43. class method;
  44. class visitor;
  45. namespace detail
  46. {
  47. class method_wrapper_base;
  48. }
  49. /*!
  50. * The \ref method class provides several meta information about a method and can be invoked.
  51. *
  52. * A instance of a method class can only be obtained from the \ref type class.
  53. * See \ref type::get_method() and \ref type::get_methods().
  54. *
  55. * For registration a method, nested inside a class, see \ref registration::class_<T>::method()
  56. * and for global methods see \ref registration::method().
  57. *
  58. * Meta Information
  59. * ----------------
  60. * A \ref method has a \ref get_name "name", a \ref get_signature "signature", a \ref get_return_type "return type", a list of \ref get_parameter_infos "parameter information"
  61. * as well as attributes that specify its behavior: \ref is_static().
  62. * When the \ref method was declared inside a class, then \ref get_declaring_type() can be used to obtain the type of this class.
  63. *
  64. * The method can be invoked with \ref invoke(); When its not a \ref is_static "static method" you have to provide a valid class instance to invoke the method.
  65. * This instance can be the raw type on the stack; the current class hierarchy level doesn't matter. It can be also a raw pointer to the object or
  66. * a \ref variant which contains the instance, again as pointer or stack object.
  67. * When the method is declared as static you you still have to provide an empty instance object,
  68. * use therefore the default ctor of \ref instance::instance() "instance()", or as shortcut use simply `{}`.
  69. *
  70. * A method will be successfully invoked when the provided instance can be converted to the \ref get_declaring_type() "declared class" type.
  71. * When the method has \ref get_parameter_infos "parameters" defined, then the same number of arguments must be provided and the type itself must **100% match** the type of the registered function.
  72. * An automatically type conversion is **not** performed.
  73. *
  74. * The return type of \ref invoke() is \ef variant object.
  75. * This object contains not only the possible return value of a function, it also indicates whether the method was invoked or not.
  76. * A \ref variant::is_valid "valid" variant object means, that then the method was successfully invoked, otherwise not.
  77. * When the invoked method has no return type, i.e. is a `void` method, then a valid variant of type `void` is returned.
  78. *
  79. * While the \ref invoke() function can directly forward up to six arguments, it is sometime necessary to forward even more arguments.
  80. * Therefore the function \ref invoke_variadic() should be used; it allows to pack an unlimited amount of arguments into a std::vector and forward them to the function.
  81. *
  82. * Another way to invoke a method is to use the \ref type class through \ref type::invoke().
  83. *
  84. * Copying and Assignment
  85. * ----------------------
  86. * A \ref method object is lightweight and can be copied by value. However, each copy will refer to the same underlying method.
  87. *
  88. * Typical Usage
  89. * ----------------------
  90. *
  91. * \code{.cpp}
  92. * using namespace rttr;
  93. * struct MyStruct { int my_method(int param) { return param; } };
  94. * //...
  95. * variant obj = type::get_by_name("MyStruct").create({});
  96. * method func = obj.get_type().get_method("my_method");
  97. * if (func)
  98. * {
  99. * variant val = func.invoke(obj, 23);
  100. * std::cout << val.get_value<int>(); // prints 23
  101. * // you can also invoke the method with an object on the stack
  102. * MyStruct inst;
  103. * val = func.invoke(inst, 42);
  104. * std::cout << val.get_value<int>(); // prints 42
  105. * // or as pointer
  106. * MyStruct* ptr = &inst;
  107. * val = func.invoke(ptr, 7);
  108. * std::cout << val.get_value<int>(); // prints 7
  109. * }
  110. * \endcode
  111. *
  112. * \see property, enumeration, constructor and type
  113. */
  114. class RTTR_API method
  115. {
  116. public:
  117. /*!
  118. * \brief Returns true if this method is valid, otherwise false.
  119. *
  120. * \return True if this method is valid, otherwise false.
  121. */
  122. bool is_valid() const RTTR_NOEXCEPT;
  123. /*!
  124. * \brief Convenience function to check if this method is valid or not.
  125. *
  126. * \return True if this method is valid, otherwise false.
  127. */
  128. explicit operator bool() const RTTR_NOEXCEPT;
  129. /*!
  130. * \brief Returns the name of this method.
  131. *
  132. * \return Name of the method.
  133. */
  134. string_view get_name() const RTTR_NOEXCEPT;
  135. /*!
  136. * \brief Returns the access level with which this method was
  137. * \ref registration::class_<T>::method() "registered".
  138. *
  139. * \remark When the method is not valid, this function will return level \ref access_levels::public_access.
  140. *
  141. * \return \ref access_levels of the method.
  142. */
  143. access_levels get_access_level() const RTTR_NOEXCEPT;
  144. /*!
  145. * \brief Returns true if this method is static method, otherwise false.
  146. * A static method does not need an instance for performing an invoke.
  147. *
  148. * \remark When the method is not valid, this function will return false.
  149. *
  150. * \return True if this is a static method, otherwise false.
  151. */
  152. bool is_static() const RTTR_NOEXCEPT;
  153. /*!
  154. * Returns the type object of the return type.
  155. *
  156. * \return The type of the return type.
  157. */
  158. type get_return_type() const RTTR_NOEXCEPT;
  159. /*!
  160. * Returns the class that declares this method.
  161. *
  162. * \remark When this method does not belong to a class (i.e. is a global method) it will return an invalid type.
  163. * When this method is not valid, this function will return an invalid type object (see \ref type::is_valid).
  164. *
  165. * \return \ref type "Type" of the declaring class/struct for this method.
  166. */
  167. type get_declaring_type() const RTTR_NOEXCEPT;
  168. /*!
  169. * \brief Returns an ordered range of \ref parameter_info objects, which matches the signature of the method.
  170. *
  171. * \return A range of parameter_info objects of the method signature.
  172. */
  173. array_range<parameter_info> get_parameter_infos() const RTTR_NOEXCEPT;
  174. /*!
  175. * \brief Returns the signature of this method as readable string.
  176. *
  177. * \return The signature as readable string.
  178. */
  179. string_view get_signature() const RTTR_NOEXCEPT;
  180. /*!
  181. * \brief Returns the meta data for the given key \p key.
  182. *
  183. * \remark When no meta data is registered with the given \p key,
  184. * an invalid \ref variant object is returned (see \ref variant::is_valid).
  185. *
  186. * \return A variant object, containing arbitrary data.
  187. */
  188. variant get_metadata(const variant& key) const;
  189. /*!
  190. * \brief Invokes the method represented by the current instance \p object.
  191. *
  192. * \remark When it's a static method you still need to provide an instance object, use therefore the default ctor of \ref instance::instance() "instance()".
  193. *
  194. * \see get_parameter_infos()
  195. *
  196. * \return The possible return value of the method.
  197. */
  198. variant invoke(instance object) const;
  199. /*!
  200. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  201. *
  202. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  203. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  204. * will be returned.
  205. * When it's a static method you still need to provide an instance object,
  206. * use therefore the default ctor of \ref instance::instance() "instance()".
  207. *
  208. * \return The possible return value of the method.
  209. *
  210. * \see get_parameter_infos()
  211. */
  212. variant invoke(instance object, argument arg1) const;
  213. /*!
  214. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  215. *
  216. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  217. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  218. * will be returned.
  219. * When it's a static method you still need to provide an instance object,
  220. * use therefore the default ctor of \ref instance::instance() "instance()".
  221. *
  222. * \see get_parameter_infos()
  223. *
  224. * \return The possible return value of the method.
  225. */
  226. variant invoke(instance object, argument arg1, argument arg2) const;
  227. /*!
  228. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  229. *
  230. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  231. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  232. * will be returned.
  233. * When it's a static method you still need to provide an instance object,
  234. * use therefore the default ctor of \ref instance::instance() "instance()".
  235. *
  236. * \see get_parameter_infos()
  237. *
  238. * \return The possible return value of the method.
  239. */
  240. variant invoke(instance object, argument arg1, argument arg2, argument arg3) const;
  241. /*!
  242. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  243. *
  244. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  245. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  246. * will be returned.
  247. * When it's a static method you still need to provide an instance object,
  248. * use therefore the default ctor of \ref instance::instance() "instance()".
  249. *
  250. * \see get_parameter_infos()
  251. *
  252. * \return The possible return value of the method.
  253. */
  254. variant invoke(instance object, argument arg1, argument arg2, argument arg3, argument arg4) const;
  255. /*!
  256. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  257. *
  258. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  259. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  260. * will be returned.
  261. * When it's a static method you still need to provide an instance object,
  262. * use therefore the default ctor of \ref instance::instance() "instance()".
  263. *
  264. * \see get_parameter_infos()
  265. *
  266. * \return The possible return value of the method.
  267. */
  268. variant invoke(instance object, argument arg1, argument arg2, argument arg3, argument arg4,
  269. argument arg5) const;
  270. /*!
  271. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  272. *
  273. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  274. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  275. * will be returned.
  276. * When it's a static method you still need to provide an instance object,
  277. * use therefore the default ctor of \ref instance::instance() "instance()".
  278. *
  279. * \see get_parameter_infos()
  280. *
  281. * \return The possible return value of the method.
  282. */
  283. variant invoke(instance object, argument arg1, argument arg2, argument arg3, argument arg4,
  284. argument arg5, argument arg6) const;
  285. /*!
  286. * \brief Invokes the method represented by the current instance \p object, using the specified parameters.
  287. * Use this method when the argument count is higher then six.
  288. *
  289. * \remark The given argument type has to match **exactly** the type of the underling method parameter,
  290. * otherwise the method cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid)
  291. * will be returned.
  292. * When it's a static method you still need to provide an instance object,
  293. * use therefore the default ctor of \ref instance::instance() "instance()".
  294. * Using this invoke function is slower, then specifying the arguments directly.
  295. *
  296. * \see get_parameter_infos()
  297. *
  298. * \return The possible return value of the method.
  299. */
  300. variant invoke_variadic(instance object, std::vector<argument> args) const;
  301. /*!
  302. * \brief Returns true if this method is the same like the \p other.
  303. *
  304. * \return True if both methods are equal, otherwise false.
  305. */
  306. bool operator==(const method& other) const RTTR_NOEXCEPT;
  307. /*!
  308. * Returns true if this method is the not the same like the \p other.
  309. *
  310. * \return True if both methods are different, otherwise false.
  311. */
  312. bool operator!=(const method& other) const RTTR_NOEXCEPT;
  313. private:
  314. method(const detail::method_wrapper_base* wrapper) RTTR_NOEXCEPT;
  315. void visit(visitor& visitor) const RTTR_NOEXCEPT;
  316. template<typename T>
  317. friend T detail::create_item(const detail::class_item_to_wrapper_t<T>* wrapper);
  318. template<typename T>
  319. friend T detail::create_invalid_item();
  320. friend class visitor;
  321. private:
  322. const detail::method_wrapper_base* m_wrapper;
  323. };
  324. } // end namespace rttr
  325. #endif // RTTR_METHOD_H_