/************************************************************************************ * * * Copyright (c) 2014 - 2018 Axel Menzel * * * * This file is part of RTTR (Run Time Type Reflection) * * License: MIT License * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * * SOFTWARE. * * * *************************************************************************************/ #ifndef RTTR_METHOD_WRAPPER_H_ #define RTTR_METHOD_WRAPPER_H_ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/detail/method/method_wrapper_base.h" #include "rttr/detail/misc/function_traits.h" #include "rttr/detail/type/accessor_type.h" #include "rttr/detail/method/method_accessor.h" #include "rttr/detail/default_arguments/default_arguments.h" #include "rttr/detail/default_arguments/invoke_with_defaults.h" #include "rttr/detail/parameter_info/parameter_infos.h" #include "rttr/argument.h" #include "rttr/instance.h" #include "rttr/variant.h" #include "rttr/array_range.h" #include "rttr/detail/visitor/visitor_iterator.h" #include "rttr/detail/visitor/method_visitor_invoker.h" #include #include #include namespace rttr { namespace detail { template class method_wrapper; ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template class method_wrapper, parameter_infos, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler { public: method_wrapper(string_view name, F func_acc, std::array metadata_list, parameter_infos param_infos) RTTR_NOEXCEPT : method_wrapper_base(name, type::get()), metadata_handler(std::move(metadata_list)), m_func_acc(func_acc), m_param_infos(std::move(param_infos)), m_param_info_list(create_paramter_info_array(m_param_infos)) { init(); } bool is_valid() const RTTR_NOEXCEPT { return true; } bool is_static() const RTTR_NOEXCEPT { return method_accessor::is_static(); } type get_return_type() const RTTR_NOEXCEPT { return method_accessor::get_return_type(); } std::vector get_is_reference() const RTTR_NOEXCEPT { return method_accessor::get_is_reference(); } std::vector get_is_const() const RTTR_NOEXCEPT { return method_accessor::get_is_const(); } access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; } array_range get_parameter_infos() const RTTR_NOEXCEPT { return array_range(const_cast(m_param_info_list).data(), m_param_info_list.size()); } variant get_metadata(const variant& key) const { return metadata_handler::get_metadata(key); } variant invoke(instance& object) const { return method_accessor::invoke(m_func_acc, object); } variant invoke(instance& object, argument& arg1) const { return method_accessor::invoke(m_func_acc, object, arg1); } variant invoke(instance& object, argument& arg1, argument& arg2) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5, arg6); } variant invoke_variadic(const instance& object, std::vector& args) const { return method_accessor::invoke_variadic(m_func_acc, object, args); } void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT { auto obj = make_method_info(meth, m_func_acc); visitor_iterator::visit(visitor, make_method_visitor_invoker(obj)); } private: F m_func_acc; parameter_infos m_param_infos; std::array m_param_info_list; }; ///////////////////////////////////////////////////////////////////////////////////////// template class method_wrapper, parameter_infos, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler { using method_type = typename detail::method_type::type; using arg_index_sequence = make_index_sequence::arg_count>; using invoker_class = method_invoker; using invoke_with_defaults = invoke_defaults_helper; public: method_wrapper(string_view name, F func_acc, std::array metadata_list, default_args default_args, parameter_infos param_infos) RTTR_NOEXCEPT : method_wrapper_base(name, type::get()), metadata_handler(std::move(metadata_list)), m_func_acc(func_acc), m_def_args(std::move(default_args)), m_param_infos(std::move(param_infos)), m_param_info_list(create_paramter_info_array(m_param_infos)) { store_default_args_in_param_infos(m_param_infos, m_def_args); init(); } bool is_valid() const RTTR_NOEXCEPT { return true; } bool is_static() const RTTR_NOEXCEPT { return method_accessor::is_static(); } type get_return_type() const RTTR_NOEXCEPT { return method_accessor::get_return_type(); } std::vector get_is_reference() const RTTR_NOEXCEPT { return method_accessor::get_is_reference(); } std::vector get_is_const() const RTTR_NOEXCEPT { return method_accessor::get_is_const(); } access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; } array_range get_parameter_infos() const RTTR_NOEXCEPT { return array_range(const_cast(m_param_info_list).data(), m_param_info_list.size()); } variant get_metadata(const variant& key) const { return metadata_handler::get_metadata(key); } variant invoke(instance& object) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args); } variant invoke(instance& object, argument& arg1) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1); } variant invoke(instance& object, argument& arg1, argument& arg2) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5, arg6); } variant invoke_variadic(const instance& object, std::vector& args) const { if (args.size() <= function_traits::arg_count) return invoke_variadic_helper::invoke(args, m_func_acc, object, m_def_args.m_args); else return variant(); } void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT { auto obj = make_method_info(meth, m_func_acc); visitor_iterator::visit(visitor, make_method_visitor_invoker(obj)); } private: F m_func_acc; default_args m_def_args; parameter_infos m_param_infos; std::array m_param_info_list; }; ///////////////////////////////////////////////////////////////////////////////////////// template class method_wrapper, parameter_infos<>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler { public: method_wrapper(string_view name, F func_acc, std::array metadata_list, parameter_infos<> param_infos) RTTR_NOEXCEPT : method_wrapper_base(name, type::get()), metadata_handler(std::move(metadata_list)), m_func_acc(func_acc) { init(); } bool is_valid() const RTTR_NOEXCEPT { return true; } bool is_static() const RTTR_NOEXCEPT { return method_accessor::is_static(); } type get_return_type() const RTTR_NOEXCEPT { return method_accessor::get_return_type(); } std::vector get_is_reference() const RTTR_NOEXCEPT { return method_accessor::get_is_reference(); } std::vector get_is_const() const RTTR_NOEXCEPT { return method_accessor::get_is_const(); } access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; } array_range get_parameter_infos() const RTTR_NOEXCEPT { return array_range(); } variant get_metadata(const variant& key) const { return metadata_handler::get_metadata(key); } variant invoke(instance& object) const { return method_accessor::invoke(m_func_acc, object); } variant invoke(instance& object, argument& arg1) const { return method_accessor::invoke(m_func_acc, object, arg1); } variant invoke(instance& object, argument& arg1, argument& arg2) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const { return method_accessor::invoke(m_func_acc, object, arg1, arg2, arg3, arg4, arg5, arg6); } variant invoke_variadic(const instance& object, std::vector& args) const { return method_accessor::invoke_variadic(m_func_acc, object, args); } void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT { auto obj = make_method_info(meth, m_func_acc); visitor_iterator::visit(visitor, make_method_visitor_invoker(obj)); } private: F m_func_acc; }; ///////////////////////////////////////////////////////////////////////////////////////// template class method_wrapper, parameter_infos<>, Metadata_Count, Visitor_List> : public method_wrapper_base, public metadata_handler { using method_type = typename detail::method_type::type; using arg_index_sequence = make_index_sequence::arg_count>; using invoker_class = method_invoker; using invoke_with_defaults = invoke_defaults_helper; public: method_wrapper(string_view name, F func_acc, std::array metadata_list, default_args default_args, parameter_infos<> param_infos) : method_wrapper_base(name, type::get()), metadata_handler(std::move(metadata_list)), m_func_acc(func_acc), m_def_args(std::move(default_args)) { init(); } bool is_valid() const RTTR_NOEXCEPT { return true; } bool is_static() const RTTR_NOEXCEPT { return method_accessor::is_static(); } type get_return_type() const RTTR_NOEXCEPT { return method_accessor::get_return_type(); } std::vector get_is_reference() const RTTR_NOEXCEPT { return method_accessor::get_is_reference(); } std::vector get_is_const() const RTTR_NOEXCEPT { return method_accessor::get_is_const(); } access_levels get_access_level() const RTTR_NOEXCEPT { return Acc_Level; } array_range get_parameter_infos() const RTTR_NOEXCEPT { return array_range(); } variant get_metadata(const variant& key) const { return metadata_handler::get_metadata(key); } variant invoke(instance& object) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args); } variant invoke(instance& object, argument& arg1) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1); } variant invoke(instance& object, argument& arg1, argument& arg2) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5); } variant invoke(instance& object, argument& arg1, argument& arg2, argument& arg3, argument& arg4, argument& arg5, argument& arg6) const { return invoke_with_defaults::invoke(m_func_acc, object, m_def_args.m_args, arg1, arg2, arg3, arg4, arg5, arg6); } variant invoke_variadic(const instance& object, std::vector& args) const { if (args.size() <= function_traits::arg_count) return invoke_variadic_helper::invoke(args, m_func_acc, object, m_def_args.m_args); else return variant(); } void visit(visitor& visitor, method meth) const RTTR_NOEXCEPT { auto obj = make_method_info(meth, m_func_acc); visitor_iterator::visit(visitor, make_method_visitor_invoker(obj)); } private: F m_func_acc; default_args m_def_args; }; ///////////////////////////////////////////////////////////////////////////////////////// } // end namespace detail } // end namespace rttr #endif // RTTR_METHOD_WRAPPER_H_