Defined in header <memoized_invoke.hh>
bool is_done() const noexcept; // (1)
auto const& value() const // (2)
requires ( ! std::is_void_v< result_type > );
1) is_done()
Returns true once the callable has run to completion and a value is cached. Returns false:
- before the first
operator(), - after a
reset(), - after the callable threw (the state was rolled back),
- on a freshly copied or moved
lock_freeobject (its state is re-initialised).
noexcept. Under lock_free it is a single acquire load; the value it returns is a snapshot and may be stale the instant it is read if another thread is mid-call.
2) value()
Returns a const reference to the cached result — without invoking the callable. Available only when result_type is not void.
Precondition: is_done() == true. If the precondition does not hold the behaviour is undefined; the shipped implementation throws std::bad_optional_access (it calls std::optional::value() on an empty optional).
value() returns a true reference into the object's storage — no copy — unlike operator(), which returns by value. Prefer value() when the result is large and you only need to read it.
Return value
is_done() | bool |
value() | result_type const& (spelled auto const&) |
Exceptions
is_done()— none (noexcept).value()—std::bad_optional_accessif called whenis_done()isfalse(undefined behaviour formally; this is what the implementation does).
Notes
There is no has_value() distinct from is_done() — for a non-void callable they are the same thing. For a void callable, is_done() is the only observer; there is no value.
value() is const, so it is safe to call on a memoized_invoke const& once you know it is done — a common pattern for a shared, load-once singleton:
inline Config const& config()
{
static auto loader = make_memoized<lock_free>(&Config::load);
loader(); // first caller loads
return loader.value(); // everyone gets the same reference
}
Example
#include <memoized_invoke.hh>
#include <iostream>
#include <stdexcept>
using fedem::utility::memoized_invoke;
int main()
{
memoized_invoke co( [](int x){ return x * x; }, 8 );
std::cout << std::boolalpha << co.is_done() << '\n'; // false
try { (void) co.value(); }
catch (std::bad_optional_access const&) { std::cout << "not ready\n"; }
co();
std::cout << co.is_done() << ' ' << co.value() << '\n'; // true 64
}
See also
- operator() — returns by value; runs the callable if needed.
- reset — after this,
is_done()isfalseagain.

