#pragma once #include "hot_reload/Status.hpp" #include #include /** * @file Result.hpp * @brief hot_reload::Result -- what Context::load() and Context::reload() return. */ namespace hot_reload { /** * @brief The outcome of one Context::load() or Context::reload() call: a Status, and the * platform's own message when that status is a failure worth explaining. * * This replaces the C API's split between a returned `HotReloadStatus` and a separate, * stateful `hot_reload_last_error()` call: every Result is self-contained, which is what * makes it safe to use from multiple threads without the two ever referring to different * calls -- see Context.hpp's own thread-safety note for why that split is not just a style * preference here. * * @code * hot_reload::Result result = ctx.load("plugin", "plugin.so"); * if (!result) // or !result.ok() * { * std::cerr << hot_reload::toString(result.status()) << ": " << result.message() << '\n'; * } * @endcode */ class Result { public: /** * @brief Constructs a successful result. * @return A Result whose status() is Status::Ok and whose message() is empty. */ [[nodiscard]] static Result success() noexcept; /** * @brief Constructs a failed result. * @param status The failure's status; must not be Status::Ok (use ok() for that). * @param message Why, in the platform's own words where there is one (see each * Status enumerator's own doc comment for what it carries); may be empty for a * failure that is fully explained by its status alone. * @return A Result whose status() is @p status and whose message() is @p message. */ [[nodiscard]] static Result failure(Status status, std::string message = {}) noexcept; /** * @brief Whether this result represents success. * @return True if status() is Status::Ok. */ [[nodiscard]] bool ok() const noexcept { return m_status == Status::Ok; } /// Equivalent to ok() -- lets a Result be used directly as `if (result)`. [[nodiscard]] explicit operator bool() const noexcept { return ok(); } /** * @brief This result's status. * @return The status passed to failure(), or Status::Ok for ok(). */ [[nodiscard]] Status status() const noexcept { return m_status; } /** * @brief This result's message. * @return The message passed to failure(), or empty for ok() or a status that needed no * further explanation. */ [[nodiscard]] const std::string& message() const noexcept { return m_message; } private: Result(Status status, std::string message) noexcept : m_status(status) , m_message(std::move(message)) { } Status m_status; std::string m_message; }; }