From e18ca9bfe094a04d2309e110c6f364a790b70d01 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 10 Oct 2023 22:11:12 +0200 Subject: [PATCH] libos: Document Action.h --- libos/include/os/Action.h | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/libos/include/os/Action.h b/libos/include/os/Action.h index f49e100b..530ec178 100644 --- a/libos/include/os/Action.h +++ b/libos/include/os/Action.h @@ -12,24 +12,57 @@ namespace os { + /** + * @brief Wrapper for callable objects. + * + * Certain callable types such as capture lambdas don't have a named type, thus they can't be passed to functions as + * arguments. The Action type acts as a callable wrapper for such functions, allowing them to be passed as arguments + * to any function. + */ class Action { public: + /** + * @brief Construct a new empty Action object. + * + * Since it is not wrapping any callable object, this object is invalid and attempting to invoke its + * (nonexistent) callable object will result in a crash at runtime. + */ Action() { m_action = nullptr; } + /** + * @brief Construct a new Action object, moving it from another one. + * + * @param other The old Action object to move from. This object will become invalid. + */ Action(Action&& other) : m_action(other.m_action) { other.m_action = nullptr; } + /** + * @brief Construct a new Action object from a callable object. + * + * @tparam T The type of the callable object. Since this can be guessed by template deduction, the object + * doesn't actually need a type name. + * @param function The callable object to wrap. + */ template Action(T&& function) { m_action = new (std::nothrow) ActionImpl(move(function)); } + /** + * @brief Assign a new callable object to this Action. + * + * @tparam T The type of the callable object. Since this can be guessed by template deduction, the object + * doesn't actually need a type name. + * @param function The callable object to wrap. + * @return Action& A reference to this object, as required by operator=(). + */ template Action& operator=(T&& function) { if (m_action) delete m_action; @@ -37,9 +70,12 @@ namespace os return *this; } + /** + * @brief Call the underlying object. + */ void operator()() { - check(m_action); + expect(m_action, "os::Action called with no underlying callable object"); return m_action->call(); }