LLVM: include/llvm/Support/ErrorOr.h Source File (original) (raw)
57 template friend class ErrorOr;
58
59 static constexpr bool isRef = std::is_reference_v;
60
61 using wrap = std::reference_wrapper<std::remove_reference_t>;
62
63public:
64 using storage_type = std::conditional_t<isRef, wrap, T>;
65
66private:
67 using reference = std::remove_reference_t &;
68 using const_reference = const std::remove_reference_t &;
69 using pointer = std::remove_reference_t *;
70 using const_pointer = const std::remove_reference_t *;
71
72public:
73 template
75 std::enable_if_t<std::is_error_code_enum::value ||
76 std::is_error_condition_enum::value,
77 void *> = nullptr)
78 : HasError(true) {
79 new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
80 }
81
83 new (getErrorStorage()) std::error_code(EC);
84 }
85
86 template
88 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
89 : HasError(false) {
90 new (getStorage()) storage_type(std::forward(Val));
91 }
92
94 copyConstruct(Other);
95 }
96
97 template
99 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
100 copyConstruct(Other);
101 }
102
103 template
106 std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * = nullptr) {
107 copyConstruct(Other);
108 }
109
111 moveConstruct(std::move(Other));
112 }
113
114 template
116 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
117 moveConstruct(std::move(Other));
118 }
119
120
121
122 template
125 std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {
126 moveConstruct(std::move(Other));
127 }
128
130 copyAssign(Other);
131 return *this;
132 }
133
135 moveAssign(std::move(Other));
136 return *this;
137 }
138
140 if (!HasError)
141 getStorage()->~storage_type();
142 }
143
144
145 explicit operator bool() const {
146 return !HasError;
147 }
148
149 reference get() { return *getStorage(); }
150 const_reference get() const { return const_cast<ErrorOr *>(this)->get(); }
151
153 return HasError ? *getErrorStorage() : std::error_code();
154 }
155
157 return toPointer(getStorage());
158 }
159
160 const_pointer operator->() const { return toPointer(getStorage()); }
161
163 return *getStorage();
164 }
165
166 const_reference operator*() const { return *getStorage(); }
167
168private:
169 template
171 if (.HasError) {
172
173 HasError = false;
175 } else {
176
177 HasError = true;
178 new (getErrorStorage()) std::error_code(Other.getError());
179 }
180 }
181
182 template
183 static bool compareThisIfSameType(const T1 &a, const T1 &b) {
184 return &a == &b;
185 }
186
187 template <class T1, class T2>
188 static bool compareThisIfSameType(const T1 &, const T2 &) {
189 return false;
190 }
191
192 template
194 if (compareThisIfSameType(*this, Other))
195 return;
196
199 }
200
201 template
203 if (.HasError) {
204
205 HasError = false;
207 } else {
208
209 HasError = true;
210 new (getErrorStorage()) std::error_code(Other.getError());
211 }
212 }
213
214 template
216 if (compareThisIfSameType(*this, Other))
217 return;
218
221 }
222
223 pointer toPointer(pointer Val) {
224 return Val;
225 }
226
227 const_pointer toPointer(const_pointer Val) const { return Val; }
228
229 pointer toPointer(wrap *Val) {
230 return &Val->get();
231 }
232
233 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
234
236 assert(!HasError && "Cannot get value when an error exists!");
238 }
239
241 assert(!HasError && "Cannot get value when an error exists!");
243 }
244
245 std::error_code *getErrorStorage() {
246 assert(HasError && "Cannot get error when a value exists!");
248 }
249
250 const std::error_code *getErrorStorage() const {
251 assert(HasError && "Cannot get error when a value exists!");
253 }
254
255 union {
258 };
259 bool HasError : 1;
260};
267 return Err.getError() == Code;
268}