Skip to content

Instantly share code, notes, and snippets.

@nurettin
Last active December 28, 2015 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nurettin/7562773 to your computer and use it in GitHub Desktop.
Save nurettin/7562773 to your computer and use it in GitHub Desktop.
C++11 lazy parameters
#include <functional>
#include <vector>
#include <boost/optional.hpp>
struct LazyBase
{
std::vector<std::reference_wrapper<LazyBase>> dependents;
virtual void nullify()= 0;
virtual ~LazyBase(){}
};
template <typename T>
struct Lazy: LazyBase
{
void nullify(){ data= boost::none; }
Lazy(){}
Lazy(std::function<T ()> getter)
: getter(getter)
{}
Lazy(std::function<T ()> getter, Lazy &)
: getter(getter)
{}
Lazy(T const &data)
: data(data)
{}
Lazy(T const &data, boost::optional<std::function<T ()>> getter)
: data(data)
{}
void set(T const &data)
{
this-> data= data;
for(auto &d: dependents)
d.get().nullify();
}
T get()
{
if(!getter|| data)
return *data;
data= (*getter)();
return *data;
}
Lazy &depends(LazyBase &other)
{
other.dependents.push_back(*this);
return *this;
}
private:
boost::optional<T> data;
boost::optional<std::function<T ()>> getter;
};
int main()
{
Lazy<double> first;
Lazy<double> second;
Lazy<double> total([&]{ return first.get()+ second.get(); });
total.depends(first).depends(second); // first and second resets value of total
first.set(1); // set total's value to boost::none
second.set(3); // set total's value to boost::none
std::cout<< total.get(); // calculate result using getter lambda, store it
std::cout<< total.get(); // no calculation
}
@nurettin
Copy link
Author

struct Laziness
{
  Lazy<int> first;
  Lazy<double> second;
  Lazy<double> total;

  Laziness()
  : total([&]{ return first.get()+ second.get(); }, total.depends(first).depends(second))
  {}
};

int main()
{
  Laziness lol;
  lol.first.set(42);
  lol.second.set(54);
  std::cout<< lol.total.get();
}

@nurettin
Copy link
Author

absolutely none

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment