9
9
#define ELFLDR_EXPECTED_H
10
10
11
11
#include < runtime/Assert.h>
12
+ #include < runtime/detail/DeferredHolder.h>
12
13
#include < runtime/Utility.h>
13
14
#include < stdint.h>
14
15
15
16
namespace elfldr {
16
17
17
- // MAYBE: Move this to a shared spot, so we can do
18
- // Maybe<T> (or Optional<T>)
19
- namespace detail {
20
-
21
- /* *
22
- * A safe deferred container for class types.
23
- * Performs no heap allocations.
24
- */
25
- template <class T >
26
- struct DeferredHolderFor {
27
- constexpr ~DeferredHolderFor () {
28
- if (constructed)
29
- Get ()->~T ();
30
- }
31
-
32
- constexpr DeferredHolderFor () = default; // do not initalize anything
33
-
34
- explicit DeferredHolderFor (const T& t) {
35
- // call the copy constructor
36
- Construct (t);
37
- }
38
-
39
- constexpr DeferredHolderFor& operator =(const DeferredHolderFor& df) {
40
- if (this == &df)
41
- return *this ;
42
-
43
- (*this ->Get ()) = (*df->Get ());
44
- }
45
-
46
- constexpr DeferredHolderFor& operator =(const T& t) {
47
- Construct (t);
48
- }
49
-
50
- template <class ... Args>
51
- constexpr void Construct (Args&&... args) {
52
- if (constructed)
53
- Destruct ();
54
-
55
- // construct new T
56
- constructed = true ;
57
- new (Get ()) T (Forward<Args>(args)...);
58
- }
59
-
60
- constexpr void Destruct () {
61
- if (constructed) {
62
- constructed = false ;
63
- Get ()->~T ();
64
- }
65
- }
66
-
67
- [[nodiscard]] constexpr bool IsConstructed () const {
68
- return constructed;
69
- }
70
-
71
- constexpr T& GetConstructed () {
72
- ELFLDR_ASSERT (constructed);
73
- return *Get ();
74
- }
75
-
76
- constexpr const T& GetConstructed () const {
77
- ELFLDR_ASSERT (constructed);
78
- return *Get ();
79
- }
80
-
81
- private:
82
- constexpr T* Get () {
83
- return UBCast<T*>(&storage[0 ]);
84
- }
85
-
86
- constexpr const T* Get () const {
87
- return UBCast<const T*>(&storage[0 ]);
88
- }
89
-
90
- bool constructed { false };
91
- alignas (T) uint8_t storage[sizeof (T)] {};
92
- };
93
-
94
- } // namespace detail
95
-
96
18
/* *
97
19
* A class template for working with deterministic errors.
98
20
* \tparam T Return type. Can be void
@@ -103,26 +25,26 @@ namespace elfldr {
103
25
constexpr Expected () = default;
104
26
105
27
constexpr Expected (const T& t) // NOLINT
106
- : t (t) {
28
+ : value (t) {
107
29
}
108
30
109
31
constexpr Expected (const E& e) // NOLINT
110
- : e (e) {
32
+ : error (e) {
111
33
}
112
34
113
35
constexpr Expected& operator =(const T& t) {
114
- if (e .IsConstructed ())
115
- e .Destruct ();
36
+ if (error .IsConstructed ())
37
+ error .Destruct ();
116
38
117
- this ->t = t;
39
+ this ->value = t;
118
40
return *this ;
119
41
}
120
42
121
43
constexpr Expected& operator =(const E& e) {
122
- if (t .IsConstructed ())
123
- t .Destruct ();
44
+ if (value .IsConstructed ())
45
+ value .Destruct ();
124
46
125
- this ->e = e;
47
+ this ->error = e;
126
48
return *this ;
127
49
}
128
50
@@ -134,37 +56,37 @@ namespace elfldr {
134
56
this ->t = e.Value ();
135
57
136
58
if (e.HasError ())
137
- this ->e = e.Error ();
59
+ this ->error = e.Error ();
138
60
139
61
return *this ;
140
62
}
141
63
142
64
[[nodiscard]] constexpr bool HasError () const {
143
- return e .IsConstructed ();
65
+ return error .IsConstructed ();
144
66
}
145
67
146
68
[[nodiscard]] constexpr bool HasValue () const {
147
- return t .IsConstructed ();
69
+ return value .IsConstructed ();
148
70
}
149
71
150
72
constexpr T& Value () {
151
73
ELFLDR_VERIFY (HasValue () && !HasError ());
152
- return t .GetConstructed ();
74
+ return value .GetConstructed ();
153
75
}
154
76
155
77
constexpr E& Error () {
156
78
ELFLDR_VERIFY (!HasValue () && HasError ());
157
- return e .GetConstructed ();
79
+ return error .GetConstructed ();
158
80
}
159
81
160
82
constexpr const T& Value () const {
161
83
ELFLDR_VERIFY (HasValue () && !HasError ());
162
- return t .GetConstructed ();
84
+ return value .GetConstructed ();
163
85
}
164
86
165
87
constexpr const E& Error () const {
166
88
ELFLDR_VERIFY (!HasValue () && HasError ());
167
- return e .GetConstructed ();
89
+ return error .GetConstructed ();
168
90
}
169
91
170
92
// Dereference operators.
@@ -187,20 +109,20 @@ namespace elfldr {
187
109
}
188
110
189
111
private:
190
- detail::DeferredHolderFor <T> t ;
191
- detail::DeferredHolderFor <E> e ;
112
+ detail::DeferredHolder <T> value ;
113
+ detail::DeferredHolder <E> error ;
192
114
};
193
115
194
116
template <class E >
195
117
struct Expected <void , E> {
196
118
constexpr Expected () = default;
197
119
198
120
constexpr Expected (const E& e) // NOLINT
199
- : e (e) {
121
+ : error (e) {
200
122
}
201
123
202
124
constexpr Expected& operator =(const E& e) {
203
- this ->e = e;
125
+ this ->error = e;
204
126
return *this ;
205
127
}
206
128
@@ -209,27 +131,27 @@ namespace elfldr {
209
131
return *this ;
210
132
211
133
if (e.HasError ())
212
- this ->e = e.Error ();
134
+ this ->error = e.Error ();
213
135
214
136
return *this ;
215
137
}
216
138
217
139
[[nodiscard]] constexpr bool HasError () const {
218
- return e .IsConstructed ();
140
+ return error .IsConstructed ();
219
141
}
220
142
221
143
constexpr E& Error () {
222
144
ELFLDR_ASSERT (HasError ());
223
- return e .GetConstructed ();
145
+ return error .GetConstructed ();
224
146
}
225
147
226
148
constexpr const E& Error () const {
227
149
ELFLDR_ASSERT (HasError ());
228
- return e .GetConstructed ();
150
+ return error .GetConstructed ();
229
151
}
230
152
231
153
private:
232
- detail::DeferredHolderFor <E> e ;
154
+ detail::DeferredHolder <E> error ;
233
155
};
234
156
235
157
template <class E >
0 commit comments