1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef META_BASE_EXPECTED_H 16 #define META_BASE_EXPECTED_H 17 18 #include <core/log.h> 19 20 #include <meta/base/interface_macros.h> 21 #include <meta/base/meta_types.h> 22 #include <meta/base/namespace.h> 23 24 META_BEGIN_NAMESPACE() 25 26 enum GenericError : int16_t { 27 SUCCESS = 0, 28 FAIL = -1, 29 INVALID_ARGUMENT = -2, 30 INCOMPATIBLE_TYPES = -3, 31 NOT_FOUND = -4, 32 RECURSIVE_CALL = -5, 33 NOT_SUPPORTED = -6 34 }; 35 36 /** 37 * @brief The class template Expected provides a way to represent either of two values: 38 * an expected value of type Type, or an unexpected value of type Error. 39 * @Notice Expected is never valueless. 40 */ 41 template<typename Type, typename Error> 42 class Expected { 43 public: Expected(Type t)44 constexpr Expected(Type t) : hasValue_(true), value_(BASE_NS::move(t)) {} Expected(Error e)45 constexpr Expected(Error e) : error_(BASE_NS::move(e)) {} 46 ~Expected()47 ~Expected() 48 { 49 if (hasValue_) { 50 value_.~Type(); 51 } else { 52 error_.~Error(); 53 } 54 } 55 Expected(const Expected & e)56 constexpr Expected(const Expected& e) : hasValue_(e.hasValue_) 57 { 58 if (hasValue_) { 59 new (&value_) Type(e.GetValue()); 60 } else { 61 new (&error_) Error(e.GetError()); 62 } 63 } 64 65 Expected(Expected&&) = delete; 66 Expected& operator=(const Expected&) = delete; 67 Expected& operator=(Expected&&) = delete; 68 69 constexpr operator bool() const 70 { 71 return hasValue_; 72 } 73 74 constexpr const Type& operator*() const 75 { 76 return GetValue(); 77 } 78 constexpr Type& operator*() 79 { 80 return GetValue(); 81 } 82 GetError()83 constexpr Error GetError() const 84 { 85 return !hasValue_ ? error_ : Error {}; 86 } 87 GetValue()88 constexpr const Type& GetValue() const 89 { 90 CORE_ASSERT(hasValue_); 91 return value_; 92 } GetValue()93 constexpr Type& GetValue() 94 { 95 CORE_ASSERT(hasValue_); 96 return value_; 97 } 98 99 private: 100 bool hasValue_ {}; 101 union { 102 Error error_; 103 Type value_; 104 }; 105 }; 106 107 /// Expected specialisation for GenericError to present success or error value 108 template<> 109 class Expected<void, GenericError> { 110 public: 111 constexpr Expected() = default; Expected(GenericError e)112 constexpr Expected(GenericError e) : error_(e) {} 113 114 constexpr operator bool() const 115 { 116 return error_ == 0; 117 } 118 GetError()119 constexpr GenericError GetError() const 120 { 121 return error_; 122 } 123 124 private: 125 GenericError error_ {}; 126 }; 127 128 using ReturnError = Expected<void, GenericError>; 129 130 /// Helper template to map enum return codes to success when positive 131 template<typename Enum> 132 class ReturnValue { 133 public: ReturnValue(Enum code)134 constexpr ReturnValue(Enum code) : code_(code) {} 135 136 constexpr operator bool() const 137 { 138 return BASE_NS::underlying_type_t<Enum>(code_) > 0; 139 } 140 GetCode()141 constexpr Enum GetCode() const 142 { 143 return code_; 144 } 145 146 bool operator==(Enum v) const 147 { 148 return code_ == v; 149 } 150 151 bool operator!=(Enum v) const 152 { 153 return code_ != v; 154 } 155 156 private: 157 Enum code_ {}; 158 }; 159 160 META_END_NAMESPACE() 161 162 #endif 163