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:
36     /* NOLINTNEXTLINE(google-explicit-constructor) */
Expected(Type t)37     constexpr Expected(Type t) : hasValue_(true), value_(BASE_NS::move(t)) {}
38     /* NOLINTNEXTLINE(google-explicit-constructor) */
Expected(Error e)39     constexpr Expected(Error e) : error_(BASE_NS::move(e)) {}
~Expected()40     ~Expected()
41     {
42         if (hasValue_) {
43             value_.~Type();
44         }
45     }
META_DEFAULT_COPY_MOVE(Expected)46     META_DEFAULT_COPY_MOVE(Expected)
47 
48     /* NOLINTNEXTLINE(google-explicit-constructor) */
49     constexpr operator bool() const
50     {
51         return hasValue_;
52     }
53 
54     constexpr const Type& operator*() const
55     {
56         return GetValue();
57     }
58     constexpr Type& operator*()
59     {
60         return GetValue();
61     }
62 
GetError()63     constexpr Error GetError() const
64     {
65         return !hasValue_ ? error_ : Error {};
66     }
67 
GetValue()68     constexpr const Type& GetValue() const
69     {
70         CORE_ASSERT(hasValue_);
71         return value_;
72     }
GetValue()73     constexpr Type& GetValue()
74     {
75         CORE_ASSERT(hasValue_);
76         return value_;
77     }
78 
79 private:
80     bool hasValue_ {};
81     union {
82         Error error_;
83         Type value_;
84     };
85 };
86 
87 // we don't have is_enum so for now just specialising for GenericError
88 template<>
89 class Expected<void, GenericError> {
90 public:
91     constexpr Expected() = default;
92     /* NOLINTNEXTLINE(google-explicit-constructor) */
Expected(GenericError e)93     constexpr Expected(GenericError e) : error_(e) {}
94 
95     /* NOLINTNEXTLINE(google-explicit-constructor) */
96     constexpr operator bool() const
97     {
98         return error_ == 0;
99     }
100 
GetError()101     constexpr GenericError GetError() const
102     {
103         return error_;
104     }
105 
106 private:
107     GenericError error_ {};
108 };
109 
110 using ReturnError = Expected<void, GenericError>;
111 
112 template<typename Enum>
113 class ReturnValue {
114 public:
115     /* NOLINTNEXTLINE(google-explicit-constructor) */
ReturnValue(Enum code)116     constexpr ReturnValue(Enum code) : code_(code) {}
117 
118     /* NOLINTNEXTLINE(google-explicit-constructor) */
119     constexpr operator bool() const
120     {
121         return BASE_NS::underlying_type_t<Enum>(code_) > 0;
122     }
123 
GetCode()124     constexpr Enum GetCode() const
125     {
126         return code_;
127     }
128 
129     bool operator==(Enum v) const
130     {
131         return code_ == v;
132     }
133 
134     bool operator!=(Enum v) const
135     {
136         return code_ != v;
137     }
138 
139 private:
140     Enum code_ {};
141 };
142 
143 META_END_NAMESPACE()
144 
145 #endif
146