1 #ifndef EAGINE_VECT_HSUM_HPP
9 #define EAGINE_VECT_HSUM_HPP
13 namespace eagine::vect {
15 template <
typename T,
int N,
bool V>
18 using _dT = data_t<T, N, V>;
19 using _dpT = data_param_t<T, 1, V>;
22 using _int = int_constant<U>;
25 using _bool = bool_constant<B>;
28 static auto _sh_apply(_dpT v) noexcept {
29 return shuffle<T, N, V>::template apply<I...>(v);
32 template <
int M,
bool B>
33 static auto _hlp(_dT v, _int<M>, _bool<B>) noexcept -> _dT {
34 static_assert(M == N);
36 for(
int i = 1; i < N; ++i) {
39 for(
int i = N - 1; i > 0; --i) {
47 static constexpr
auto _hlp(_dT v, _int<1>, _bool<B>) noexcept {
51 static constexpr
auto _hlp(_dpT v, _int<2>, std::true_type) noexcept {
52 return v + _sh_apply<1, 0>(v);
55 static constexpr
auto _hlp3_1(_dpT t, _dpT v) noexcept {
56 return t + _sh_apply<2, 2, 1>(v);
59 static constexpr
auto _hlp(_dpT v, _int<3>, std::true_type) noexcept {
60 return _hlp3_1(v + _sh_apply<1, 0, 0>(v), v);
63 static constexpr
auto _hlp4_1(_dpT v) noexcept {
64 return v + _sh_apply<2, 3, 0, 1>(v);
67 static constexpr
auto _hlp(_dpT v, _int<4>, std::true_type) noexcept {
68 return _hlp4_1(v + _sh_apply<1, 0, 3, 2>(v));
71 static constexpr
auto _hlp8_1(_dpT v) noexcept {
72 return v + _sh_apply<1, 0, 3, 2, 5, 4, 7, 6>(v);
75 static constexpr
auto _hlp8_2(_dpT v) noexcept {
76 return v + _sh_apply<2, 3, 0, 1, 6, 7, 4, 5>(v);
79 static constexpr
auto _hlp8_3(_dpT v) noexcept {
80 return v + _sh_apply<4, 5, 6, 7, 0, 1, 2, 3>(v);
83 static constexpr
auto _hlp(_dpT v, _int<8>, std::true_type) noexcept {
84 return _hlp8_3(_hlp8_2(_hlp8_1(v)));
88 static auto apply(_dT v) noexcept -> data_t<T, N, V> {
89 return _hlp(v, _int<N>(), has_vect_data<T, N, V>());
95 #endif // EAGINE_VECT_HSUM_HPP