@@ -166,6 +166,8 @@ inline const void *_Nullable getErrorMetadata() {
166
166
return ptr2;
167
167
}
168
168
169
+ #ifndef SWIFT_CXX_INTEROP_HIDE_SWIFT_ERROR
170
+
169
171
class Error {
170
172
public:
171
173
Error () {}
@@ -213,4 +215,196 @@ class Error {
213
215
void *_Nonnull opaqueValue = nullptr ;
214
216
};
215
217
218
+ namespace _impl {
219
+
220
+ constexpr inline std::size_t max (std::size_t a, std::size_t b) {
221
+ return a > b ? a : b;
222
+ }
223
+
224
+ } // namespace _impl
225
+
226
+ // / The Expected class has either an error or an value.
227
+ template <class T >
228
+ class Expected {
229
+ public:
230
+
231
+ // / Default
232
+ constexpr Expected () noexcept {
233
+ new (&buffer) Error ();
234
+ has_val = false ;
235
+ }
236
+
237
+ constexpr Expected (const Swift::Error& error_val) noexcept {
238
+ new (&buffer) Error (error_val);
239
+ has_val = false ;
240
+ }
241
+
242
+ constexpr Expected (const T &val) noexcept {
243
+ new (&buffer) T (val);
244
+ has_val = true ;
245
+ }
246
+
247
+ // / Copy
248
+ constexpr Expected (Expected const & other) noexcept {
249
+ if (other.has_value ())
250
+ new (&buffer) T (other.value ());
251
+ else
252
+ new (&buffer) Error (other.error ());
253
+
254
+ has_val = other.has_value ();
255
+ }
256
+
257
+ // / Move
258
+ // FIXME: Implement move semantics when move Swift values is possible
259
+ constexpr Expected (Expected&&) noexcept { abort (); }
260
+
261
+ ~Expected () noexcept {
262
+ if (has_value ())
263
+ reinterpret_cast <const T *>(buffer)->~T ();
264
+ else
265
+ reinterpret_cast <Swift::Error *>(buffer)->~Error ();
266
+ }
267
+
268
+ // / assignment
269
+ constexpr auto operator =(Expected&& other) noexcept = delete ;
270
+ constexpr auto operator =(Expected&) noexcept = delete ;
271
+
272
+ // / For accessing T's members
273
+ constexpr T const *_Nonnull operator ->() const noexcept {
274
+ if (!has_value ())
275
+ abort ();
276
+ return reinterpret_cast <const T *>(buffer);
277
+ }
278
+
279
+ constexpr T *_Nonnull operator ->() noexcept {
280
+ if (!has_value ())
281
+ abort ();
282
+ return reinterpret_cast <T *>(buffer);
283
+ }
284
+
285
+ // / Getting reference to T
286
+ constexpr T const &operator *() const & noexcept {
287
+ if (!has_value ())
288
+ abort ();
289
+ return reinterpret_cast <const T &>(buffer);
290
+ }
291
+
292
+ constexpr T &operator *() & noexcept {
293
+ if (!has_value ())
294
+ abort ();
295
+ return reinterpret_cast <T &>(buffer);
296
+ }
297
+
298
+ constexpr explicit operator bool () const noexcept { return has_value (); }
299
+
300
+ // Get value, if not exists abort
301
+ constexpr T const & value () const & {
302
+ if (!has_value ())
303
+ abort ();
304
+ return *reinterpret_cast <const T *>(buffer);
305
+ }
306
+
307
+ constexpr T& value () & {
308
+ if (!has_value ())
309
+ abort ();
310
+ return *reinterpret_cast <T *>(buffer);
311
+ }
312
+
313
+ // Get error
314
+ constexpr Swift::Error const & error () const & {
315
+ if (has_value ())
316
+ abort ();
317
+ return reinterpret_cast <const Swift::Error&>(buffer);
318
+ }
319
+
320
+ constexpr Swift::Error& error () & {
321
+ if (has_value ())
322
+ abort ();
323
+ return reinterpret_cast <Swift::Error&>(buffer);
324
+ }
325
+
326
+ constexpr bool has_value () const noexcept { return has_val; }
327
+
328
+ private:
329
+ alignas (_impl::max(alignof (T), alignof (Swift::Error))) char buffer[_impl::max(sizeof (T), sizeof (Swift::Error))];
330
+ bool has_val;
331
+ };
332
+
333
+ template <>
334
+ class Expected <void > {
335
+ public:
336
+ // / Default
337
+ Expected () noexcept {
338
+ new (&buffer) Error ();
339
+ has_val = false ;
340
+ }
341
+
342
+ Expected (const Swift::Error& error_val) noexcept {
343
+ new (&buffer) Error (error_val);
344
+ has_val = false ;
345
+ }
346
+
347
+
348
+ // / Copy
349
+ Expected (Expected const & other) noexcept {
350
+ if (other.has_value ())
351
+ abort ();
352
+ else
353
+ new (&buffer) Error (other.error ());
354
+
355
+ has_val = other.has_value ();
356
+ }
357
+
358
+ // / Move
359
+ // FIXME: Implement move semantics when move swift values is possible
360
+ [[noreturn]] Expected(Expected&&) noexcept { abort (); }
361
+
362
+ ~Expected () noexcept {
363
+ reinterpret_cast <Swift::Error *>(buffer)->~Error ();
364
+ }
365
+
366
+ // / assignment
367
+ constexpr auto operator =(Expected&& other) noexcept = delete ;
368
+ constexpr auto operator =(Expected&) noexcept = delete ;
369
+
370
+
371
+ constexpr explicit operator bool () const noexcept { return has_value (); }
372
+
373
+ // Get error
374
+ constexpr Swift::Error const & error () const & {
375
+ if (has_value ())
376
+ abort ();
377
+ return reinterpret_cast <const Swift::Error&>(buffer);
378
+ }
379
+
380
+ constexpr Swift::Error& error () & {
381
+ if (has_value ())
382
+ abort ();
383
+ return reinterpret_cast <Swift::Error&>(buffer);
384
+ }
385
+
386
+ constexpr bool has_value () const noexcept { return has_val; }
387
+ private:
388
+ alignas (alignof (Swift::Error)) char buffer[sizeof (Swift::Error)];
389
+ bool has_val;
390
+ };
391
+
392
+ #ifdef __cpp_exceptions
393
+
394
+ template <class T >
395
+ using ThrowingResult = T;
396
+
397
+ #define SWIFT_RETURN_THUNK (T, v ) v
398
+
399
+ #else
400
+
401
+ template <class T >
402
+ using ThrowingResult = Swift::Expected<T>;
403
+
404
+ #define SWIFT_RETURN_THUNK (T, v ) Swift::Expected<T>(v)
405
+
406
+ #endif
407
+
408
+ #endif // SWIFT_CXX_INTEROP_HIDE_SWIFT_ERROR
409
+
216
410
#endif
0 commit comments