I know that I can use boost::variantand not ask this question. But use boost::variantincludes a lot of ugly code. In particular, visitors are dirty. So, without further ado ...
I wrote the following template class to implement a lazy evaluation of curry functions. (See my previous question for the entire snippet.)
template <typename> class curry;
template <typename _Res>
class curry< _Res() >
{
public:
typedef std::function< _Res() > _Fun;
typedef _Res _Ret;
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
operator _Ret ()
{ return _fun(); }
};
So I want to update it to enable memoization. Conceptually, it is very simple. First of all, I have to replace:
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
WITH
private:
bool _evaluated;
union
{
_Fun _fun;
_Res _res;
};
public:
explicit curry (_Fun fun)
: _evaluated(false), _fun(fun) { }
explicit curry (_Res res)
: _evaluated(true), _res(res) { }
. -, operator _Ret, , , memoized. -, , _evaluated _fun, _res. , .
-, _fun _res? , ?
operator _Ret ()
{
if (!_evaluated) {
_Fun fun = _fun;
_fun.~_Fun();
_res._Res(fun());
_evaluated = true;
}
return _res;
}
-, _fun _res? , ?
~curry ()
{
if (_evaluated)
_res.~_Res();
else
_fun.~_Fun();
}