Skip to content

Commit 12be501

Browse files
committed
Update apply to std 17
1 parent f31d415 commit 12be501

File tree

2 files changed

+21
-25
lines changed

2 files changed

+21
-25
lines changed

include/xtensor/utils/xutils.hpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace xt
5555
constexpr decltype(auto) argument(Args&&... args) noexcept;
5656

5757
template <class R, class F, class... S>
58-
R apply(std::size_t index, F&& func, const std::tuple<S...>& s) NOEXCEPT(noexcept(func(std::get<0>(s))));
58+
R apply(std::size_t index, F&& func, const std::tuple<S...>& s);
5959

6060
template <class T, class S>
6161
void nested_copy(T&& iter, const S& s);
@@ -283,29 +283,28 @@ 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)
306-
NOEXCEPT(noexcept(func(std::get<0>(s))))
307288
{
308-
return detail::apply<R>(index, std::forward<F>(func), std::make_index_sequence<sizeof...(S)>(), s);
289+
XTENSOR_ASSERT(sizeof...(S) > index);
290+
return std::apply(
291+
[&](const S&... args) -> R
292+
{
293+
auto f_impl = [&](auto&& self, auto&& i, auto&& h, auto&&... t) -> R
294+
{
295+
if (i == index)
296+
{
297+
return static_cast<R>(func(h));
298+
}
299+
if constexpr (sizeof...(t) > 0)
300+
{
301+
return self(self, std::size_t{i + 1}, t...);
302+
}
303+
};
304+
return f_impl(f_impl, std::size_t{0}, args...);
305+
},
306+
s
307+
);
309308
}
310309

311310
/***************************

test/test_xutils.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,8 @@ namespace xt
110110
return i;
111111
};
112112
auto t = std::make_tuple(1, 2, 3);
113-
#if (_MSC_VER >= 1910)
113+
// This can always throw if the runtime index exceeds the length of the tuple
114114
EXPECT_FALSE(noexcept(apply<int>(1, func_ne, t)));
115-
#else
116-
EXPECT_TRUE(noexcept(apply<int>(1, func_ne, t)));
117-
#endif
118115
}
119116

120117
TEST(utils, conditional_cast)

0 commit comments

Comments
 (0)