From a22799332f69a2f49069f21e61da6c50a2f85def Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 23 Jul 2024 16:27:40 -0600 Subject: [PATCH] Obey the rule of 5 or 7. --- include/deal.II/base/task_result.h | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/deal.II/base/task_result.h b/include/deal.II/base/task_result.h index fa62e99f0a..54f706b7cf 100644 --- a/include/deal.II/base/task_result.h +++ b/include/deal.II/base/task_result.h @@ -182,6 +182,22 @@ namespace Threads */ ~TaskResult(); + /** + * Copy operator. Like the copy constructor, this function is deleted + * because TaskResult corresponds to the output of a specific task, + * not a copy of that tasks's outcome. + */ + TaskResult & + operator=(const TaskResult &) = delete; + + /** + * Move assignment operator. Following this call, the newly created object + * represents the task's result, whereas the old object no longer + * represents anything and is left as if default-constructed. + */ + TaskResult & + operator=(TaskResult &&); + /** * Copy assignment operator from a Task object. By assigning the Task * object to the current object, the current object is set to represent @@ -426,6 +442,33 @@ namespace Threads } + template + inline TaskResult & + TaskResult::operator=(TaskResult &&other) + { + // First clear the current object before we put new content into it: + clear(); + + // Then lock the other object and move the members of the other + // object, and finally reset it. Note that we do not have to wait for + // the other object's task to finish (nor should we): We may simply + // inherit the other object's task. + std::lock_guard lock(other.mutex); + + result_is_available = other.result_is_available.load(); + other.result_is_available = false; + + task = std::move(other.task); + other.task.reset(); + + task_result = std::move(other.task_result); + other.task_result.reset(); + + return *this; + } + + + template template void -- 2.39.5