/************************************************************************************ * * * 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_CONSTRUCTOR_H_ #define RTTR_CONSTRUCTOR_H_ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/detail/misc/class_item_mapper.h" #include "rttr/parameter_info.h" #include "rttr/access_levels.h" #include "rttr/array_range.h" #include "rttr/string_view.h" #include #include namespace rttr { class variant; class type; class argument; class visitor; namespace detail { class constructor_wrapper_base; } /*! * The \ref constructor class provides several meta information about a constructor and can be invoked. * * A instance of a constructor class can only be obtained from the \ref type class. * See \ref type::get_constructor() and \ref type::get_constructors(). * * For registration a constructor of a class, see \ref registration::class_::constructor(). * * Meta Information * ---------------- * A \ref constructor has a signature (\ref get_signature()) and instantiate exactly one type (\ref get_instantiated_type()). * With \ref get_parameter_infos() you retrieve all information of the parameters for this constructor. * When the \ref constructor was declared inside a class, then \ref get_declaring_type() can be used to obtain the type of this class. * * The constructor can be invoked with \ref invoke() or via the \ref type class through \ref type::create(). * The created object will be copied into a variant and returned. Depending on the used policy during the registration process, * it can be an object with automatic or dynamic storage. * * Copying and Assignment * ---------------------- * A \ref constructor object is lightweight and can be copied by value. However, each copy will refer to the same underlying constructor. * * Typical Usage * ---------------------- * * \code{.cpp} * constructor ctor = type::get_by_name("std::string").get_constructor({type::get()}); // retrieve the copy ctor * * variant var = ctor.invoke(std::string("Hello World")); // returns an object with automatic storage * * std::cout << var.get_value().c_str() << std::endl; // prints 'Hello World' * \endcode * * \see method, property, enumeration, destructor and type */ class RTTR_API constructor { public: /*! * \brief Returns true if this constructor is valid, otherwise false. * * \return True if this constructor is valid, otherwise false. */ bool is_valid() const RTTR_NOEXCEPT; /*! * \brief Convenience function to check if this constructor is valid or not. * * \return True if this constructor is valid, otherwise false. */ explicit operator bool() const RTTR_NOEXCEPT; /*! * \brief Returns access level with which this constructor was * \ref registration::class_::constructor() "registered". * * \remark When the constructor is not valid, this function will return level \ref access_levels::public_access. * * \return \ref access_levels of the method. */ access_levels get_access_level() const RTTR_NOEXCEPT; /*! * Returns the type object of the instantiated type. * * \return The instantiated type. */ type get_instantiated_type() const RTTR_NOEXCEPT; /*! * \brief Returns the \ref type of the class or struct that declares this \ref constructor. * * \remark When this constructor does not belong to a class (i.e. is a primitive type) it will return an invalid type object. * When this constructor is not valid, this function will return an invalid type object (see \ref type::is_valid). * * \return \ref type "Type" of the declaring class/struct for this enumeration. */ type get_declaring_type() const RTTR_NOEXCEPT; /*! * \brief Returns the signature of this constructor as readable string. * * \return The signature as readable string. */ string_view get_signature() const RTTR_NOEXCEPT; /*! * \brief Returns an ordered range of \ref parameter_info objects, which matches the signature of the constructor. * * \return A range of parameter_info objects of the constructor signature. */ array_range get_parameter_infos() const RTTR_NOEXCEPT; /*! * \brief Returns the meta data for the given key \p key. * * \remark When no meta data is registered with the given \p key, * an invalid \ref variant object is returned (see \ref variant::is_valid). * * \return A variant object, containing arbitrary data. */ variant get_metadata(const variant& key) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark Returns an invalid \ref variant object (see \ref variant::is_valid), when the arguments does * not match the parameters of the underlying constructor. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke() const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1, argument arg2) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1, argument arg2, argument arg3) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1, argument arg2, argument arg3, argument arg4) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1, argument arg2, argument arg3, argument arg4, argument arg5) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke(argument arg1, argument arg2, argument arg3, argument arg4, argument arg5, argument arg6) const; /*! * \brief Invokes the constructor of type returned by \ref get_instantiated_type(). * The instance will always be created on the heap and will be returned as variant object. * Use this method when you need to instantiate a constructor with more then 6 parameters. * * \remark The given argument type has to match **exactly** the type of the underling constructor parameter, * otherwise the constructor cannot be invoked and an invalid \ref variant object (see \ref variant::is_valid) * will be returned. * Using this invoke function is slower, then specifying the arguments directly. * * \see get_parameter_infos() * * \return An instance of the type \ref get_instantiated_type(). */ variant invoke_variadic(std::vector args) const; /*! * \brief Returns true if this constructor is the same like the \p other. * * \return True if both constructors are equal, otherwise false. */ bool operator==(const constructor& other) const RTTR_NOEXCEPT; /*! * Returns true if this constructor is the not the same like the \p other. * * \return True if both constructors are different, otherwise false. */ bool operator!=(const constructor& other) const RTTR_NOEXCEPT; private: constructor(const detail::constructor_wrapper_base* wrapper) RTTR_NOEXCEPT; void visit(visitor& visitor) const RTTR_NOEXCEPT; template friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); template friend T detail::create_invalid_item(); friend class visitor; private: const detail::constructor_wrapper_base* m_wrapper; }; } // end namespace rttr #endif // RTTR_CONSTRUCTOR_H_