// ------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // ------------------------------------------------------------ #pragma once #include "Failure.h" #include namespace cdb_core { /// /// Result is analogous to an "Either" - holds a successful /// result or a failure. Result<> is a value type. /// template class [[nodiscard]] Result { public: constexpr Result(TResult result) noexcept; constexpr Result(Failure failure) noexcept; Result(Result&&) noexcept = default; ~Result() = default; Result& operator=(Result&&) noexcept = default; [[nodiscard]] bool IsSuccess() const; TResult GetResult(); [[nodiscard]] Failure GetFailure() const noexcept; private: std::variant m_value; }; template constexpr Result::Result(TResult result) noexcept : m_value{ std::in_place_index<0>, std::move(result) } { } template constexpr Result::Result(Failure failure) noexcept : m_value{ std::in_place_index<1>, std::move(failure) } { } template TResult Result::GetResult() { Contract::Requires(IsSuccess()); return std::move(std::get<0>(m_value)); } template bool Result::IsSuccess() const { return m_value.index() == 0; } template Failure Result::GetFailure() const noexcept { Contract::Requires(!IsSuccess()); return std::move(std::get<1>(m_value)); } template<> class [[nodiscard]] Result { public: Result(); explicit Result(Failure failure); Result(const Result&) = default; Result(Result&&) = default; Result& operator=(const Result&) = default; Result& operator=(Result&&) = default; [[nodiscard]] bool IsSuccess() const noexcept; [[nodiscard]] Failure GetFailure() const noexcept; private: Failure m_failure; }; inline Result::Result() : m_failure(Failure::None) { } inline Result::Result(Failure failure) : m_failure(failure) { Contract::Requires(failure.IsFailed(), "Result constructed with Failure must be failed. Use Result() if no failure occurred"); } inline bool Result::IsSuccess() const noexcept { return !m_failure.IsFailed(); } inline Failure Result::GetFailure() const noexcept { return m_failure; } }