xref: /freebsd/contrib/llvm-project/libcxx/include/__expected/expected.h (revision 7ef62cebc2f965b0f640263e179276928885e33d)
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___EXPECTED_EXPECTED_H
10 #define _LIBCPP___EXPECTED_EXPECTED_H
11 
12 #include <__assert>
13 #include <__config>
14 #include <__expected/bad_expected_access.h>
15 #include <__expected/unexpect.h>
16 #include <__expected/unexpected.h>
17 #include <__memory/addressof.h>
18 #include <__memory/construct_at.h>
19 #include <__type_traits/conjunction.h>
20 #include <__type_traits/disjunction.h>
21 #include <__type_traits/is_assignable.h>
22 #include <__type_traits/is_constructible.h>
23 #include <__type_traits/is_convertible.h>
24 #include <__type_traits/is_copy_assignable.h>
25 #include <__type_traits/is_copy_constructible.h>
26 #include <__type_traits/is_default_constructible.h>
27 #include <__type_traits/is_function.h>
28 #include <__type_traits/is_move_assignable.h>
29 #include <__type_traits/is_move_constructible.h>
30 #include <__type_traits/is_nothrow_constructible.h>
31 #include <__type_traits/is_nothrow_copy_assignable.h>
32 #include <__type_traits/is_nothrow_copy_constructible.h>
33 #include <__type_traits/is_nothrow_default_constructible.h>
34 #include <__type_traits/is_nothrow_move_assignable.h>
35 #include <__type_traits/is_nothrow_move_constructible.h>
36 #include <__type_traits/is_reference.h>
37 #include <__type_traits/is_same.h>
38 #include <__type_traits/is_swappable.h>
39 #include <__type_traits/is_trivially_copy_constructible.h>
40 #include <__type_traits/is_trivially_destructible.h>
41 #include <__type_traits/is_trivially_move_constructible.h>
42 #include <__type_traits/is_void.h>
43 #include <__type_traits/lazy.h>
44 #include <__type_traits/negation.h>
45 #include <__type_traits/remove_cv.h>
46 #include <__type_traits/remove_cvref.h>
47 #include <__utility/exception_guard.h>
48 #include <__utility/forward.h>
49 #include <__utility/in_place.h>
50 #include <__utility/move.h>
51 #include <__utility/swap.h>
52 #include <cstdlib> // for std::abort
53 #include <initializer_list>
54 
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 #  pragma GCC system_header
57 #endif
58 
59 #if _LIBCPP_STD_VER >= 23
60 
61 _LIBCPP_BEGIN_NAMESPACE_STD
62 
63 namespace __expected {
64 
65 template <class _Err, class _Arg>
66 _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
67 #  ifndef _LIBCPP_NO_EXCEPTIONS
68   throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
69 #  else
70   (void)__arg;
71   std::abort();
72 #  endif
73 }
74 
75 } // namespace __expected
76 
77 template <class _Tp, class _Err>
78 class expected {
79   static_assert(
80       !is_reference_v<_Tp> &&
81           !is_function_v<_Tp> &&
82           !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
83           !is_same_v<remove_cv_t<_Tp>, unexpect_t> &&
84           !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
85           __valid_std_unexpected<_Err>::value
86       ,
87       "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
88       "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
89       "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
90       "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
91       "template argument for unexpected is ill-formed.");
92 
93   template <class _Up, class _OtherErr>
94   friend class expected;
95 
96 public:
97   using value_type      = _Tp;
98   using error_type      = _Err;
99   using unexpected_type = unexpected<_Err>;
100 
101   template <class _Up>
102   using rebind = expected<_Up, error_type>;
103 
104   // [expected.object.ctor], constructors
105   _LIBCPP_HIDE_FROM_ABI constexpr expected()
106     noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
107     requires is_default_constructible_v<_Tp>
108       : __has_val_(true) {
109     std::construct_at(std::addressof(__union_.__val_));
110   }
111 
112   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
113 
114   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
115     requires(is_copy_constructible_v<_Tp> &&
116              is_copy_constructible_v<_Err> &&
117              is_trivially_copy_constructible_v<_Tp> &&
118              is_trivially_copy_constructible_v<_Err>)
119   = default;
120 
121   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other)
122     noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
123     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
124              !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
125       : __has_val_(__other.__has_val_) {
126     if (__has_val_) {
127       std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
128     } else {
129       std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
130     }
131   }
132 
133 
134   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
135     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
136               && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
137   = default;
138 
139   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other)
140     noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
141     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
142              !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
143       : __has_val_(__other.__has_val_) {
144     if (__has_val_) {
145       std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
146     } else {
147       std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
148     }
149   }
150 
151 private:
152   template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
153   using __can_convert =
154       _And< is_constructible<_Tp, _UfQual>,
155             is_constructible<_Err, _OtherErrQual>,
156             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
157             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
158             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
159             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
160             _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
161             _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
162             _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
163             _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>,
164             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
165             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
166             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
167             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
168 
169 
170 public:
171   template <class _Up, class _OtherErr>
172     requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
173   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
174                                            !is_convertible_v<const _OtherErr&, _Err>)
175   expected(const expected<_Up, _OtherErr>& __other)
176     noexcept(is_nothrow_constructible_v<_Tp, const _Up&> &&
177              is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
178       : __has_val_(__other.__has_val_) {
179     if (__has_val_) {
180       std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
181     } else {
182       std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
183     }
184   }
185 
186   template <class _Up, class _OtherErr>
187     requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
188   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
189   expected(expected<_Up, _OtherErr>&& __other)
190     noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
191       : __has_val_(__other.__has_val_) {
192     if (__has_val_) {
193       std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
194     } else {
195       std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
196     }
197   }
198 
199   template <class _Up = _Tp>
200     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
201              !__is_std_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
202   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
203   expected(_Up&& __u)
204     noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
205       : __has_val_(true) {
206     std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u));
207   }
208 
209 
210   template <class _OtherErr>
211     requires is_constructible_v<_Err, const _OtherErr&>
212   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
213   expected(const unexpected<_OtherErr>& __unex)
214     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
215       : __has_val_(false) {
216     std::construct_at(std::addressof(__union_.__unex_), __unex.error());
217   }
218 
219   template <class _OtherErr>
220     requires is_constructible_v<_Err, _OtherErr>
221   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
222   expected(unexpected<_OtherErr>&& __unex)
223     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
224       : __has_val_(false) {
225     std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
226   }
227 
228   template <class... _Args>
229     requires is_constructible_v<_Tp, _Args...>
230   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args)
231     noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
232       : __has_val_(true) {
233     std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
234   }
235 
236   template <class _Up, class... _Args>
237     requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
238   _LIBCPP_HIDE_FROM_ABI constexpr explicit
239   expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
240     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
241       : __has_val_(true) {
242     std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
243   }
244 
245   template <class... _Args>
246     requires is_constructible_v<_Err, _Args...>
247   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
248     noexcept(is_nothrow_constructible_v<_Err, _Args...>)  // strengthened
249       : __has_val_(false) {
250     std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
251   }
252 
253   template <class _Up, class... _Args>
254     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
255   _LIBCPP_HIDE_FROM_ABI constexpr explicit
256   expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
257     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
258       : __has_val_(false) {
259     std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
260   }
261 
262   // [expected.object.dtor], destructor
263 
264   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
265     requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
266   = default;
267 
268   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
269     requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
270   {
271     if (__has_val_) {
272       std::destroy_at(std::addressof(__union_.__val_));
273     } else {
274       std::destroy_at(std::addressof(__union_.__unex_));
275     }
276   }
277 
278 private:
279   template <class _T1, class _T2, class... _Args>
280   _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) {
281     if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
282       std::destroy_at(std::addressof(__oldval));
283       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
284     } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
285       _T1 __tmp(std::forward<_Args>(__args)...);
286       std::destroy_at(std::addressof(__oldval));
287       std::construct_at(std::addressof(__newval), std::move(__tmp));
288     } else {
289       static_assert(
290           is_nothrow_move_constructible_v<_T2>,
291           "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
292           "be reverted to the previous state in case an exception is thrown during the assignment.");
293       _T2 __tmp(std::move(__oldval));
294       std::destroy_at(std::addressof(__oldval));
295       auto __trans =
296           std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
297       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
298       __trans.__complete();
299     }
300   }
301 
302 public:
303   // [expected.object.assign], assignment
304   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
305 
306   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
307     noexcept(is_nothrow_copy_assignable_v<_Tp> &&
308              is_nothrow_copy_constructible_v<_Tp> &&
309              is_nothrow_copy_assignable_v<_Err> &&
310              is_nothrow_copy_constructible_v<_Err>) // strengthened
311     requires(is_copy_assignable_v<_Tp> &&
312              is_copy_constructible_v<_Tp> &&
313              is_copy_assignable_v<_Err> &&
314              is_copy_constructible_v<_Err> &&
315              (is_nothrow_move_constructible_v<_Tp> ||
316               is_nothrow_move_constructible_v<_Err>))
317   {
318     if (__has_val_ && __rhs.__has_val_) {
319       __union_.__val_ = __rhs.__union_.__val_;
320     } else if (__has_val_) {
321       __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_);
322     } else if (__rhs.__has_val_) {
323       __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_);
324     } else {
325       __union_.__unex_ = __rhs.__union_.__unex_;
326     }
327     // note: only reached if no exception+rollback was done inside __reinit_expected
328     __has_val_ = __rhs.__has_val_;
329     return *this;
330   }
331 
332   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
333     noexcept(is_nothrow_move_assignable_v<_Tp> &&
334              is_nothrow_move_constructible_v<_Tp> &&
335              is_nothrow_move_assignable_v<_Err> &&
336              is_nothrow_move_constructible_v<_Err>)
337     requires(is_move_constructible_v<_Tp> &&
338              is_move_assignable_v<_Tp> &&
339              is_move_constructible_v<_Err> &&
340              is_move_assignable_v<_Err> &&
341              (is_nothrow_move_constructible_v<_Tp> ||
342               is_nothrow_move_constructible_v<_Err>))
343   {
344     if (__has_val_ && __rhs.__has_val_) {
345       __union_.__val_ = std::move(__rhs.__union_.__val_);
346     } else if (__has_val_) {
347       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_));
348     } else if (__rhs.__has_val_) {
349       __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_));
350     } else {
351       __union_.__unex_ = std::move(__rhs.__union_.__unex_);
352     }
353     // note: only reached if no exception+rollback was done inside __reinit_expected
354     __has_val_ = __rhs.__has_val_;
355     return *this;
356   }
357 
358   template <class _Up = _Tp>
359   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
360     requires(!is_same_v<expected, remove_cvref_t<_Up>> &&
361              !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
362              is_constructible_v<_Tp, _Up> &&
363              is_assignable_v<_Tp&, _Up> &&
364              (is_nothrow_constructible_v<_Tp, _Up> ||
365               is_nothrow_move_constructible_v<_Tp> ||
366               is_nothrow_move_constructible_v<_Err>))
367   {
368     if (__has_val_) {
369       __union_.__val_ = std::forward<_Up>(__v);
370     } else {
371       __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v));
372       __has_val_ = true;
373     }
374     return *this;
375   }
376 
377 private:
378   template <class _OtherErrQual>
379   static constexpr bool __can_assign_from_unexpected =
380       _And< is_constructible<_Err, _OtherErrQual>,
381             is_assignable<_Err&, _OtherErrQual>,
382             _Lazy<_Or,
383                   is_nothrow_constructible<_Err, _OtherErrQual>,
384                   is_nothrow_move_constructible<_Tp>,
385                   is_nothrow_move_constructible<_Err>> >::value;
386 
387 public:
388   template <class _OtherErr>
389     requires(__can_assign_from_unexpected<const _OtherErr&>)
390   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
391     if (__has_val_) {
392       __reinit_expected(__union_.__unex_, __union_.__val_, __un.error());
393       __has_val_ = false;
394     } else {
395       __union_.__unex_ = __un.error();
396     }
397     return *this;
398   }
399 
400   template <class _OtherErr>
401     requires(__can_assign_from_unexpected<_OtherErr>)
402   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
403     if (__has_val_) {
404       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error()));
405       __has_val_ = false;
406     } else {
407       __union_.__unex_ = std::move(__un.error());
408     }
409     return *this;
410   }
411 
412   template <class... _Args>
413     requires is_nothrow_constructible_v<_Tp, _Args...>
414   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
415     if (__has_val_) {
416       std::destroy_at(std::addressof(__union_.__val_));
417     } else {
418       std::destroy_at(std::addressof(__union_.__unex_));
419       __has_val_ = true;
420     }
421     return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
422   }
423 
424   template <class _Up, class... _Args>
425     requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
426   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
427     if (__has_val_) {
428       std::destroy_at(std::addressof(__union_.__val_));
429     } else {
430       std::destroy_at(std::addressof(__union_.__unex_));
431       __has_val_ = true;
432     }
433     return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
434   }
435 
436 
437 public:
438   // [expected.object.swap], swap
439   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
440     noexcept(is_nothrow_move_constructible_v<_Tp> &&
441              is_nothrow_swappable_v<_Tp> &&
442              is_nothrow_move_constructible_v<_Err> &&
443              is_nothrow_swappable_v<_Err>)
444     requires(is_swappable_v<_Tp> &&
445              is_swappable_v<_Err> &&
446              is_move_constructible_v<_Tp> &&
447              is_move_constructible_v<_Err> &&
448              (is_nothrow_move_constructible_v<_Tp> ||
449               is_nothrow_move_constructible_v<_Err>))
450   {
451     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
452       if constexpr (is_nothrow_move_constructible_v<_Err>) {
453         _Err __tmp(std::move(__with_err.__union_.__unex_));
454         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
455         auto __trans = std::__make_exception_guard([&] {
456           std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp));
457         });
458         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_));
459         __trans.__complete();
460         std::destroy_at(std::addressof(__with_val.__union_.__val_));
461         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp));
462       } else {
463         static_assert(is_nothrow_move_constructible_v<_Tp>,
464                       "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
465                       "that it can be reverted to the previous state in case an exception is thrown during swap.");
466         _Tp __tmp(std::move(__with_val.__union_.__val_));
467         std::destroy_at(std::addressof(__with_val.__union_.__val_));
468         auto __trans = std::__make_exception_guard([&] {
469           std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp));
470         });
471         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
472         __trans.__complete();
473         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
474         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp));
475       }
476       __with_val.__has_val_ = false;
477       __with_err.__has_val_ = true;
478     };
479 
480     if (__has_val_) {
481       if (__rhs.__has_val_) {
482         using std::swap;
483         swap(__union_.__val_, __rhs.__union_.__val_);
484       } else {
485         __swap_val_unex_impl(*this, __rhs);
486       }
487     } else {
488       if (__rhs.__has_val_) {
489         __swap_val_unex_impl(__rhs, *this);
490       } else {
491         using std::swap;
492         swap(__union_.__unex_, __rhs.__union_.__unex_);
493       }
494     }
495   }
496 
497   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
498     noexcept(noexcept(__x.swap(__y)))
499     requires requires { __x.swap(__y); }
500   {
501     __x.swap(__y);
502   }
503 
504   // [expected.object.obs], observers
505   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
506     _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
507     return std::addressof(__union_.__val_);
508   }
509 
510   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
511     _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
512     return std::addressof(__union_.__val_);
513   }
514 
515   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
516     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
517     return __union_.__val_;
518   }
519 
520   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
521     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
522     return __union_.__val_;
523   }
524 
525   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
526     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
527     return std::move(__union_.__val_);
528   }
529 
530   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
531     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
532     return std::move(__union_.__val_);
533   }
534 
535   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
536 
537   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
538 
539   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
540     if (!__has_val_) {
541       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
542     }
543     return __union_.__val_;
544   }
545 
546   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
547     if (!__has_val_) {
548       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
549     }
550     return __union_.__val_;
551   }
552 
553   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
554     if (!__has_val_) {
555       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
556     }
557     return std::move(__union_.__val_);
558   }
559 
560   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
561     if (!__has_val_) {
562       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
563     }
564     return std::move(__union_.__val_);
565   }
566 
567   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
568     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
569     return __union_.__unex_;
570   }
571 
572   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
573     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
574     return __union_.__unex_;
575   }
576 
577   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
578     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
579     return std::move(__union_.__unex_);
580   }
581 
582   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
583     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
584     return std::move(__union_.__unex_);
585   }
586 
587   template <class _Up>
588   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
589     static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
590     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
591     return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v));
592   }
593 
594   template <class _Up>
595   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
596     static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
597     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
598     return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
599   }
600 
601   // [expected.object.eq], equality operators
602   template <class _T2, class _E2>
603     requires(!is_void_v<_T2>)
604   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
605     if (__x.__has_val_ != __y.__has_val_) {
606       return false;
607     } else {
608       if (__x.__has_val_) {
609         return __x.__union_.__val_ == __y.__union_.__val_;
610       } else {
611         return __x.__union_.__unex_ == __y.__union_.__unex_;
612       }
613     }
614   }
615 
616   template <class _T2>
617   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
618     return __x.__has_val_ && static_cast<bool>(__x.__union_.__val_ == __v);
619   }
620 
621   template <class _E2>
622   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
623     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __e.error());
624   }
625 
626 private:
627   struct __empty_t {};
628   // use named union because [[no_unique_address]] cannot be applied to an unnamed union
629   _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
630     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
631 
632     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
633       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
634     = default;
635 
636     // the expected's destructor handles this
637     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
638       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
639     {}
640 
641     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
642     _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
643     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
644   } __union_;
645 
646   bool __has_val_;
647 };
648 
649 template <class _Tp, class _Err>
650   requires is_void_v<_Tp>
651 class expected<_Tp, _Err> {
652   static_assert(__valid_std_unexpected<_Err>::value,
653                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
654                 "valid argument for unexpected<E> is ill-formed");
655 
656   template <class, class>
657   friend class expected;
658 
659   template <class _Up, class _OtherErr, class _OtherErrQual>
660   using __can_convert =
661       _And< is_void<_Up>,
662             is_constructible<_Err, _OtherErrQual>,
663             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
664             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
665             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
666             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
667 
668 public:
669   using value_type      = _Tp;
670   using error_type      = _Err;
671   using unexpected_type = unexpected<_Err>;
672 
673   template <class _Up>
674   using rebind = expected<_Up, error_type>;
675 
676   // [expected.void.ctor], constructors
677   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {}
678 
679   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
680 
681   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
682     requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
683   = default;
684 
685   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs)
686     noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened
687     requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
688       : __has_val_(__rhs.__has_val_) {
689     if (!__rhs.__has_val_) {
690       std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
691     }
692   }
693 
694   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
695     requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
696   = default;
697 
698   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs)
699     noexcept(is_nothrow_move_constructible_v<_Err>)
700     requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
701       : __has_val_(__rhs.__has_val_) {
702     if (!__rhs.__has_val_) {
703       std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
704     }
705   }
706 
707   template <class _Up, class _OtherErr>
708     requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
709   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
710   expected(const expected<_Up, _OtherErr>& __rhs)
711     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
712       : __has_val_(__rhs.__has_val_) {
713     if (!__rhs.__has_val_) {
714       std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
715     }
716   }
717 
718   template <class _Up, class _OtherErr>
719     requires __can_convert<_Up, _OtherErr, _OtherErr>::value
720   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
721   expected(expected<_Up, _OtherErr>&& __rhs)
722     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
723       : __has_val_(__rhs.__has_val_) {
724     if (!__rhs.__has_val_) {
725       std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
726     }
727   }
728 
729   template <class _OtherErr>
730     requires is_constructible_v<_Err, const _OtherErr&>
731   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
732   expected(const unexpected<_OtherErr>& __unex)
733     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
734       : __has_val_(false) {
735     std::construct_at(std::addressof(__union_.__unex_), __unex.error());
736   }
737 
738   template <class _OtherErr>
739     requires is_constructible_v<_Err, _OtherErr>
740   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
741   expected(unexpected<_OtherErr>&& __unex)
742     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
743       : __has_val_(false) {
744     std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
745   }
746 
747   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
748 
749   template <class... _Args>
750     requires is_constructible_v<_Err, _Args...>
751   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
752     noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
753       : __has_val_(false) {
754     std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
755   }
756 
757   template <class _Up, class... _Args>
758     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
759   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
760     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
761       : __has_val_(false) {
762     std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
763   }
764 
765   // [expected.void.dtor], destructor
766 
767   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
768     requires is_trivially_destructible_v<_Err>
769   = default;
770 
771   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
772     requires(!is_trivially_destructible_v<_Err>)
773   {
774     if (!__has_val_) {
775       std::destroy_at(std::addressof(__union_.__unex_));
776     }
777   }
778 
779   // [expected.void.assign], assignment
780 
781   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
782 
783   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
784     noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
785     requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
786   {
787     if (__has_val_) {
788       if (!__rhs.__has_val_) {
789         std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
790         __has_val_ = false;
791       }
792     } else {
793       if (__rhs.__has_val_) {
794         std::destroy_at(std::addressof(__union_.__unex_));
795         __has_val_ = true;
796       } else {
797         __union_.__unex_ = __rhs.__union_.__unex_;
798       }
799     }
800     return *this;
801   }
802 
803   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
804 
805   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
806     noexcept(is_nothrow_move_assignable_v<_Err> &&
807              is_nothrow_move_constructible_v<_Err>)
808     requires(is_move_assignable_v<_Err> &&
809              is_move_constructible_v<_Err>)
810   {
811     if (__has_val_) {
812       if (!__rhs.__has_val_) {
813         std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
814         __has_val_ = false;
815       }
816     } else {
817       if (__rhs.__has_val_) {
818         std::destroy_at(std::addressof(__union_.__unex_));
819         __has_val_ = true;
820       } else {
821         __union_.__unex_ = std::move(__rhs.__union_.__unex_);
822       }
823     }
824     return *this;
825   }
826 
827   template <class _OtherErr>
828     requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
829   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
830     if (__has_val_) {
831       std::construct_at(std::addressof(__union_.__unex_), __un.error());
832       __has_val_ = false;
833     } else {
834       __union_.__unex_ = __un.error();
835     }
836     return *this;
837   }
838 
839   template <class _OtherErr>
840     requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
841   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
842     if (__has_val_) {
843       std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error()));
844       __has_val_ = false;
845     } else {
846       __union_.__unex_ = std::move(__un.error());
847     }
848     return *this;
849   }
850 
851   _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
852     if (!__has_val_) {
853       std::destroy_at(std::addressof(__union_.__unex_));
854       __has_val_ = true;
855     }
856   }
857 
858   // [expected.void.swap], swap
859   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
860     noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
861     requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
862   {
863     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
864       std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
865       std::destroy_at(std::addressof(__with_err.__union_.__unex_));
866       __with_val.__has_val_ = false;
867       __with_err.__has_val_ = true;
868     };
869 
870     if (__has_val_) {
871       if (!__rhs.__has_val_) {
872         __swap_val_unex_impl(*this, __rhs);
873       }
874     } else {
875       if (__rhs.__has_val_) {
876         __swap_val_unex_impl(__rhs, *this);
877       } else {
878         using std::swap;
879         swap(__union_.__unex_, __rhs.__union_.__unex_);
880       }
881     }
882   }
883 
884   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
885     noexcept(noexcept(__x.swap(__y)))
886     requires requires { __x.swap(__y); }
887   {
888     __x.swap(__y);
889   }
890 
891   // [expected.void.obs], observers
892   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
893 
894   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
895 
896   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
897     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
898   }
899 
900   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
901     if (!__has_val_) {
902       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
903     }
904   }
905 
906   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
907     if (!__has_val_) {
908       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
909     }
910   }
911 
912   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
913     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
914     return __union_.__unex_;
915   }
916 
917   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
918     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
919     return __union_.__unex_;
920   }
921 
922   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
923     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
924     return std::move(__union_.__unex_);
925   }
926 
927   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
928     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
929     return std::move(__union_.__unex_);
930   }
931 
932   // [expected.void.eq], equality operators
933   template <class _T2, class _E2>
934     requires is_void_v<_T2>
935   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
936     if (__x.__has_val_ != __y.__has_val_) {
937       return false;
938     } else {
939       return __x.__has_val_ || static_cast<bool>(__x.__union_.__unex_ == __y.__union_.__unex_);
940     }
941   }
942 
943   template <class _E2>
944   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
945     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __y.error());
946   }
947 
948 private:
949   struct __empty_t {};
950   // use named union because [[no_unique_address]] cannot be applied to an unnamed union
951   _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
952     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
953 
954     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
955       requires(is_trivially_destructible_v<_Err>)
956     = default;
957 
958     // the expected's destructor handles this
959     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
960       requires(!is_trivially_destructible_v<_Err>)
961     {}
962 
963     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
964     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
965   } __union_;
966 
967   bool __has_val_;
968 };
969 
970 _LIBCPP_END_NAMESPACE_STD
971 
972 #endif // _LIBCPP_STD_VER >= 23
973 
974 #endif // _LIBCPP___EXPECTED_EXPECTED_H
975