#include <iostream>
#include <functional>
template <typename T>
class yoba {
public:
yoba(const T& n, std::function<T(T)> func)
: n(n), func(func) {}
T next() {
n = func(n);
return n;
}
private:
T n;
std::function<T(T)> func;
};
template <typename T>
struct return_type : public return_type<decltype(&T::operator())> {};
template <typename C, typename R, typename... Args>
struct return_type<R(C::*)(Args...) const> {
using type = R;
};
template <typename Func>
auto make_yoba(Func func) -> std::function<yoba<typename return_type<Func>::type>(typename return_type<Func>::type)> {
using T = typename return_type<Func>::type;
return [func] (const T& n) {
return yoba<T>(n, func);
};
}
auto main() -> int {
auto yoba_int = make_yoba([] (int n) -> int {
return n + 1;
});
auto yoba_double = make_yoba([] (double n) -> double {
return n / 2;
});
auto yoba_int5 = yoba_int(5);
std::cout << yoba_int5.next() << std::endl;
std::cout << yoba_int5.next() << std::endl;
auto yoba_double238 = yoba_double(2.38);
std::cout << yoba_double238.next() << std::endl;
std::cout << yoba_double238.next() << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyB5b2JhIHsKcHVibGljOgoJeW9iYShjb25zdCBUJiBuLCBzdGQ6OmZ1bmN0aW9uPFQoVCk+IGZ1bmMpCgkJOiBuKG4pLCBmdW5jKGZ1bmMpIHt9CgkKCVQgbmV4dCgpIHsKCQluID0gZnVuYyhuKTsKCQlyZXR1cm4gbjsKCX0KcHJpdmF0ZToKCVQgbjsKCXN0ZDo6ZnVuY3Rpb248VChUKT4gZnVuYzsKfTsKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IHJldHVybl90eXBlIDogcHVibGljIHJldHVybl90eXBlPGRlY2x0eXBlKCZUOjpvcGVyYXRvcigpKT4ge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQywgdHlwZW5hbWUgUiwgdHlwZW5hbWUuLi4gQXJncz4Kc3RydWN0IHJldHVybl90eXBlPFIoQzo6KikoQXJncy4uLikgY29uc3Q+IHsKCXVzaW5nIHR5cGUgPSBSOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEZ1bmM+IAphdXRvIG1ha2VfeW9iYShGdW5jIGZ1bmMpIC0+IHN0ZDo6ZnVuY3Rpb248eW9iYTx0eXBlbmFtZSByZXR1cm5fdHlwZTxGdW5jPjo6dHlwZT4odHlwZW5hbWUgcmV0dXJuX3R5cGU8RnVuYz46OnR5cGUpPiB7Cgl1c2luZyBUID0gdHlwZW5hbWUgcmV0dXJuX3R5cGU8RnVuYz46OnR5cGU7CglyZXR1cm4gW2Z1bmNdIChjb25zdCBUJiBuKSB7CgkJcmV0dXJuIHlvYmE8VD4obiwgZnVuYyk7Cgl9Owp9CgphdXRvIG1haW4oKSAtPiBpbnQgewoJYXV0byB5b2JhX2ludCA9IG1ha2VfeW9iYShbXSAoaW50IG4pIC0+IGludCB7CgkJcmV0dXJuIG4gKyAxOwoJfSk7CglhdXRvIHlvYmFfZG91YmxlID0gbWFrZV95b2JhKFtdIChkb3VibGUgbikgLT4gZG91YmxlIHsKCQlyZXR1cm4gbiAvIDI7Cgl9KTsKCQoJYXV0byB5b2JhX2ludDUgPSB5b2JhX2ludCg1KTsKCQoJc3RkOjpjb3V0IDw8IHlvYmFfaW50NS5uZXh0KCkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IHlvYmFfaW50NS5uZXh0KCkgPDwgc3RkOjplbmRsOwoJCglhdXRvIHlvYmFfZG91YmxlMjM4ID0geW9iYV9kb3VibGUoMi4zOCk7CgkKCXN0ZDo6Y291dCA8PCB5b2JhX2RvdWJsZTIzOC5uZXh0KCkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IHlvYmFfZG91YmxlMjM4Lm5leHQoKSA8PCBzdGQ6OmVuZGw7CgoJcmV0dXJuIDA7Cn0K