#include <iostream>
#include <functional>
#include <unordered_map>
template<typename Sig, typename F=Sig* >
struct memoize_t;
template<typename R, typename Arg, typename F>
struct memoize_t<R(Arg), F> {
F f;
mutable std::unordered_map< Arg, R > results;
R operator()( Arg a ) const {
auto it = results.find(a);
if (it != results.end())
return it->second;
else
return results[a] = f(a);
}
};
template<typename F>
memoize_t<F> memoize( F* func ) {
return {func};
}
int foo(int x) {
static auto mem = memoize(foo);
auto&& foo = mem;
std::cout << "processing...\n";
if (x <= 0) return 0;
if (x <= 2) return 1;
return foo(x-1) + foo(x-2);;
}
int main() {
std::cout << foo(10) << "\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CgoKdGVtcGxhdGU8dHlwZW5hbWUgU2lnLCB0eXBlbmFtZSBGPVNpZyogPgpzdHJ1Y3QgbWVtb2l6ZV90Owp0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZSBBcmcsIHR5cGVuYW1lIEY+CnN0cnVjdCBtZW1vaXplX3Q8UihBcmcpLCBGPiB7CglGIGY7CgltdXRhYmxlIHN0ZDo6dW5vcmRlcmVkX21hcDwgQXJnLCBSID4gcmVzdWx0czsKCVIgb3BlcmF0b3IoKSggQXJnIGEgKSBjb25zdCB7CgkJYXV0byBpdCA9IHJlc3VsdHMuZmluZChhKTsKCQlpZiAoaXQgIT0gcmVzdWx0cy5lbmQoKSkKCQkJcmV0dXJuIGl0LT5zZWNvbmQ7CgkJZWxzZQoJCQlyZXR1cm4gcmVzdWx0c1thXSA9IGYoYSk7Cgl9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGPgptZW1vaXplX3Q8Rj4gbWVtb2l6ZSggRiogZnVuYyApIHsKCXJldHVybiB7ZnVuY307Cn0KCmludCBmb28oaW50IHgpIHsKCXN0YXRpYyBhdXRvIG1lbSA9IG1lbW9pemUoZm9vKTsKCWF1dG8mJiBmb28gPSBtZW07CglzdGQ6OmNvdXQgPDwgInByb2Nlc3NpbmcuLi5cbiI7CglpZiAoeCA8PSAwKSByZXR1cm4gMDsKCWlmICh4IDw9IDIpIHJldHVybiAxOwoJcmV0dXJuIGZvbyh4LTEpICsgZm9vKHgtMik7Owp9CmludCBtYWluKCkgewoJc3RkOjpjb3V0IDw8IGZvbygxMCkgPDwgIlxuIjsKfQ==