argument_extractor.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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_ARGUMENT_EXTRACTOR_H_
  28. #define RTTR_ARGUMENT_EXTRACTOR_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/misc_type_traits.h"
  31. #include <memory>
  32. #include <type_traits>
  33. #include <array>
  34. namespace rttr
  35. {
  36. namespace detail
  37. {
  38. /*!
  39. * The class \ref argument_extractor will forwards all arguments of type \p T
  40. * via a variadic function call to a std::array.
  41. * All other types will be ignored.
  42. */
  43. template<typename T, typename... OrigArgs>
  44. struct argument_extractor
  45. {
  46. using container_size = count_type<T, type_list<OrigArgs...>>;
  47. using array_type = std::array<T, container_size::value>;
  48. static array_type extract_to_array(OrigArgs&&... arg)
  49. {
  50. array_type result;
  51. extract_types_recursively(result, std::forward<OrigArgs>(arg)...);
  52. return result;
  53. }
  54. static std::vector<T> extract_to_vector(OrigArgs&&... arg)
  55. {
  56. std::vector<T> result;
  57. result.reserve(container_size::value);
  58. extract_types_recursively(result, std::forward<OrigArgs>(arg)...);
  59. return result;
  60. }
  61. private:
  62. template<typename container_type>
  63. static void extract_types_recursively(container_type& container) { }
  64. /////////////////////////////////////////////////////////////////////////////////////
  65. template<typename container_type, typename U, typename... Args>
  66. static
  67. enable_if_t< !std::is_same<T, raw_type_t<U>>::value, void >
  68. extract_types_recursively(container_type& container, U&& value, Args &&... tail)
  69. {
  70. extract_types_recursively(container, std::forward< Args >(tail)...);
  71. }
  72. /////////////////////////////////////////////////////////////////////////////////////
  73. template<typename container_type, typename U, typename... Args>
  74. static
  75. enable_if_t< std::is_same<T, raw_type_t<U>>::value, void >
  76. extract_types_recursively(container_type& container, U&& value, Args &&... tail)
  77. {
  78. RTTR_STATIC_CONSTEXPR auto index = count_type<T, type_list<OrigArgs...>>::value - count_type<T, type_list<Args...>>::value - 1;
  79. container[index] = std::forward<U>(value);
  80. extract_types_recursively(container, std::forward< Args >(tail)...);
  81. }
  82. /////////////////////////////////////////////////////////////////////////////////////
  83. template<typename U, typename... Args>
  84. static
  85. enable_if_t< std::is_same<T, raw_type_t<U>>::value, void >
  86. extract_types_recursively(std::vector<T>& container, U&& value, Args &&... tail)
  87. {
  88. container.emplace_back(std::forward<U>(value));
  89. extract_types_recursively(container, std::forward< Args >(tail)...);
  90. }
  91. };
  92. /////////////////////////////////////////////////////////////////////////////////////
  93. /*!
  94. * Forwards all objects of type \p T to an std::vector<T>.
  95. *
  96. * Use it in a context of a variadic function call.
  97. * See following code sample:
  98. *
  99. * \code{.cpp}
  100. *
  101. * template<typename...Args>
  102. * void get_all_int_values(Args&&... args)
  103. * {
  104. * std::vector<int> my_values = get_as_vector<int>(std::forward<Args>(args)...);
  105. * }
  106. *
  107. * \endcode
  108. */
  109. template<typename T, typename...Args>
  110. std::vector<T> forward_to_vector(Args&&... args)
  111. {
  112. return argument_extractor<T, Args...>::extract_to_vector(std::forward<Args>(args)...);
  113. }
  114. /*!
  115. * Forwards all objects of type \p T to an std::array<T, N>.
  116. *
  117. * Use it in a context of a variadic function call.
  118. * See following code sample:
  119. *
  120. * \code{.cpp}
  121. *
  122. * template<typename...Args>
  123. * void get_all_int_values(Args&&... args)
  124. * {
  125. * auto my_values = forward_to_array<int>(std::forward<Args>(args)...);
  126. * }
  127. *
  128. * \endcode
  129. */
  130. template<typename T, typename...Args>
  131. std::array<T, count_type<T, type_list<Args...>>::value> forward_to_array(Args&&... args)
  132. {
  133. return argument_extractor<T, Args...>::extract_to_array(std::forward<Args>(args)...);
  134. }
  135. } // end namespace detail
  136. } // end namespace rttr
  137. #endif // RTTR_ARGUMENT_EXTRACTOR_H_