/************************************************************************************ * * * 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_ARGUMENT_EXTRACTOR_H_ #define RTTR_ARGUMENT_EXTRACTOR_H_ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/detail/misc/misc_type_traits.h" #include #include #include namespace rttr { namespace detail { /*! * The class \ref argument_extractor will forwards all arguments of type \p T * via a variadic function call to a std::array. * All other types will be ignored. */ template struct argument_extractor { using container_size = count_type>; using array_type = std::array; static array_type extract_to_array(OrigArgs&&... arg) { array_type result; extract_types_recursively(result, std::forward(arg)...); return result; } static std::vector extract_to_vector(OrigArgs&&... arg) { std::vector result; result.reserve(container_size::value); extract_types_recursively(result, std::forward(arg)...); return result; } private: template static void extract_types_recursively(container_type& container) { } ///////////////////////////////////////////////////////////////////////////////////// template static enable_if_t< !std::is_same>::value, void > extract_types_recursively(container_type& container, U&& value, Args &&... tail) { extract_types_recursively(container, std::forward< Args >(tail)...); } ///////////////////////////////////////////////////////////////////////////////////// template static enable_if_t< std::is_same>::value, void > extract_types_recursively(container_type& container, U&& value, Args &&... tail) { RTTR_STATIC_CONSTEXPR auto index = count_type>::value - count_type>::value - 1; container[index] = std::forward(value); extract_types_recursively(container, std::forward< Args >(tail)...); } ///////////////////////////////////////////////////////////////////////////////////// template static enable_if_t< std::is_same>::value, void > extract_types_recursively(std::vector& container, U&& value, Args &&... tail) { container.emplace_back(std::forward(value)); extract_types_recursively(container, std::forward< Args >(tail)...); } }; ///////////////////////////////////////////////////////////////////////////////////// /*! * Forwards all objects of type \p T to an std::vector. * * Use it in a context of a variadic function call. * See following code sample: * * \code{.cpp} * * template * void get_all_int_values(Args&&... args) * { * std::vector my_values = get_as_vector(std::forward(args)...); * } * * \endcode */ template std::vector forward_to_vector(Args&&... args) { return argument_extractor::extract_to_vector(std::forward(args)...); } /*! * Forwards all objects of type \p T to an std::array. * * Use it in a context of a variadic function call. * See following code sample: * * \code{.cpp} * * template * void get_all_int_values(Args&&... args) * { * auto my_values = forward_to_array(std::forward(args)...); * } * * \endcode */ template std::array>::value> forward_to_array(Args&&... args) { return argument_extractor::extract_to_array(std::forward(args)...); } } // end namespace detail } // end namespace rttr #endif // RTTR_ARGUMENT_EXTRACTOR_H_