#pragma once
#include <functional>
#include <optional>

template <typename T> struct GeneratingAccessor
{
    using Func = std::function<T()>;
    Func generating_func;
    bool generated = false;
    std::optional<T> result;

    template <typename F> GeneratingAccessor(const F& f): generating_func(f)
    {
    }

    void invalidate()
    {
        generated = false;
    }

    operator T()
    {
        if (!generated)
        {
            result    = std::make_optional(generating_func());
            generated = true;
        }

        return result.value();
    }
};
