diff --git a/common/error_code.hpp b/common/error_code.hpp index cbc2744c..f8bde035 100644 --- a/common/error_code.hpp +++ b/common/error_code.hpp @@ -22,25 +22,39 @@ #include #include #include +#include namespace snapcast { +/// Error codes with detail information struct ErrorCode : public std::error_code { + /// c'tor ErrorCode() : std::error_code(), detail_(std::nullopt) { } + /// c'tor + /// @param code the std error code ErrorCode(const std::error_code& code) : std::error_code(code), detail_(std::nullopt) { } + /// c'tor + /// @param code the std error code + /// @param detail additional details ErrorCode(const std::error_code& code, std::string detail) : std::error_code(code), detail_(std::move(detail)) { } + /// Move c'tor + ErrorCode(ErrorCode&& other) = default; + /// Move assignment + ErrorCode& operator=(ErrorCode&& rhs) = default; + + /// @return detaiƶed error message std::string detailed_message() const { if (detail_.has_value()) @@ -49,8 +63,76 @@ struct ErrorCode : public std::error_code } private: + /// Optional error detais std::optional detail_; }; +/// Storage for an ErrorCode or a type T +/// Mostly used as return type +template +struct ErrorOr +{ + /// Move construct with @p t + ErrorOr(T&& t) : var(std::move(t)) + { + } + + /// Construct with @p t + ErrorOr(const T& t) : var(t) + { + } + + /// Move construct with an error + ErrorOr(ErrorCode&& error) : var(std::move(error)) + { + } + + /// Construct with an error + ErrorOr(const ErrorCode& error) : var(error) + { + } + + /// @return true if contains a value (i.e. no error) + bool hasValue() + { + return std::holds_alternative(var); + } + + /// @return true if contains an error (i.e. no value) + bool hasError() + { + return std::holds_alternative(var); + } + + /// @return the value + const T& getValue() + { + return std::get(var); + } + + /// @return the moved value + T takeValue() + { + return std::move(std::get(var)); + } + + /// @return the error + const ErrorCode& getError() + { + return std::get(var); + } + + /// @return the moved error + ErrorCode takeError() + { + return std::move(std::get(var)); + } + +private: + /// The stored ErrorCode or value + std::variant var; +}; + + } // namespace snapcast