/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #pragma once #include #include #include namespace Aws { namespace Utils { /** * Template class representing the outcome of making a request. It will contain * either a successful result or the failure error. The caller must check * whether the outcome of the request was a success before attempting to access * the result or the error. */ template // Result, Error class Outcome { public: Outcome() : success(false) { } Outcome(const R& r) : result(r), success(true) { } Outcome(const E& e) : error(e), success(false) { } Outcome(R&& r) : result(std::forward(r)), success(true) { } Outcome(E&& e) : error(std::forward(e)), success(false) { } Outcome(const Outcome& o) : result(o.result), error(o.error), success(o.success) { } template friend class Outcome; #if defined (__cplusplus) && __cplusplus > 201103L template< bool B, class T = void > using enable_if_t = std::enable_if_t; #else template< bool B, class T = void > using enable_if_t = typename std::enable_if::type; #endif // Move both result and error from other type of outcome template::value && std::is_convertible::value, int> = 0> Outcome(Outcome&& o) : result(std::move(o.result)), error(std::move(o.error)), success(o.success) { } // Move result from other type of outcome template::value && !std::is_convertible::value, int> = 0> Outcome(Outcome&& o) : result(std::move(o.result)), success(o.success) { assert(o.success); } // Move error from other type of outcome template::value && std::is_convertible::value, int> = 0> Outcome(Outcome&& o) : error(std::move(o.error)), success(o.success) { assert(!o.success); } template::value, int> = 0> Outcome(ET&& e) : error(std::forward(e)), success(false) { } Outcome& operator=(const Outcome& o) { if (this != &o) { result = o.result; error = o.error; success = o.success; } return *this; } Outcome(Outcome&& o) : // Required to force Move Constructor result(std::move(o.result)), error(std::move(o.error)), success(o.success) { } Outcome& operator=(Outcome&& o) { if (this != &o) { result = std::move(o.result); error = std::move(o.error); success = o.success; } return *this; } inline const R& GetResult() const { return result; } inline R& GetResult() { return result; } /** * casts the underlying result to an r-value so that caller can take ownership of underlying resources. * this is necessary when streams are involved. */ inline R&& GetResultWithOwnership() { return std::move(result); } inline const E& GetError() const { return error; } template inline T GetError() { return error.template GetModeledError(); } inline bool IsSuccess() const { return this->success; } private: R result; E error; bool success; }; } // namespace Utils } // namespace Aws