|
callonce
1.0.0
Header-only memoized call-once wrapper for any C++ callable
|
Wraps a callable + argument set, runs it at most once, caches the result. More...
#include <memoized_invoke.hh>
Collaboration diagram for fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >:Classes | |
| struct | execution_guard |
Public Types | |
| using | result_type = std::invoke_result_t< F, Args... > |
The callable's return type: std::invoke_result_t<F, Args...>. May be void. More... | |
Public Member Functions | |
| memoized_invoke (F func) requires(sizeof...(Args) | |
| Construct from a callable that takes no arguments. More... | |
| memoized_invoke & | operator= (memoized_invoke const &other) requires std |
| Copy assignment. Self-assignment safe. More... | |
| result_type | operator() () |
| Invoke with the stored arguments, or return the cached result. More... | |
| result_type | operator() (std::decay_t< Args >... args) requires(sizeof...(Args) > 0) |
| Invoke with a fresh argument set, re-executing if it changed. More... | |
| void | reset () noexcept |
| Drop the cached result and return to the not-started state. More... | |
| void | reset (std::decay_t< Args >... args) requires(sizeof...(Args) > 0) |
| Drop the cached result, replace the stored arguments, and reset. More... | |
| bool | is_done () const noexcept |
| auto const & | value () const requires(! std |
| Access the cached result without invoking the callable. More... | |
Private Types | |
| using | args_tuple = std::tuple< std::decay_t< Args >... > |
Private Member Functions | |
| void | do_invoke () |
| void | check_and_call () |
Private Attributes | |
| F | callable_ |
| ExecutionPolicy | policy_ |
| detail::return_storage< result_type > | storage_ |
| args_tuple | args_ |
Wraps a callable + argument set, runs it at most once, caches the result.
| ExecutionPolicy | Synchronisation policy — single_threaded or lock_free, or any type meeting the same interface (try_enter, mark_done, mark_free, is_done, wait). |
| F | The callable type. Any type for which std::is_invocable_v<F, Args...> holds: free / member function pointers (including noexcept), lambdas (stateless, capturing, mutable), functors with const or non-const operator(), std::function, and std::bind_front results. |
| Args | The argument types F is invoked with. For a member function pointer, the object (pointer or reference) is the first entry. Stored by value as std::decay_t<Args>.... |
Construct with the callable and its arguments, then call operator(): the first call runs std::apply(f, args) and caches what it returns; every later call returns the cached value. operator()(new_args...) compares the new arguments with the stored ones (as tuples, via operator!=) and re-executes when they differ.
If the callable throws, an internal RAII guard rolls the policy state back to not-started, the cache stays empty, and the next call retries — the same contract as std::call_once.
CTAD deduces every parameter and selects single_threaded. For a different policy, go through make_memoized.
| using fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::result_type = std::invoke_result_t< F, Args... > |
The callable's return type: std::invoke_result_t<F, Args...>. May be void.
|
private |
|
explicit |
Construct from a callable that takes no arguments.
| func | The callable. Moved into the object. |
sizeof...(Args) == 0.
|
inlineprivate |
References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::args_, fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::callable_, fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_, and fedem::utility::detail::return_storage< T >::store().
Referenced by fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::check_and_call().
Here is the call graph for this function:
Here is the caller graph for this function:
|
inlineprivate |
References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::execution_guard::commit(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::do_invoke(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_.
Referenced by fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator()().
Here is the call graph for this function:
Here is the caller graph for this function:
|
inline |
Copy assignment. Self-assignment safe.
std::is_copy_assignable_v<F>.Move assignment. Self-assignment safe.
noexcept when both F and the argument tuple move without throwing. References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::args_, fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::callable_, fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_, and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
|
inline |
Invoke with the stored arguments, or return the cached result.
If is_done is false, runs std::apply(f, args), caches the result and transitions to done. If the callable throws, the exception propagates and the state stays not-started so a later call retries. If is_done is true, returns the cached result without running anything.
void callable. References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::check_and_call(), fedem::utility::detail::return_storage< T >::get(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
Here is the call graph for this function:
|
inline |
Invoke with a fresh argument set, re-executing if it changed.
The new arguments are compared with the stored ones as tuples via operator!=. If they differ, the stored arguments are replaced, the cache is cleared, the state is reset and the callable runs again. If they are equal, this behaves exactly like operator()().
| args | The new argument set. |
void. sizeof...(Args) > 0. Requires the argument types to be equality-comparable. Not thread-safe even under lock_free. References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::args_, fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::check_and_call(), fedem::utility::detail::return_storage< T >::clear(), fedem::utility::detail::return_storage< T >::get(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_, and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
Here is the call graph for this function:
|
inlinenoexcept |
Drop the cached result and return to the not-started state.
The stored arguments are kept; the next call re-runs the callable with them. Not thread-safe.
References fedem::utility::detail::return_storage< T >::clear(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_, and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
Here is the call graph for this function:
|
inline |
Drop the cached result, replace the stored arguments, and reset.
| args | The new argument set the next call will use. |
sizeof...(Args) > 0. Not thread-safe. References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::args_, fedem::utility::detail::return_storage< T >::clear(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_, and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
Here is the call graph for this function:
|
inlinenoexcept |
true once the callable has completed and a value is cached. References fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::policy_.
|
inline |
Access the cached result without invoking the callable.
const reference to the cached value. true; otherwise the behaviour is undefined (the shipped implementation throws std::bad_optional_access). void result_type. References fedem::utility::detail::return_storage< T >::get(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::storage_.
Here is the call graph for this function:
|
private |
|
private |
Referenced by fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::check_and_call(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::is_done(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator()(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator=(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::reset().
|
private |
Referenced by fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::do_invoke(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator()(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator=(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::reset(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::value().
|
private |
Referenced by fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::do_invoke(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator()(), fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::operator=(), and fedem::utility::memoized_invoke< ExecutionPolicy, F, Args >::reset().