Skip to content

Commit fa6b07a

Browse files
committed
Apply C++17 fold to accumulation
1 parent 3f986cf commit fa6b07a

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

include/xtensor/utils/xutils.hpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,28 +219,27 @@ namespace xt
219219

220220
namespace detail
221221
{
222-
template <std::size_t I, class F, class R, class... T>
223-
inline std::enable_if_t<I == sizeof...(T), R>
224-
accumulate_impl(F&& /*f*/, R init, const std::tuple<T...>& /*t*/) noexcept
222+
template <class F, class R, class... T, size_t... I>
223+
R accumulate_impl(F&& f, R init, const std::tuple<T...>& t, std::index_sequence<I...> /*I*/) noexcept(
224+
(noexcept(f(init, std::get<I>(t))) && ...)
225+
)
225226
{
226-
return init;
227-
}
228-
229-
template <std::size_t I, class F, class R, class... T>
230-
inline std::enable_if_t < I<sizeof...(T), R>
231-
accumulate_impl(F&& f, R init, const std::tuple<T...>& t) noexcept(noexcept(f(init, std::get<I>(t))))
232-
{
233-
R res = f(init, std::get<I>(t));
234-
return accumulate_impl<I + 1, F, R, T...>(std::forward<F>(f), res, t);
227+
R res = init;
228+
auto wrapper = [&](const auto& i, const auto& j)
229+
{
230+
res = f(i, j);
231+
};
232+
(wrapper(res, std::get<I>(t)), ...);
233+
return res;
235234
}
236235
}
237236

238237
template <class F, class R, class... T>
239238
inline R accumulate(F&& f, R init, const std::tuple<T...>& t) noexcept(
240-
noexcept(detail::accumulate_impl<0, F, R, T...>(std::forward<F>(f), init, t))
239+
noexcept(detail::accumulate_impl(std::forward<F>(f), init, t, std::make_index_sequence<sizeof...(T)>{}))
241240
)
242241
{
243-
return detail::accumulate_impl<0, F, R, T...>(std::forward<F>(f), init, t);
242+
return detail::accumulate_impl(std::forward<F>(f), init, t, std::make_index_sequence<sizeof...(T)>{});
244243
}
245244

246245
/// @endcond

test/test_xutils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ namespace xt
8484
};
8585
EXPECT_EQ(8, accumulate(func_ne, 0, t));
8686
EXPECT_TRUE(noexcept(accumulate(func_ne, 0, t)));
87+
88+
const std::tuple<> t_empty
89+
{
90+
}
91+
EXPECT_EQ(8, accumulate(func_ne, 8, t_empty));
8792
}
8893

8994
template <class... T>

0 commit comments

Comments
 (0)