#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";
}