Skip to content

Commit d0f0425

Browse files
authored
Merge pull request #2835 from spectre-ns/apply17
Implement apply with std 17
2 parents 422a58f + 9cd70cf commit d0f0425

File tree

2 files changed

+23
-22
lines changed

2 files changed

+23
-22
lines changed

include/xtensor/utils/xutils.hpp

+20-19
Original file line numberDiff line numberDiff line change
@@ -283,29 +283,30 @@ namespace xt
283283
* apply implementation *
284284
************************/
285285

286-
namespace detail
287-
{
288-
template <class R, class F, std::size_t I, class... S>
289-
R apply_one(F&& func, const std::tuple<S...>& s) NOEXCEPT(noexcept(func(std::get<I>(s))))
290-
{
291-
return static_cast<R>(func(std::get<I>(s)));
292-
}
293-
294-
template <class R, class F, std::size_t... I, class... S>
295-
R apply(std::size_t index, F&& func, std::index_sequence<I...> /*seq*/, const std::tuple<S...>& s)
296-
NOEXCEPT(noexcept(func(std::get<0>(s))))
297-
{
298-
using FT = std::add_pointer_t<R(F&&, const std::tuple<S...>&)>;
299-
static const std::array<FT, sizeof...(I)> ar = {{&apply_one<R, F, I, S...>...}};
300-
return ar[index](std::forward<F>(func), s);
301-
}
302-
}
303-
304286
template <class R, class F, class... S>
305287
inline R apply(std::size_t index, F&& func, const std::tuple<S...>& s)
306288
NOEXCEPT(noexcept(func(std::get<0>(s))))
307289
{
308-
return detail::apply<R>(index, std::forward<F>(func), std::make_index_sequence<sizeof...(S)>(), s);
290+
XTENSOR_ASSERT(sizeof...(S) > index);
291+
return std::apply(
292+
[&](const S&... args) -> R
293+
{
294+
auto f_impl = [&](auto&& self, auto&& i, auto&& h, auto&&... t) -> R
295+
{
296+
if (i == index)
297+
{
298+
return static_cast<R>(func(h));
299+
}
300+
if constexpr (sizeof...(t) > 0)
301+
{
302+
return self(self, std::size_t{i + 1}, t...);
303+
}
304+
return R{};
305+
};
306+
return f_impl(f_impl, std::size_t{0}, args...);
307+
},
308+
s
309+
);
309310
}
310311

311312
/***************************

test/test_xutils.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,16 @@ namespace xt
104104
TEST(utils, apply)
105105
{
106106
ASSERT_TRUE(foo(std::make_tuple(1, 2, 3)) == 2);
107-
EXPECT_FALSE(noexcept(foo(std::make_tuple(1, 2, 3))));
107+
static_assert(!noexcept(foo(std::make_tuple(1, 2, 3))));
108108
auto func_ne = [](int i) noexcept
109109
{
110110
return i;
111111
};
112112
auto t = std::make_tuple(1, 2, 3);
113113
#if (_MSC_VER >= 1910)
114-
EXPECT_FALSE(noexcept(apply<int>(1, func_ne, t)));
114+
static_assert(!noexcept(apply<int>(1, func_ne, t)));
115115
#else
116-
EXPECT_TRUE(noexcept(apply<int>(1, func_ne, t)));
116+
static_assert(noexcept(apply<int>(1, func_ne, t)));
117117
#endif
118118
}
119119

0 commit comments

Comments
 (0)