template <typename T>
+DEAL_II_CXX20_REQUIRES((std::is_move_constructible_v<T> &&
+ std::is_move_assignable_v<T>))
inline Lazy<T>::Lazy(Lazy &&other) noexcept
- : object(other.object)
+ : object(std::move(other.object))
{
object_is_initialized.store(other.object_is_initialized.load());
+
+ // Mark the other object as uninitialized. This is marginally non-trivial
+ // because moving from std::optional<T> does *not* result in an empty
+ // std::optional<T> but instead one that does contain a T, but one that
+ // has been moved from -- typically something akin to a default-initialized
+ // T. That seems undesirable, so reset everything to an empty state.
+ other.object_is_initialized.store(false);
+ other.object.reset();
}
template <typename T>
-inline Lazy<T> &
-Lazy<T>::operator=(Lazy &&other) noexcept
+DEAL_II_CXX20_REQUIRES((std::is_move_constructible_v<T> &&
+ std::is_move_assignable_v<T>))
+inline Lazy<T> &Lazy<T>::operator=(Lazy &&other) noexcept
{
- object = other.object;
+ object = std::move(other.object);
object_is_initialized.store(other.object_is_initialized.load());
+
+ // Mark the other object as uninitialized. This is marginally non-trivial
+ // because moving from std::optional<T> does *not* result in an empty
+ // std::optional<T> but instead one that does contain a T, but one that
+ // has been moved from -- typically something akin to a default-initialized
+ // T. That seems undesirable, so reset everything to an empty state.
+ other.object_is_initialized.store(false);
+ other.object.reset();
+
return *this;
}