method_accessor.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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_ACCESSOR_H_
  28. #define RTTR_METHOD_ACCESSOR_H_
  29. #include "rttr/detail/misc/function_traits.h"
  30. #include "rttr/detail/misc/utility.h"
  31. #include "rttr/detail/method/method_invoker.h"
  32. namespace rttr
  33. {
  34. namespace detail
  35. {
  36. /////////////////////////////////////////////////////////////////////////////////////////
  37. template<typename F, typename IndexSequence, typename B>
  38. struct method_accessor_impl;
  39. template<typename F, std::size_t... ArgCount>
  40. struct method_accessor_impl<F, index_sequence<ArgCount...>, std::true_type>
  41. {
  42. static std::vector<bool> get_is_reference() RTTR_NOEXCEPT
  43. {
  44. return { std::is_reference<typename param_types<F, ArgCount>::type>::value... };
  45. }
  46. static std::vector<bool> get_is_const() RTTR_NOEXCEPT
  47. {
  48. return { std::is_const<typename std::remove_reference<typename param_types<F, ArgCount>::type>::type>::value... };
  49. }
  50. };
  51. /////////////////////////////////////////////////////////////////////////////////////////
  52. template<typename F, std::size_t... ArgCount>
  53. struct method_accessor_impl<F, index_sequence<ArgCount...>, std::false_type>
  54. {
  55. static std::vector<bool> get_is_reference() RTTR_NOEXCEPT
  56. {
  57. return std::vector<bool>();
  58. }
  59. static std::vector<bool> get_is_const() RTTR_NOEXCEPT
  60. {
  61. return std::vector<bool>();
  62. }
  63. };
  64. /////////////////////////////////////////////////////////////////////////////////////////
  65. template<typename MethodType>
  66. struct method_accessor_helper_is_static
  67. {
  68. static bool is_static() RTTR_NOEXCEPT { return true; }
  69. };
  70. template<>
  71. struct method_accessor_helper_is_static<return_member_func>
  72. {
  73. static bool is_static() RTTR_NOEXCEPT { return false; }
  74. };
  75. template<>
  76. struct method_accessor_helper_is_static<void_member_func>
  77. {
  78. static bool is_static() RTTR_NOEXCEPT { return false; }
  79. };
  80. /////////////////////////////////////////////////////////////////////////////////////////
  81. template<typename F, typename Policy>
  82. struct method_accessor_helper_return_type
  83. {
  84. static type get_return_type() RTTR_NOEXCEPT { return type::get<typename function_traits<F>::return_type>(); }
  85. };
  86. template<typename F>
  87. struct method_accessor_helper_return_type<F, return_as_ptr>
  88. {
  89. using return_type = typename function_traits<F>::return_type;
  90. static type get_return_type() RTTR_NOEXCEPT { return type::get<typename std::remove_reference<return_type>::type*>(); }
  91. };
  92. template<typename F>
  93. struct method_accessor_helper_return_type<F, discard_return>
  94. {
  95. static type get_return_type() RTTR_NOEXCEPT { return type::get<void>(); }
  96. };
  97. /////////////////////////////////////////////////////////////////////////////////////////
  98. // this is a workaround because MSVC2013 cannot handle sizeof...(T) with enable_if
  99. template<typename F, typename...TArgs>
  100. struct does_argument_count_match : std::integral_constant<bool, (sizeof...(TArgs) == function_traits<F>::arg_count)>
  101. {
  102. };
  103. /////////////////////////////////////////////////////////////////////////////////////////
  104. template<typename F, typename Policy>
  105. struct method_accessor
  106. {
  107. static RTTR_CONSTEXPR_OR_CONST std::size_t arg_count = function_traits<F>::arg_count;
  108. using method_type = typename detail::method_type<F>::type;
  109. using arg_index_sequence = make_index_sequence< arg_count >;
  110. using invoker_class = method_invoker<F, Policy, method_type, arg_index_sequence>;
  111. static bool is_static() RTTR_NOEXCEPT
  112. {
  113. using method_type = typename detail::method_type<F>::type;
  114. return method_accessor_helper_is_static<method_type>::is_static();
  115. }
  116. /////////////////////////////////////////////////////////////////////////////////////
  117. static type get_return_type() RTTR_NOEXCEPT
  118. {
  119. return method_accessor_helper_return_type<F, Policy>::get_return_type();
  120. }
  121. /////////////////////////////////////////////////////////////////////////////////////
  122. static std::vector<bool> get_is_reference() RTTR_NOEXCEPT
  123. {
  124. using has_arguments = typename std::integral_constant<bool, arg_count != 0>::type;
  125. return method_accessor_impl<F, make_index_sequence<arg_count>, has_arguments>::get_is_reference();
  126. }
  127. /////////////////////////////////////////////////////////////////////////////////////
  128. static std::vector<bool> get_is_const() RTTR_NOEXCEPT
  129. {
  130. using has_arguments = typename std::integral_constant<bool, arg_count != 0>::type;
  131. return method_accessor_impl<F, make_index_sequence<arg_count>, has_arguments>::get_is_const();
  132. }
  133. /////////////////////////////////////////////////////////////////////////////////////
  134. template<typename... TArgs>
  135. static RTTR_INLINE
  136. enable_if_t< does_argument_count_match<F, TArgs...>::value, variant>
  137. invoke(const F& func_ptr, const instance& obj, const TArgs&...args)
  138. {
  139. return invoker_class::invoke(func_ptr, obj, args...);
  140. }
  141. /////////////////////////////////////////////////////////////////////////////////////
  142. template<typename... TArgs>
  143. static RTTR_INLINE
  144. enable_if_t< !does_argument_count_match<F, TArgs...>::value, variant>
  145. invoke(const F& func_ptr, const instance& obj, const TArgs&...args)
  146. {
  147. return variant();
  148. }
  149. /////////////////////////////////////////////////////////////////////////////////////
  150. template<std::size_t... Arg_Idx>
  151. static RTTR_INLINE variant invoke_variadic_impl(const F& func_ptr, const instance& obj, index_sequence<Arg_Idx...>, const std::vector<argument>& arg_list)
  152. {
  153. return invoker_class::invoke(func_ptr, obj, arg_list[Arg_Idx]...);
  154. }
  155. /////////////////////////////////////////////////////////////////////////////////////
  156. static RTTR_INLINE variant invoke_variadic(const F& func_ptr, const instance& obj, const std::vector<argument>& arg_list)
  157. {
  158. if (arg_list.size() == arg_count)
  159. return invoke_variadic_impl(func_ptr, obj, make_index_sequence<arg_count>(), arg_list);
  160. else
  161. return variant();
  162. }
  163. };
  164. /////////////////////////////////////////////////////////////////////////////////////////
  165. } // end namespace detail
  166. } // end namespace rttr
  167. #endif // RTTR_METHOD_ACCESSOR_H_