#include <iostream>
#include <array>
// -- Generate a sequence.
template <int... Is>
struct seq {};
template <int I, int... Is>
struct gen_seq : gen_seq<I - 1, I - 1, Is...> {};
template <int... Is>
struct gen_seq<0, Is...> : seq<Is...> {};
// -- Array summation function.
template <typename T>
constexpr T sum(std::array<T, 1> arr, decltype(gen_seq<0>{})) {
return std::get<0>(arr);
}
template <typename T, std::size_t N, int... Is>
constexpr auto sum(std::array<T, N> arr, seq<Is...>) -> decltype(T() + T()) {
return sum(std::array<T, N - 1>{ { std::get<Is>(arr)... } },
gen_seq<N - 2>()) +
std::get<N - 1>(arr);
}
// The interface - sum all elements of a given array.
template <typename T, std::size_t N>
constexpr auto sum(std::array<T, N> arr)
-> decltype(sum(arr, gen_seq<N - 1>{})) {
return sum(arr, gen_seq<N - 1>{});
}
// -- Demonstration
int main() {
std::cout << sum(std::array<int, 1>{{1}}) << std::endl;
std::cout << sum(std::array<int, 2>{{1, 2}}) << std::endl;
std::cout << sum(std::array<int, 5>{{1, 2, 3, 4, 5}}) << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YXJyYXk+CgovLyAtLSBHZW5lcmF0ZSBhIHNlcXVlbmNlLgp0ZW1wbGF0ZSA8aW50Li4uIElzPgpzdHJ1Y3Qgc2VxIHt9Owp0ZW1wbGF0ZSA8aW50IEksIGludC4uLiBJcz4Kc3RydWN0IGdlbl9zZXEgOiBnZW5fc2VxPEkgLSAxLCBJIC0gMSwgSXMuLi4+IHt9Owp0ZW1wbGF0ZSA8aW50Li4uIElzPgpzdHJ1Y3QgZ2VuX3NlcTwwLCBJcy4uLj4gOiBzZXE8SXMuLi4+IHt9OwoKCi8vIC0tIEFycmF5IHN1bW1hdGlvbiBmdW5jdGlvbi4KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNvbnN0ZXhwciBUIHN1bShzdGQ6OmFycmF5PFQsIDE+IGFyciwgZGVjbHR5cGUoZ2VuX3NlcTwwPnt9KSkgewogICAgcmV0dXJuIHN0ZDo6Z2V0PDA+KGFycik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCBzdGQ6OnNpemVfdCBOLCBpbnQuLi4gSXM+CmNvbnN0ZXhwciBhdXRvIHN1bShzdGQ6OmFycmF5PFQsIE4+IGFyciwgc2VxPElzLi4uPikgLT4gZGVjbHR5cGUoVCgpICsgVCgpKSB7CiAgICByZXR1cm4gc3VtKHN0ZDo6YXJyYXk8VCwgTiAtIDE+eyB7IHN0ZDo6Z2V0PElzPihhcnIpLi4uIH0gfSwKICAgICAgICAgICAgICAgIGdlbl9zZXE8TiAtIDI+KCkpICsKICAgICAgICAgICBzdGQ6OmdldDxOIC0gMT4oYXJyKTsKfQoKLy8gVGhlIGludGVyZmFjZSAtIHN1bSBhbGwgZWxlbWVudHMgb2YgYSBnaXZlbiBhcnJheS4KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHN0ZDo6c2l6ZV90IE4+CmNvbnN0ZXhwciBhdXRvIHN1bShzdGQ6OmFycmF5PFQsIE4+IGFycikKICAgIC0+IGRlY2x0eXBlKHN1bShhcnIsIGdlbl9zZXE8TiAtIDE+e30pKSB7CiAgICByZXR1cm4gc3VtKGFyciwgZ2VuX3NlcTxOIC0gMT57fSk7Cn0KCgovLyAtLSBEZW1vbnN0cmF0aW9uCmludCBtYWluKCkgewogICAgc3RkOjpjb3V0IDw8IHN1bShzdGQ6OmFycmF5PGludCwgMT57ezF9fSkgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IHN1bShzdGQ6OmFycmF5PGludCwgMj57ezEsIDJ9fSkgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IHN1bShzdGQ6OmFycmF5PGludCwgNT57ezEsIDIsIDMsIDQsIDV9fSkgPDwgc3RkOjplbmRsOwp9