From df01ef8c1f623cd6e5efed5e321d84a7430b4c71 Mon Sep 17 00:00:00 2001 From: Olivier Coulaud <olivier.coulaud@inria.fr> Date: Wed, 12 Feb 2025 12:46:06 +0100 Subject: [PATCH] Add a function (ptr_on_variables()) to access the tuple pointing to the first element of the variables in the particle block --- include/scalfmm/container/block.hpp | 32 ++++++++++++++++++-- include/scalfmm/meta/utils.hpp | 46 +++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/include/scalfmm/container/block.hpp b/include/scalfmm/container/block.hpp index 225dfefc..8543890b 100644 --- a/include/scalfmm/container/block.hpp +++ b/include/scalfmm/container/block.hpp @@ -89,6 +89,7 @@ namespace scalfmm::container static constexpr std::size_t variables_size = particle_type::variables_size; using variables_type = typename Particle::variables_type; + using pointer_variables_type = meta::ToPointerTuple_t<variables_type>; static constexpr std::size_t block_particle_raw = get_particle_raw_size(); @@ -414,6 +415,33 @@ namespace scalfmm::container return reinterpret_cast<outputs_value_type*>(std::get<dimension_size + inputs_size>(m_tuple_start)); } + /** + * @brief Get the pointer of the variables inside the block + * + * This pointer allows to access the different variables as arrays. + * \code + * auto variable_storage = pg->storage().ptr_on_variables(); + * auto first_varaible = std::get<0>(variable_storage); + * auto second_varaible = std::get<1>(variable_storage); + * auto input_storage = pg->storage().ptr_on_input(); + * + * for (auto i(0); i < pg->storage().size(); ++i) + * { + * input_storage[i] = Q[index[i]]; + * } + * \endcode + * + * @returnvariables_value_type* const + **/ + inline auto ptr_on_variables() const noexcept -> pointer_variables_type const + { + using range_variable = + meta::make_range_sequence<dimension_size + inputs_size + outputs_size, + dimension_size + inputs_size + outputs_size + variables_size>; + auto tuple_variables = meta::make_sub_tuple(m_tuple_start, range_variable{}); + + return tuple_variables; + } /** * @brief Sets all positions inside the block to zero. */ @@ -623,8 +651,8 @@ namespace scalfmm::container * @param nb_particles number of particles * @return tuple_ptr_type */ - inline constexpr auto init_tuple_start(raw_type* const start_in, - std::size_t nb_particles) const noexcept -> tuple_ptr_type + inline constexpr auto init_tuple_start(raw_type* const start_in, std::size_t nb_particles) const noexcept + -> tuple_ptr_type { auto start{start_in}; tuple_ptr_type tuple_start{}; diff --git a/include/scalfmm/meta/utils.hpp b/include/scalfmm/meta/utils.hpp index 160101e1..194b6a0a 100644 --- a/include/scalfmm/meta/utils.hpp +++ b/include/scalfmm/meta/utils.hpp @@ -135,6 +135,46 @@ namespace scalfmm::meta } }; + /** + * @brief Type deduction: Converts a std::tuple<Ts...> into a std::tuple<Ts*...>. + */ + template<typename Tuple> + struct ToPointerTuple; + + /** + * @brief Specialization for std::tuple<Ts...> + */ + template<typename... Ts> + struct ToPointerTuple<std::tuple<Ts...>> + { + using type = std::tuple<typename std::add_pointer<Ts>::type...>; + }; + + /** + * @brief Aliases to simplify use + * + * How to use if + * @code + * // Define a tuple of values + * using ValueTuple = std::tuple<int, float>; + * + * // Automatic generation of the std::tuple<int*, float*> type + * using PointerTuple = ToPointerTuple_t<ValueTuple>; + * @endcode + */ + template<typename Tuple> + using ToPointerTuple_t = typename ToPointerTuple<Tuple>::type; + + /// @brief Function that takes a tuple of values and returns a tuple of pointers to its elements + /// @tparam ...Ts + /// @param values + /// @return a tuple of pointers to its elements + template<typename... Ts> + auto tupleToPointerTuple(std::tuple<Ts...>& values) + { + return std::apply([](auto&... args) { return std::make_tuple(&args...); }, values); + } + /** * @brief * @@ -396,9 +436,9 @@ namespace scalfmm::meta * std::make_index_sequence<meta::tuple_size<std::decay_t<T>>::value>())) */ template<typename T> - inline constexpr auto - reverse(T&& t) -> decltype(reverse_impl(std::forward<T>(t), - std::make_index_sequence<meta::tuple_size<std::decay_t<T>>::value>())) + inline constexpr auto reverse(T&& t) + -> decltype(reverse_impl(std::forward<T>(t), + std::make_index_sequence<meta::tuple_size<std::decay_t<T>>::value>())) { return reverse_impl(std::forward<T>(t), std::make_index_sequence<meta::tuple_size<std::decay_t<T>>::value>()); } -- GitLab