![]() |
deal.II version 9.7.0
|
#include <deal.II/base/lazy.h>
This class is a wrapper that provides a convenient mechanism for lazy initialization of the contained object on first use. The class ensures that on-demand initialization of some expensive data structure happens (a) exactly once in a thread-safe manner, and that (b) subsequent checks in hot paths are cheap.
Lazy<T> is closely modeled after the std::optional interface providing a reset() and value() method, but also and extending it with two methods: ensure_initialized(creator) which, as the name suggests, ensures that the contained object is properly initialized. If the Lazy<T> happens happens to contain no value yet, it initializes the wrapped object by calling the creator() function object and storing the return value. In addition a value_or_initialize(creator) function is provided that, similarly, ensures that the object is properly initialized and then returns a reference to the contained value.
Example usage could look like the following, where the FE class stores a matrix that is expensive to compute and so we do not want to do it unless it is actually needed. As a consequence, rather than storing a matrix, we store a Lazy<FullMatrix<double>> that by default is empty; whenever the matrix is first requested, we create it and store it for later reuse:

Public Member Functions | |
| Lazy () | |
| Lazy (const Lazy &other) | |
| Lazy (Lazy &&other) noexcept | |
| Lazy & | operator= (const Lazy &other) |
| Lazy & | operator= (Lazy &&other) noexcept |
| void | reset () noexcept |
| template<typename Callable> | |
| void | ensure_initialized (const Callable &creator) const |
| bool | has_value () const |
| const T & | value () const |
| template<typename Callable> | |
| const T & | value_or_initialize (const Callable &creator) const |
| std::size_t | memory_consumption () const |
Private Attributes | |
| Threads::TaskResult< T > | task_result |
| std::atomic< bool > | object_is_initialized |
Copy constructor. If the other object contains an initialized value, then that value will be copied into the current object. If the other object is uninitialized, then the current object will be as well.
Move constructor. If the other object contains an initialized value, then that value will be moved into the current object, and the other object will end up being empty (as if default initialized). If the other object is uninitialized, then the current object will be as well.
Copy assignment. If the other object contains an initialized value, then that value will be copied into the current object. If the other object is uninitialized, then the current object will be as well.
Any content of the current object is lost in the assignment.
Move assignment. If the other object contains an initialized value, then that value will be moved into the current object, and the other object will end up being empty (as if default initialized). If the other object is uninitialized, then the current object will be as well.
Any content of the current object is lost in the move assignment.
|
noexcept |
Reset the Lazy<T> object to an uninitialized state.
| void Lazy< T >::ensure_initialized | ( | const Callable & | creator | ) | const |
Initialize the wrapped object.
If the contained object is already initialized this function simply returns and does nothing.
If, instead, the object has not yet been initialized then the creator function object (oftentimes a lambda function) is called to initialize the contained object.
This operation is thread safe: The ensure_initialized() method guarantees that the creator function object is only called once on one of the calling threads and that after completion the initialization result (which is stored in the std::optional) is visible on all threads.
Returns true if the contained object has been initialized, otherwise false.
| const T & Lazy< T >::value | ( | ) | const |
Return a const reference to the contained object.
| const T & Lazy< T >::value_or_initialize | ( | const Callable & | creator | ) | const |
If the underlying object is initialized the function simply returns a const reference to the contained value. Otherwise, the creator() function object is called to initialize the object first.
This function mimics the syntax of the std::optional<T> interface and is functionally equivalent to calling ensure_initialized() followed by value(). It returns a const reference to make clear that the object created by the creator function is what it is, and is not subject to later modification unless one calls reset() and creates a new object.
| std::size_t Lazy< T >::memory_consumption | ( | ) | const |
Compute the memory consumption of this structure.
|
mutableprivate |