/************************************************************************************ * * * 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_REGISTRATION_IMPL_H_ #define RTTR_REGISTRATION_IMPL_H_ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/detail/misc/argument_extractor.h" #include "rttr/detail/constructor/constructor_wrapper.h" #include "rttr/detail/constructor/constructor_wrapper_defaults.h" #include "rttr/detail/destructor/destructor_wrapper.h" #include "rttr/detail/enumeration/enumeration_wrapper.h" #include "rttr/detail/method/method_wrapper.h" #include "rttr/detail/property/property_wrapper.h" #include "rttr/detail/type/accessor_type.h" #include "rttr/detail/misc/misc_type_traits.h" #include "rttr/detail/misc/utility.h" #include "rttr/detail/type/type_register.h" #include "rttr/detail/registration/bind_impl.h" #include "rttr/detail/registration/registration_state_saver.h" #include "rttr/policy.h" #include "rttr/enumeration.h" #include "rttr/detail/visitor/create_type_visitor_func.h" #include #include namespace rttr { ///////////////////////////////////////////////////////////////////////////////////////// RTTR_INLINE detail::metadata metadata(variant key, variant value) { return detail::metadata{std::move(key), std::move(value)}; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE detail::enum_data value(string_view name, Enum_Type value) { return detail::enum_data(name, value); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE detail::default_args default_arguments(TArgs&&...args) { static_assert((sizeof...(TArgs) > 0), "Please provide at least one default argument!"); return { std::forward(args)... }; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE detail::parameter_names...> parameter_names(TArgs&&...args) { using namespace detail; static_assert(static_all_of>::value...>::value, "Please use this function only with string literals!"); return { static_cast>(std::forward(args))...}; } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template registration::class_::class_(string_view name) { auto t = type::get(); detail::type_register::custom_name(t, name); detail::type_register::register_visit_type_func(t, &detail::visit_type); } ///////////////////////////////////////////////////////////////////////////////////////// template registration::class_::class_(const std::shared_ptr& reg_exec) : m_reg_exec(reg_exec) { } ///////////////////////////////////////////////////////////////////////////////////////// template registration::class_::~class_() { // make sure that all base classes are registered detail::base_classes::get_types(); } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::class_& registration::class_::operator()(Args&&...args) { detail::type_register::metadata(type::get(), detail::forward_to_vector(std::forward(args)...)); return *this; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::constructor(acc_level level) { return {create_if_empty(m_reg_exec)}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::constructor(F func, acc_level level) { using namespace detail; static_assert(is_functor::value, "No valid accessor for invoking the constructor provided!"); static_assert(std::is_same::type>::value, "For creating this 'class type', please provide a function pointer or std::function with a return value."); return {create_if_empty(m_reg_exec), func}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::property(string_view name, A acc, acc_level level) { using namespace detail; static_assert(contains::value, "The given type of 'level' is not a type of 'rttr::access_levels.'"); static_assert(std::is_member_object_pointer::value || std::is_pointer::value, "No valid property accessor provided!"); return {create_if_empty(m_reg_exec), name, acc}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::property_readonly(string_view name, A acc, acc_level level) { using namespace detail; static_assert(contains::value, "The given type of 'level' is not a type of 'rttr::access_levels.'"); static_assert(std::is_pointer::value || std::is_member_object_pointer::value || std::is_member_function_pointer::value || is_functor::value, "No valid property accessor provided!"); return {create_if_empty(m_reg_exec), name, acc}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::property(string_view name, A1 getter, A2 setter, acc_level level) { using namespace detail; static_assert(contains::value, "The given type of 'level' is not a type of 'rttr::access_levels.'"); static_assert(std::is_member_function_pointer::value || std::is_member_function_pointer::value || is_functor::value || is_functor::value, "No valid property accessor provided!"); static_assert(function_traits::arg_count == 0, "Invalid number of arguments, please provide as first accessor a getter-member-function without arguments."); static_assert(function_traits::arg_count == 1, "Invalid number of arguments, please provide as second argument a setter-member-function with exactly one argument."); using return_type = typename function_traits::return_type; using arg_type = typename param_types::type; static_assert(std::is_same::value, "Please provide the same signature (data type) for getter and setter!"); return {create_if_empty(m_reg_exec), name, getter, setter}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::method(string_view name, F f, acc_level level) { using namespace detail; static_assert(contains::value, "The given type of 'level' is not a type of 'rttr::access_levels.'"); static_assert(std::is_member_function_pointer::value || is_functor::value, "No valid method accessor provided!"); return {create_if_empty(m_reg_exec), name, f}; } ///////////////////////////////////////////////////////////////////////////////////////// template template registration::bind registration::class_::enumeration(string_view name) { using namespace detail; static_assert(std::is_enum::value, "No enum type provided, please call this method with an enum type!"); return {create_if_empty(m_reg_exec), name}; } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template registration::bind registration::property(string_view name, A acc) { using namespace detail; static_assert(std::is_pointer::value, "No valid property accessor provided!"); return {std::make_shared(), name, acc}; } ///////////////////////////////////////////////////////////////////////////////////////// template registration::bind registration::property_readonly(string_view name, A acc) { using namespace detail; static_assert(std::is_pointer::value || is_functor::value, "No valid property accessor provided!"); return {std::make_shared(), name, acc}; } ///////////////////////////////////////////////////////////////////////////////////////// template registration::bind registration::property(string_view name, A1 getter, A2 setter) { using namespace detail; static_assert(is_functor::value || is_functor::value, "No valid property accessor provided!"); return {std::make_shared(), name, getter, setter}; } ///////////////////////////////////////////////////////////////////////////////////////// template registration::bind registration::method(string_view name, F f) { using namespace detail; static_assert(is_functor::value, "No valid property accessor provided!"); return {std::make_shared(), name, f}; } ///////////////////////////////////////////////////////////////////////////////////////// template registration::bind registration::enumeration(string_view name) { using namespace detail; static_assert(std::is_enum::value, "No enum type provided, please call this method with an enum type!"); return {std::make_shared(), name}; } ///////////////////////////////////////////////////////////////////////////////////////// } // end namespace rttr #define RTTR_REGISTRATION \ static void rttr_auto_register_reflection_function_(); \ namespace \ { \ struct rttr__auto__register__ \ { \ rttr__auto__register__() \ { \ rttr_auto_register_reflection_function_(); \ } \ }; \ } \ static const rttr__auto__register__ RTTR_CAT(auto_register__, __LINE__); \ static void rttr_auto_register_reflection_function_() #if RTTR_COMPILER == RTTR_COMPILER_MSVC #define RTTR_PLUGIN_REGISTRATION RTTR_REGISTRATION #else #define RTTR_PLUGIN_REGISTRATION \ static void rttr_auto_register_reflection_function_() RTTR_DECLARE_PLUGIN_CTOR; \ static void rttr_auto_unregister_reflection_function() RTTR_DECLARE_PLUGIN_DTOR; \ \ static void rttr_auto_unregister_reflection_function() \ { \ rttr::detail::get_registration_manager().unregister(); \ } \ static void rttr_auto_register_reflection_function_() #endif #endif // RTTR_REGISTRATION_IMPL_H_