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 <meta/base/interface_macros.h> 19 #include <meta/base/meta_types.h> 20 #include <meta/base/namespace.h> 21 22 META_BEGIN_NAMESPACE() 23 24 enum GenericError : int16_t { 25 SUCCESS = 0, 26 FAIL = -1, 27 INVALID_ARGUMENT = -2, 28 INCOMPATIBLE_TYPES = -3, 29 NOT_FOUND = -4, 30 RECURSIVE_CALL = -5, 31 }; 32 33 template<typename Type, typename Error> 34 class Expected { 35 public: Expected(Type t)36 constexpr Expected(Type t) : hasValue_(true), value_(BASE_NS::move(t)) {} Expected(Error e)37 constexpr Expected(Error e) : error_(BASE_NS::move(e)) {} ~Expected()38 ~Expected() 39 { 40 if (hasValue_) { 41 value_.~Type(); 42 } else { 43 error_.~Error(); 44 } 45 } 46 Expected(const Expected & e)47 constexpr Expected(const Expected& e) : hasValue_(e.hasValue_) 48 { 49 if (hasValue_) { 50 new (&value_) Type(e.GetValue()); 51 } else { 52 new (&error_) Error(e.GetError()); 53 } 54 } 55 56 Expected(Expected&&) = delete; 57 Expected& operator=(const Expected&) = delete; 58 Expected& operator=(Expected&&) = delete; 59 constexpr operator bool() const 60 { 61 return hasValue_; 62 } 63 64 constexpr const Type& operator*() const 65 { 66 return GetValue(); 67 } 68 constexpr Type& operator*() 69 { 70 return GetValue(); 71 } 72 GetError()73 constexpr Error GetError() const 74 { 75 return !hasValue_ ? error_ : Error {}; 76 } 77 GetValue()78 constexpr const Type& GetValue() const 79 { 80 CORE_ASSERT(hasValue_); 81 return value_; 82 } GetValue()83 constexpr Type& GetValue() 84 { 85 CORE_ASSERT(hasValue_); 86 return value_; 87 } 88 89 private: 90 bool hasValue_ {}; 91 union { 92 Error error_; 93 Type value_; 94 }; 95 }; 96 97 // we don't have is_enum so for now just specialising for GenericError 98 template<> 99 class Expected<void, GenericError> { 100 public: 101 constexpr Expected() = default; Expected(GenericError e)102 constexpr Expected(GenericError e) : error_(e) {} 103 104 constexpr operator bool() const 105 { 106 return error_ == 0; 107 } 108 GetError()109 constexpr GenericError GetError() const 110 { 111 return error_; 112 } 113 114 private: 115 GenericError error_ {}; 116 }; 117 118 using ReturnError = Expected<void, GenericError>; 119 120 template<typename Enum> 121 class ReturnValue { 122 public: ReturnValue(Enum code)123 constexpr ReturnValue(Enum code) : code_(code) {} 124 125 constexpr operator bool() const 126 { 127 return BASE_NS::underlying_type_t<Enum>(code_) > 0; 128 } 129 GetCode()130 constexpr Enum GetCode() const 131 { 132 return code_; 133 } 134 135 bool operator==(Enum v) const 136 { 137 return code_ == v; 138 } 139 140 bool operator!=(Enum v) const 141 { 142 return code_ != v; 143 } 144 145 private: 146 Enum code_ {}; 147 }; 148 149 META_END_NAMESPACE() 150 151 #endif 152