From 997f19d6ce7817fa3afe5903a8bb90ad6974c8f2 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 20 Sep 2024 22:02:39 +0200 Subject: [PATCH] Fix potentially invalid use of C++20 input iterators as C++17 iterators. --- include/heyoka/detail/rng_to_vec.hpp | 51 ++++++++++++++++++++++++++++ include/heyoka/expression.hpp | 10 +++--- include/heyoka/llvm_state.hpp | 3 +- src/taylor_02.cpp | 5 +-- 4 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 include/heyoka/detail/rng_to_vec.hpp diff --git a/include/heyoka/detail/rng_to_vec.hpp b/include/heyoka/detail/rng_to_vec.hpp new file mode 100644 index 000000000..21b5e9c2a --- /dev/null +++ b/include/heyoka/detail/rng_to_vec.hpp @@ -0,0 +1,51 @@ +// Copyright 2020, 2021, 2022, 2023, 2024 Francesco Biscani (bluescarni@gmail.com), Dario Izzo (dario.izzo@gmail.com) +// +// This file is part of the heyoka library. +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef HEYOKA_DETAIL_RNG_TO_VEC_HPP +#define HEYOKA_DETAIL_RNG_TO_VEC_HPP + +#include +#include +#include +#include + +#include + +HEYOKA_BEGIN_NAMESPACE + +namespace detail +{ + +// Helper to convert an input range R into a vector. +// The value type is deduced from the reference type of R. +template +auto rng_to_vec(R &&r) +{ + // Deduce the value type. + using value_type = std::remove_cvref_t>; + + // Prepare the return value, reserving the appropriate + // size if R is a sized range. + std::vector retval; + if constexpr (std::ranges::sized_range) { + retval.reserve(static_cast(std::ranges::size(r))); + } + + // Add r's values into retval. + for (auto &&val : r) { + retval.push_back(std::forward(val)); + } + + return retval; +} + +} // namespace detail + +HEYOKA_END_NAMESPACE + +#endif diff --git a/include/heyoka/expression.hpp b/include/heyoka/expression.hpp index 72b01683b..5bac58cd6 100644 --- a/include/heyoka/expression.hpp +++ b/include/heyoka/expression.hpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -461,8 +462,8 @@ class HEYOKA_DLL_PUBLIC dtens [[nodiscard]] size_type index_of(const iterator &) const; [[nodiscard]] auto get_derivatives(std::uint32_t) const -> decltype(std::ranges::subrange(begin(), end())); - [[nodiscard]] auto get_derivatives(std::uint32_t, - std::uint32_t) const -> decltype(std::ranges::subrange(begin(), end())); + [[nodiscard]] auto get_derivatives(std::uint32_t, std::uint32_t) const + -> decltype(std::ranges::subrange(begin(), end())); [[nodiscard]] std::vector get_gradient() const; [[nodiscard]] std::vector get_jacobian() const; [[nodiscard]] std::vector get_hessian(std::uint32_t) const; @@ -846,9 +847,8 @@ class HEYOKA_DLL_PUBLIC_INLINE_CLASS cfunc template static auto rng_to_vecex(R &&r) { - auto tv = r | std::views::transform([](U &&x) { return expression{std::forward(x)}; }); - - return std::vector(std::ranges::begin(tv), std::ranges::end(tv)); + return detail::rng_to_vec( + r | std::views::transform([](U &&x) { return expression{std::forward(x)}; })); } public: diff --git a/include/heyoka/llvm_state.hpp b/include/heyoka/llvm_state.hpp index a6fb77d52..07f26c9cf 100644 --- a/include/heyoka/llvm_state.hpp +++ b/include/heyoka/llvm_state.hpp @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -390,7 +391,7 @@ class HEYOKA_DLL_PUBLIC llvm_multi_state requires std::ranges::input_range && std::same_as>> explicit llvm_multi_state(R &&rng, bool parjit = detail::default_parjit) - : llvm_multi_state(std::vector(std::ranges::begin(rng), std::ranges::end(rng)), parjit) + : llvm_multi_state(detail::rng_to_vec(std::forward(rng)), parjit) { } llvm_multi_state(const llvm_multi_state &); diff --git a/src/taylor_02.cpp b/src/taylor_02.cpp index b5d4354d0..274634471 100644 --- a/src/taylor_02.cpp +++ b/src/taylor_02.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -1200,8 +1201,8 @@ std::vector taylor_compute_jet_multi(llvm_state &main_state, llvm::T // the custom transform: // // https://en.cppreference.com/w/cpp/ranges/as_rvalue_view - auto sview = states | std::views::transform([](auto &s) -> auto && { return std::move(s); }); - return std::vector(std::ranges::begin(sview), std::ranges::end(sview)); + auto sview = states | std::views::transform([](llvm_state &s) -> llvm_state && { return std::move(s); }); + return rng_to_vec(sview); } // Helper for the computation of a jet of derivatives in compact mode,