From 9cd70cf57b0edda2111ecb6ec8c812f2768f19f7 Mon Sep 17 00:00:00 2001 From: Drew Hubley Date: Mon, 31 Mar 2025 20:22:53 -0300 Subject: [PATCH] Update apply to std 17 --- include/xtensor/utils/xutils.hpp | 39 ++++++++++++++++---------------- test/test_xutils.cpp | 6 ++--- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/xtensor/utils/xutils.hpp b/include/xtensor/utils/xutils.hpp index 7c4989506..cce399a17 100644 --- a/include/xtensor/utils/xutils.hpp +++ b/include/xtensor/utils/xutils.hpp @@ -283,29 +283,30 @@ namespace xt * apply implementation * ************************/ - namespace detail - { - template - R apply_one(F&& func, const std::tuple& s) NOEXCEPT(noexcept(func(std::get(s)))) - { - return static_cast(func(std::get(s))); - } - - template - R apply(std::size_t index, F&& func, std::index_sequence /*seq*/, const std::tuple& s) - NOEXCEPT(noexcept(func(std::get<0>(s)))) - { - using FT = std::add_pointer_t&)>; - static const std::array ar = {{&apply_one...}}; - return ar[index](std::forward(func), s); - } - } - template inline R apply(std::size_t index, F&& func, const std::tuple& s) NOEXCEPT(noexcept(func(std::get<0>(s)))) { - return detail::apply(index, std::forward(func), std::make_index_sequence(), s); + XTENSOR_ASSERT(sizeof...(S) > index); + return std::apply( + [&](const S&... args) -> R + { + auto f_impl = [&](auto&& self, auto&& i, auto&& h, auto&&... t) -> R + { + if (i == index) + { + return static_cast(func(h)); + } + if constexpr (sizeof...(t) > 0) + { + return self(self, std::size_t{i + 1}, t...); + } + return R{}; + }; + return f_impl(f_impl, std::size_t{0}, args...); + }, + s + ); } /*************************** diff --git a/test/test_xutils.cpp b/test/test_xutils.cpp index a6acfe759..5a88baa39 100644 --- a/test/test_xutils.cpp +++ b/test/test_xutils.cpp @@ -104,16 +104,16 @@ namespace xt TEST(utils, apply) { ASSERT_TRUE(foo(std::make_tuple(1, 2, 3)) == 2); - EXPECT_FALSE(noexcept(foo(std::make_tuple(1, 2, 3)))); + static_assert(!noexcept(foo(std::make_tuple(1, 2, 3)))); auto func_ne = [](int i) noexcept { return i; }; auto t = std::make_tuple(1, 2, 3); #if (_MSC_VER >= 1910) - EXPECT_FALSE(noexcept(apply(1, func_ne, t))); + static_assert(!noexcept(apply(1, func_ne, t))); #else - EXPECT_TRUE(noexcept(apply(1, func_ne, t))); + static_assert(noexcept(apply(1, func_ne, t))); #endif }