From a82c60b22a7fb616306f2246f8b7d2e1058ccabc Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 30 Jul 2019 17:20:34 +0200 Subject: [PATCH] Add Result<>, to use with/complement Error An operation often has two pieces of underlying information: * the data returned as a result from that operation * an error that occurred while retrieving that data Merely returning the data is not good enough. Result<> allows exposing both the data, and the underlying error, and forces (via clang's consumable attribute) you to check for the error before you try to access the data. --- AK/Result.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 AK/Result.h diff --git a/AK/Result.h b/AK/Result.h new file mode 100644 index 00000000000..64997f6d20c --- /dev/null +++ b/AK/Result.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include + +namespace AK { + +template +class CONSUMABLE(unknown) Result { +public: + RETURN_TYPESTATE(unknown) + Result(const T& res) + : m_result(res) + {} + + RETURN_TYPESTATE(unknown) + Result(const E& error) + : m_error(error) + { + } + + RETURN_TYPESTATE(unknown) + Result(const T& res, const E& error) + : m_result(res) + , m_error(error) + { + } + + RETURN_TYPESTATE(unknown) + Result(Result&& other) + : m_result(move(other.m_result)) + , m_error(move(other.m_error)) + { + } + + RETURN_TYPESTATE(unknown) + Result(Result& other) + : m_result(other.m_result) + , m_error(other.m_error) + { + } + + CALLABLE_WHEN("unknown", "consumed") + ~Result() + {} + + CALLABLE_WHEN(consumed) + T& unwrap() { + return m_result.value(); + } + + CALLABLE_WHEN(consumed) + E& error() { + return m_error.value(); + } + + bool has_error() const { + return m_error.has_value(); + } + bool has_value() const { + return m_result.has_value(); + } + + SET_TYPESTATE(consumed) + bool failed() const { + return m_error.value().failed(); + } + +private: + Optional m_result; + Optional m_error; +}; + +} + +using AK::Result; +