Skip to content

Commit 9a37673

Browse files
authored
Apply C++17 fold to accumulation (#2874)
# Checklist - [x] The title and commit message(s) are descriptive. - [x] Small commits made to fix your PR have been squashed to avoid history pollution. - [x] Tests have been added for new features or bug fixes. - [x] API of new functions and classes are documented. # Description <!--- Give any relevant description here. If your PR fixes an issue, please include "Fixes #ISSUE" (substituting the relevant issue ID). -->
1 parent 239cd7f commit 9a37673

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

include/xtensor/utils/xutils.hpp

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

205205
namespace detail
206206
{
207-
template <std::size_t I, class F, class R, class... T>
208-
inline std::enable_if_t<I == sizeof...(T), R>
209-
accumulate_impl(F&& /*f*/, R init, const std::tuple<T...>& /*t*/) noexcept
210-
{
211-
return init;
212-
}
213-
214-
template <std::size_t I, class F, class R, class... T>
215-
inline std::enable_if_t < I<sizeof...(T), R>
216-
accumulate_impl(F&& f, R init, const std::tuple<T...>& t) noexcept(noexcept(f(init, std::get<I>(t))))
207+
template <class F, class R, class... T, size_t... I>
208+
R accumulate_impl(F&& f, R init, const std::tuple<T...>& t, std::index_sequence<I...> /*I*/) noexcept(
209+
(noexcept(f(init, std::get<I>(t))) && ...)
210+
)
217211
{
218-
R res = f(init, std::get<I>(t));
219-
return accumulate_impl<I + 1, F, R, T...>(std::forward<F>(f), res, t);
212+
R res = init;
213+
auto wrapper = [&](const auto& i, const auto& j)
214+
{
215+
res = f(i, j);
216+
};
217+
(wrapper(res, std::get<I>(t)), ...);
218+
return res;
220219
}
221220
}
222221

223222
template <class F, class R, class... T>
224223
inline R accumulate(F&& f, R init, const std::tuple<T...>& t) noexcept(
225-
noexcept(detail::accumulate_impl<0, F, R, T...>(std::forward<F>(f), init, t))
224+
noexcept(detail::accumulate_impl(std::forward<F>(f), init, t, std::make_index_sequence<sizeof...(T)>{}))
226225
)
227226
{
228-
return detail::accumulate_impl<0, F, R, T...>(std::forward<F>(f), init, t);
227+
return detail::accumulate_impl(std::forward<F>(f), init, t, std::make_index_sequence<sizeof...(T)>{});
229228
}
230229

231230
/// @endcond

test/test_xutils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ 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+
EXPECT_EQ(8, accumulate(func_ne, 8, t_empty));
8790
}
8891

8992
template <class... T>

0 commit comments

Comments
 (0)