#include <utility>
#include <iostream>
struct A {
int x;
A(const int a) : x(a) { std::cout<<x<<std::endl; };
A( A const& ) = default;
A& operator=( A const& ) = default;
A operator+(const A &tmp) const {
std::cout<<"("<<x << " + "<<tmp.x<<") ";
return x+tmp.x;
};
};
struct add {
template<typename T, typename U>
auto operator()( T&& t, U&& u )const-> decltype( std::forward<T>(t)+std::forward<U>(u) )
{
return std::forward<T>(t)+std::forward<U>(u);
}
};
#define RETURNS(x) ->decltype(x) { return (x); }
template<typename Op, typename T0>
auto apply_binop( Op&& op, T0&& t0 )
RETURNS(std::forward<T0>(t0))
template<typename Op, typename T0, typename T1, typename... Ts>
auto apply_binop( Op&& op, T0&& t0, T1&& t1, Ts&&... ts )
RETURNS(
op(
std::forward<T0>(t0),
apply_binop(op, std::forward<T1>(t1), std::forward<Ts>(ts)...)
)
)
template<typename... Ts>
auto sum( Ts&&... ts )
RETURNS( apply_binop( add(), std::forward<Ts>(ts)... ) )
int main() {
std::cout << sum(1,2,3,4,5) << "\n";
std::cout << sum(1) << "\n";
std::cout << sum(1,2) << "\n";
std::cout << sum(1,2,3) << "\n";
std::cout << sum(1,2,3,4) << "\n";
std::cout << sum(1,2,3,4.7723) << "\n";
A a(1),b(2),c(3),d(4),e(5),f(6),g(7);
sum(a,b,c,d,e,f);
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KIApzdHJ1Y3QgQSB7CiAgICBpbnQgeDsKIAogICAgQShjb25zdCBpbnQgYSkgOiB4KGEpIHsgc3RkOjpjb3V0PDx4PDxzdGQ6OmVuZGw7IH07CiAgICBBKCBBIGNvbnN0JiApID0gZGVmYXVsdDsKICAgIEEmIG9wZXJhdG9yPSggQSBjb25zdCYgKSA9IGRlZmF1bHQ7CiAgICBBIG9wZXJhdG9yKyhjb25zdCBBICZ0bXApIGNvbnN0IHsKICAgICAgICBzdGQ6OmNvdXQ8PCIoIjw8eCA8PCAiICsgIjw8dG1wLng8PCIpICI7CiAgICAgICAgcmV0dXJuIHgrdG1wLng7CiAgICB9Owp9OwogCnN0cnVjdCBhZGQgewogIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CiAgYXV0byBvcGVyYXRvcigpKCBUJiYgdCwgVSYmIHUgKWNvbnN0LT4gZGVjbHR5cGUoIHN0ZDo6Zm9yd2FyZDxUPih0KStzdGQ6OmZvcndhcmQ8VT4odSkgKQogIHsKICAgIHJldHVybiBzdGQ6OmZvcndhcmQ8VD4odCkrc3RkOjpmb3J3YXJkPFU+KHUpOwogIH0KfTsKIAojZGVmaW5lIFJFVFVSTlMoeCkgLT5kZWNsdHlwZSh4KSB7IHJldHVybiAoeCk7IH0KIAp0ZW1wbGF0ZTx0eXBlbmFtZSBPcCwgdHlwZW5hbWUgVDA+CmF1dG8gYXBwbHlfYmlub3AoIE9wJiYgb3AsIFQwJiYgdDAgKQogIFJFVFVSTlMoc3RkOjpmb3J3YXJkPFQwPih0MCkpCiAKdGVtcGxhdGU8dHlwZW5hbWUgT3AsIHR5cGVuYW1lIFQwLCB0eXBlbmFtZSBUMSwgdHlwZW5hbWUuLi4gVHM+CmF1dG8gYXBwbHlfYmlub3AoIE9wJiYgb3AsIFQwJiYgdDAsIFQxJiYgdDEsIFRzJiYuLi4gdHMgKQogIFJFVFVSTlMoCiAgICBvcCgKICAgICAgc3RkOjpmb3J3YXJkPFQwPih0MCksCiAgICAgIGFwcGx5X2Jpbm9wKG9wLCBzdGQ6OmZvcndhcmQ8VDE+KHQxKSwgc3RkOjpmb3J3YXJkPFRzPih0cykuLi4pCiAgICApCiAgKQogCnRlbXBsYXRlPHR5cGVuYW1lLi4uIFRzPgphdXRvIHN1bSggVHMmJi4uLiB0cyApCiAgUkVUVVJOUyggYXBwbHlfYmlub3AoIGFkZCgpLCBzdGQ6OmZvcndhcmQ8VHM+KHRzKS4uLiApICkKIAppbnQgbWFpbigpIHsKICBzdGQ6OmNvdXQgPDwgc3VtKDEsMiwzLDQsNSkgPDwgIlxuIjsKICBzdGQ6OmNvdXQgPDwgc3VtKDEpIDw8ICJcbiI7CiAgc3RkOjpjb3V0IDw8IHN1bSgxLDIpIDw8ICJcbiI7CiAgc3RkOjpjb3V0IDw8IHN1bSgxLDIsMykgPDwgIlxuIjsKICBzdGQ6OmNvdXQgPDwgc3VtKDEsMiwzLDQpIDw8ICJcbiI7CiAgc3RkOjpjb3V0IDw8IHN1bSgxLDIsMyw0Ljc3MjMpIDw8ICJcbiI7CiAgQSBhKDEpLGIoMiksYygzKSxkKDQpLGUoNSksZig2KSxnKDcpOwogIHN1bShhLGIsYyxkLGUsZik7Cn0=