template<std::size_t...Is>
auto index_over(std::index_sequence<Is...>) {
return [](auto&& f)->decltype(auto){
return decltype(f)(f)( std::integral_constant< std::size_t, Is >{}... );
};
}
template<std::size_t N>
auto index_upto(std::integral_constant<std::size_t, N> ={}) {
return index_over( std::make_index_sequence<N>{} );
}
inline float sum() { return 0.0f; }
template<class...Args>
float sum( float a, Args... args ) {
return a + sum(args...);
}
, .
auto Z_f = [&](auto X, auto Y)->float {
return index_upto<2>()( [&](auto...Zs)->float{
return sum((poly<2,Zs>(fU) * mat[X][Y][Zs])...);
});
};
auto Y_f = [&](auto X)->float {
return index_upto<2>()( [&](auto...Ys)->float{
return sum( (poly<2,Ys>(fT) * Z_f(X, Ys))... );
});
};
auto X_f = [&]()->float {
return index_upto<2>()( [&](auto...Xs)->float{
return sum( (poly<2,Xs>(fS) * Y_f(Xs))... );
});
};
float val = X_f();
, - , , , X_f, Y_f Z_f .
clang .
++ 14 (index_sequence make_index_sequence), ++ 11.
auto lambdas, ++ 14. ++ 11 , , .
sum (0.f + ... + args) ++ 17.
, .
godbolt, , .
, , 3 Xs, Ys Zs, .
auto contribution = [&](auto X, auto Y, auto Z) {
return mat[X][Y][Z] * poly<2,X>(fS) * poly2<2,Y>(fT) * poly2<2,Z>(fU);
};
, 3 , .
auto summer_1d = [](auto...Vals)->decltype(auto){
return sum(Vals...);
};
template<std::size_t X_max, std::size_t Y_max, std::size_t Z_max, class Sum = decltype(summer_1d)>
auto sumup_3d(Sum sum = summer_1d) {
return [](auto&& f)->decltype(auto) {
auto Z_part = [&](auto X, auto Y)->decltype(auto) {
return index_upto<Z_max>()([&](auto...Zs)->decltype(auto){
return sum( f(X,Y,Zs)... );
});
};
auto Y_part = [&](auto X)->decltype(auto) {
return index_upto<Y_max>()([&](auto...Ys)->decltype(auto){
return sum( Z_part(X, Ys)... );
});
};
return index_upto<X_max>()([&](auto...Xs)->decltype(auto){
return sum( Y_part(Xs)... );
});
};
};
auto val = sumup_3d<3,3,3>()(contribution);
somesuch.