• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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