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 <__functional/invoke.h> |
18 | #include <__memory/addressof.h> |
19 | #include <__memory/construct_at.h> |
20 | #include <__type_traits/conditional.h> |
21 | #include <__type_traits/conjunction.h> |
22 | #include <__type_traits/disjunction.h> |
23 | #include <__type_traits/integral_constant.h> |
24 | #include <__type_traits/invoke.h> |
25 | #include <__type_traits/is_assignable.h> |
26 | #include <__type_traits/is_constructible.h> |
27 | #include <__type_traits/is_convertible.h> |
28 | #include <__type_traits/is_core_convertible.h> |
29 | #include <__type_traits/is_function.h> |
30 | #include <__type_traits/is_nothrow_assignable.h> |
31 | #include <__type_traits/is_nothrow_constructible.h> |
32 | #include <__type_traits/is_reference.h> |
33 | #include <__type_traits/is_replaceable.h> |
34 | #include <__type_traits/is_same.h> |
35 | #include <__type_traits/is_swappable.h> |
36 | #include <__type_traits/is_trivially_constructible.h> |
37 | #include <__type_traits/is_trivially_destructible.h> |
38 | #include <__type_traits/is_trivially_relocatable.h> |
39 | #include <__type_traits/is_void.h> |
40 | #include <__type_traits/lazy.h> |
41 | #include <__type_traits/negation.h> |
42 | #include <__type_traits/remove_cv.h> |
43 | #include <__type_traits/remove_cvref.h> |
44 | #include <__utility/as_const.h> |
45 | #include <__utility/exception_guard.h> |
46 | #include <__utility/forward.h> |
47 | #include <__utility/in_place.h> |
48 | #include <__utility/move.h> |
49 | #include <__utility/swap.h> |
50 | #include <__verbose_abort> |
51 | #include <initializer_list> |
52 | |
53 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
54 | # pragma GCC system_header |
55 | #endif |
56 | |
57 | _LIBCPP_PUSH_MACROS |
58 | #include <__undef_macros> |
59 | |
60 | #if _LIBCPP_STD_VER >= 23 |
61 | |
62 | _LIBCPP_BEGIN_NAMESPACE_STD |
63 | |
64 | template <class _Tp, class _Err> |
65 | class expected; |
66 | |
67 | template <class _Tp> |
68 | struct __is_std_expected : false_type {}; |
69 | |
70 | template <class _Tp, class _Err> |
71 | struct __is_std_expected<expected<_Tp, _Err>> : true_type {}; |
72 | |
73 | struct __expected_construct_in_place_from_invoke_tag {}; |
74 | struct __expected_construct_unexpected_from_invoke_tag {}; |
75 | |
76 | template <class _Err, class _Arg> |
77 | _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { |
78 | # if _LIBCPP_HAS_EXCEPTIONS |
79 | throw bad_expected_access<_Err>(std::forward<_Arg>(__arg)); |
80 | # else |
81 | (void)__arg; |
82 | _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode" ); |
83 | # endif |
84 | } |
85 | |
86 | // If parameter type `_Tp` of `__conditional_no_unique_address` is neither |
87 | // copyable nor movable, a constructor with this tag is provided. For that |
88 | // constructor, the user has to provide a function and arguments. The function |
89 | // must return an object of type `_Tp`. When the function is invoked by the |
90 | // constructor, guaranteed copy elision kicks in and the `_Tp` is constructed |
91 | // in place. |
92 | struct __conditional_no_unique_address_invoke_tag {}; |
93 | |
94 | // This class implements an object with `[[no_unique_address]]` conditionally applied to it, |
95 | // based on the value of `_NoUnique`. |
96 | // |
97 | // A member of this class must always have `[[no_unique_address]]` applied to |
98 | // it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case |
99 | // would not have any effect. In the `false` case, the `__v` is not |
100 | // `[[no_unique_address]]`, so nullifies the effects of the "outer" |
101 | // `[[no_unique_address]]` regarding data layout. |
102 | // |
103 | // If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`. |
104 | template <bool _NoUnique, class _Tp> |
105 | struct __conditional_no_unique_address; |
106 | |
107 | template <class _Tp> |
108 | struct __conditional_no_unique_address<true, _Tp> { |
109 | template <class... _Args> |
110 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args) |
111 | : __v(std::forward<_Args>(__args)...) {} |
112 | |
113 | template <class _Func, class... _Args> |
114 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address( |
115 | __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args) |
116 | : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} |
117 | |
118 | _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v; |
119 | }; |
120 | |
121 | template <class _Tp> |
122 | struct __conditional_no_unique_address<false, _Tp> { |
123 | template <class... _Args> |
124 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args) |
125 | : __v(std::forward<_Args>(__args)...) {} |
126 | |
127 | template <class _Func, class... _Args> |
128 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address( |
129 | __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args) |
130 | : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} |
131 | |
132 | _Tp __v; |
133 | }; |
134 | |
135 | // This function returns whether the type `_Second` can be stuffed into the tail padding |
136 | // of the `_First` type if both of them are given `[[no_unique_address]]`. |
137 | template <class _First, class _Second> |
138 | inline constexpr bool __fits_in_tail_padding = []() { |
139 | struct __x { |
140 | _LIBCPP_NO_UNIQUE_ADDRESS _First __first; |
141 | _LIBCPP_NO_UNIQUE_ADDRESS _Second __second; |
142 | }; |
143 | return sizeof(__x) == sizeof(_First); |
144 | }(); |
145 | |
146 | // This class implements the storage used by `std::expected`. We have a few |
147 | // goals for this storage: |
148 | // 1. Whenever the underlying {_Tp | _Unex} combination has free bytes in its |
149 | // tail padding, we should reuse it to store the bool discriminator of the |
150 | // expected, so as to save space. |
151 | // 2. Whenever the `expected<_Tp, _Unex>` as a whole has free bytes in its tail |
152 | // padding, we should allow an object following the expected to be stored in |
153 | // its tail padding. |
154 | // 3. However, we never want a user object (say `X`) that would follow an |
155 | // `expected<_Tp, _Unex>` to be stored in the padding bytes of the |
156 | // underlying {_Tp | _Unex} union, if any. That is because we use |
157 | // `construct_at` on that union, which would end up overwriting the `X` |
158 | // member if it is stored in the tail padding of the union. |
159 | // |
160 | // To achieve this, `__expected_base`'s logic is implemented in an inner |
161 | // `__repr` class. `__expected_base` holds one `__repr` member which is |
162 | // conditionally `[[no_unique_address]]`. The `__repr` class holds the |
163 | // underlying {_Tp | _Unex} union and a boolean "has value" flag. |
164 | // |
165 | // Which one of the `__repr_`/`__union_` members is `[[no_unique_address]]` |
166 | // depends on whether the "has value" boolean fits into the tail padding of |
167 | // the underlying {_Tp | _Unex} union: |
168 | // |
169 | // - In case the "has value" bool fits into the tail padding of the union, the |
170 | // whole `__repr_` member is _not_ `[[no_unique_address]]` as it needs to be |
171 | // transparently replaced on `emplace()`/`swap()` etc. |
172 | // - In case the "has value" bool does not fit into the tail padding of the |
173 | // union, only the union member must be transparently replaced (therefore is |
174 | // _not_ `[[no_unique_address]]`) and the "has value" flag must be adjusted |
175 | // manually. |
176 | // |
177 | // This way, the member that is transparently replaced on mutating operations |
178 | // is never `[[no_unique_address]]`, satisfying the requirements from |
179 | // "[basic.life]" in the standard. |
180 | // |
181 | // Stripped away of all superfluous elements, the layout of `__expected_base` |
182 | // then looks like this: |
183 | // |
184 | // template <class Tp, class Err> |
185 | // class expected_base { |
186 | // union union_t { |
187 | // [[no_unique_address]] Tp val; |
188 | // [[no_unique_address]] Err unex; |
189 | // }; |
190 | // |
191 | // static constexpr bool put_flag_in_tail = fits_in_tail_padding<union_t, bool>; |
192 | // static constexpr bool allow_reusing_expected_tail_padding = !put_flag_in_tail; |
193 | // |
194 | // struct repr { |
195 | // private: |
196 | // // If "has value" fits into the tail, this should be |
197 | // // `[[no_unique_address]]`, otherwise not. |
198 | // [[no_unique_address]] conditional_no_unique_address< |
199 | // put_flag_in_tail, |
200 | // union_t>::type union_; |
201 | // [[no_unique_address]] bool has_val_; |
202 | // }; |
203 | // |
204 | // protected: |
205 | // // If "has value" fits into the tail, this must _not_ be |
206 | // // `[[no_unique_address]]` so that we fill out the |
207 | // // complete `expected` object. |
208 | // [[no_unique_address]] conditional_no_unique_address< |
209 | // allow_reusing_expected_tail_padding, |
210 | // repr>::type repr_; |
211 | // }; |
212 | // |
213 | template <class _Tp, class _Err> |
214 | class __expected_base { |
215 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union, |
216 | // also guaranteed elision into a potentially-overlapping subobject is unsettled (and |
217 | // it's not clear that it's implementable, given that the function is allowed to clobber |
218 | // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. |
219 | union __union_t { |
220 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete; |
221 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) |
222 | requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && |
223 | is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) |
224 | = default; |
225 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete; |
226 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) |
227 | requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && |
228 | is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) |
229 | = default; |
230 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete; |
231 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&) = delete; |
232 | |
233 | template <class... _Args> |
234 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t, _Args&&... __args) |
235 | : __val_(std::forward<_Args>(__args)...) {} |
236 | |
237 | template <class... _Args> |
238 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args) |
239 | : __unex_(std::forward<_Args>(__args)...) {} |
240 | |
241 | template <class _Func, class... _Args> |
242 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( |
243 | std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) |
244 | : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} |
245 | |
246 | template <class _Func, class... _Args> |
247 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( |
248 | std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) |
249 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} |
250 | |
251 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
252 | requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) |
253 | = default; |
254 | |
255 | // __repr's destructor handles this |
256 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} |
257 | |
258 | _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; |
259 | _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; |
260 | }; |
261 | |
262 | static constexpr bool __put_flag_in_tail = __fits_in_tail_padding<__union_t, bool>; |
263 | static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail; |
264 | |
265 | struct __repr { |
266 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete; |
267 | |
268 | template <class... _Args> |
269 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag, _Args&&... __args) |
270 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {} |
271 | |
272 | template <class... _Args> |
273 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args) |
274 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} |
275 | |
276 | template <class... _Args> |
277 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_in_place_from_invoke_tag __tag, |
278 | _Args&&... __args) |
279 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {} |
280 | |
281 | template <class... _Args> |
282 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag, |
283 | _Args&&... __args) |
284 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} |
285 | |
286 | // The return value of `__make_union` must be constructed in place in the |
287 | // `__v` member of `__union_`, relying on guaranteed copy elision. To do |
288 | // this, the `__conditional_no_unique_address_invoke_tag` constructor is |
289 | // called with a lambda that is immediately called inside |
290 | // `__conditional_no_unique_address`'s constructor. |
291 | template <class _OtherUnion> |
292 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other) |
293 | requires(__allow_reusing_expected_tail_padding) |
294 | : __union_(__conditional_no_unique_address_invoke_tag{}, |
295 | [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }), |
296 | __has_val_(__has_val) {} |
297 | |
298 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete; |
299 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) |
300 | requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && |
301 | is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) |
302 | = default; |
303 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete; |
304 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) |
305 | requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && |
306 | is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) |
307 | = default; |
308 | |
309 | _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete; |
310 | _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&) = delete; |
311 | |
312 | _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() |
313 | requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) |
314 | = default; |
315 | |
316 | _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() |
317 | requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) |
318 | { |
319 | __destroy_union_member(); |
320 | } |
321 | |
322 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() |
323 | requires(__allow_reusing_expected_tail_padding && |
324 | (is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)) |
325 | { |
326 | // Note: Since the destructor of the union is trivial, this does nothing |
327 | // except to end the lifetime of the union. |
328 | std::destroy_at(&__union_.__v); |
329 | } |
330 | |
331 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() |
332 | requires(__allow_reusing_expected_tail_padding && |
333 | (!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)) |
334 | { |
335 | __destroy_union_member(); |
336 | std::destroy_at(&__union_.__v); |
337 | } |
338 | |
339 | template <class... _Args> |
340 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t, _Args&&... __args) |
341 | requires(__allow_reusing_expected_tail_padding) |
342 | { |
343 | std::construct_at(&__union_.__v, in_place, std::forward<_Args>(__args)...); |
344 | __has_val_ = true; |
345 | } |
346 | |
347 | template <class... _Args> |
348 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args) |
349 | requires(__allow_reusing_expected_tail_padding) |
350 | { |
351 | std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...); |
352 | __has_val_ = false; |
353 | } |
354 | |
355 | private: |
356 | template <class, class> |
357 | friend class __expected_base; |
358 | |
359 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member() |
360 | requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) |
361 | { |
362 | if (__has_val_) { |
363 | std::destroy_at(std::addressof(__union_.__v.__val_)); |
364 | } else { |
365 | std::destroy_at(std::addressof(__union_.__v.__unex_)); |
366 | } |
367 | } |
368 | |
369 | template <class _OtherUnion> |
370 | _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other) |
371 | requires(__allow_reusing_expected_tail_padding) |
372 | { |
373 | if (__has_val) |
374 | return __union_t(in_place, std::forward<_OtherUnion>(__other).__val_); |
375 | else |
376 | return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_); |
377 | } |
378 | |
379 | _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_; |
380 | _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_; |
381 | }; |
382 | |
383 | template <class _OtherUnion> |
384 | _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other) |
385 | requires(__put_flag_in_tail) |
386 | { |
387 | if (__has_val) |
388 | return __repr(in_place, std::forward<_OtherUnion>(__other).__val_); |
389 | else |
390 | return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_); |
391 | } |
392 | |
393 | protected: |
394 | template <class... _Args> |
395 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(_Args&&... __args) |
396 | : __repr_(in_place, std::forward<_Args>(__args)...) {} |
397 | |
398 | // In case we copy/move construct from another `expected` we need to create |
399 | // our `expected` so that it either has a value or not, depending on the "has |
400 | // value" flag of the other `expected`. To do this without falling back on |
401 | // `std::construct_at` we rely on guaranteed copy elision using two helper |
402 | // functions `__make_repr` and `__make_union`. There have to be two since |
403 | // there are two data layouts with different members being |
404 | // `[[no_unique_address]]`. GCC (as of version 13) does not do guaranteed |
405 | // copy elision when initializing `[[no_unique_address]]` members. The two |
406 | // cases are: |
407 | // |
408 | // - `__make_repr`: This is used when the "has value" flag lives in the tail |
409 | // of the union. In this case, the `__repr` member is _not_ |
410 | // `[[no_unique_address]]`. |
411 | // - `__make_union`: When the "has value" flag does _not_ fit in the tail of |
412 | // the union, the `__repr` member is `[[no_unique_address]]` and the union |
413 | // is not. |
414 | // |
415 | // This constructor "catches" the first case and leaves the second case to |
416 | // `__union_t`, its constructors and `__make_union`. |
417 | template <class _OtherUnion> |
418 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(bool __has_val, _OtherUnion&& __other) |
419 | requires(__put_flag_in_tail) |
420 | : __repr_(__conditional_no_unique_address_invoke_tag{}, |
421 | [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {} |
422 | |
423 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() { |
424 | if constexpr (__put_flag_in_tail) |
425 | std::destroy_at(&__repr_.__v); |
426 | else |
427 | __repr_.__v.__destroy_union(); |
428 | } |
429 | |
430 | template <class _Tag, class... _Args> |
431 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) { |
432 | if constexpr (__put_flag_in_tail) |
433 | std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...); |
434 | else |
435 | __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...); |
436 | } |
437 | |
438 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; } |
439 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; } |
440 | _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; } |
441 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& __val() { return __repr_.__v.__union_.__v.__val_; } |
442 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& __val() const { return __repr_.__v.__union_.__v.__val_; } |
443 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; } |
444 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; } |
445 | |
446 | private: |
447 | _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_; |
448 | }; |
449 | |
450 | template <class _Tp, class _Err> |
451 | class expected : private __expected_base<_Tp, _Err> { |
452 | static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v<remove_cv_t<_Tp>, in_place_t> && |
453 | !is_same_v<remove_cv_t<_Tp>, unexpect_t> && !__is_std_unexpected<remove_cv_t<_Tp>>::value && |
454 | __valid_std_unexpected<_Err>::value, |
455 | "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a " |
456 | "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " |
457 | "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " |
458 | "definition of the template expected<T, E> with a type for the E parameter that is not a valid " |
459 | "template argument for unexpected is ill-formed." ); |
460 | |
461 | template <class _Up, class _OtherErr> |
462 | friend class expected; |
463 | |
464 | using __base _LIBCPP_NODEBUG = __expected_base<_Tp, _Err>; |
465 | |
466 | public: |
467 | using value_type = _Tp; |
468 | using error_type = _Err; |
469 | using unexpected_type = unexpected<_Err>; |
470 | |
471 | using __trivially_relocatable _LIBCPP_NODEBUG = |
472 | __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value, |
473 | expected, |
474 | void>; |
475 | using __replaceable _LIBCPP_NODEBUG = |
476 | __conditional_t<__is_replaceable_v<_Tp> && __is_replaceable_v<_Err>, expected, void>; |
477 | |
478 | template <class _Up> |
479 | using rebind = expected<_Up, error_type>; |
480 | |
481 | // [expected.object.ctor], constructors |
482 | _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened |
483 | requires is_default_constructible_v<_Tp> |
484 | : __base(in_place) {} |
485 | |
486 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; |
487 | |
488 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) |
489 | requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Tp> && |
490 | is_trivially_copy_constructible_v<_Err>) |
491 | = default; |
492 | |
493 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) noexcept( |
494 | is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened |
495 | requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && |
496 | !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) |
497 | : __base(__other.__has_val(), __other.__union()) {} |
498 | |
499 | _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) |
500 | requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Tp> && |
501 | is_trivially_move_constructible_v<_Err>) |
502 | = default; |
503 | |
504 | _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) noexcept( |
505 | is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) |
506 | requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && |
507 | !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) |
508 | : __base(__other.__has_val(), std::move(__other.__union())) {} |
509 | |
510 | private: |
511 | template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual> |
512 | using __can_convert _LIBCPP_NODEBUG = _And< |
513 | is_constructible<_Tp, _UfQual>, |
514 | is_constructible<_Err, _OtherErrQual>, |
515 | _If<_Not<is_same<remove_cv_t<_Tp>, bool>>::value, |
516 | _And< _Not<_And<is_same<_Tp, _Up>, is_same<_Err, _OtherErr>>>, // use the copy constructor instead, see #92676 |
517 | _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>, |
518 | _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>, |
519 | _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>, |
520 | _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>, |
521 | _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>, |
522 | _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>, |
523 | _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>, |
524 | _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>>, |
525 | true_type>, |
526 | _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>, |
527 | _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>, |
528 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, |
529 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >; |
530 | |
531 | template <class _Func, class... _Args> |
532 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( |
533 | std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) |
534 | : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} |
535 | |
536 | template <class _Func, class... _Args> |
537 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( |
538 | std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) |
539 | : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} |
540 | |
541 | public: |
542 | template <class _Up, class _OtherErr> |
543 | requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value |
544 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> || |
545 | !is_convertible_v<const _OtherErr&, _Err>) |
546 | expected(const expected<_Up, _OtherErr>& __other) noexcept( |
547 | is_nothrow_constructible_v<_Tp, const _Up&> && |
548 | is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened |
549 | : __base(__other.__has_val(), __other.__union()) {} |
550 | |
551 | template <class _Up, class _OtherErr> |
552 | requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value |
553 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) |
554 | expected(expected<_Up, _OtherErr>&& __other) noexcept( |
555 | is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened |
556 | : __base(__other.__has_val(), std::move(__other.__union())) {} |
557 | |
558 | template <class _Up = _Tp> |
559 | requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> && |
560 | is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value && |
561 | (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value)) |
562 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) |
563 | expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened |
564 | : __base(in_place, std::forward<_Up>(__u)) {} |
565 | |
566 | template <class _OtherErr> |
567 | requires is_constructible_v<_Err, const _OtherErr&> |
568 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected( |
569 | const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened |
570 | : __base(unexpect, __unex.error()) {} |
571 | |
572 | template <class _OtherErr> |
573 | requires is_constructible_v<_Err, _OtherErr> |
574 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) |
575 | expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened |
576 | : __base(unexpect, std::move(__unex.error())) {} |
577 | |
578 | template <class... _Args> |
579 | requires is_constructible_v<_Tp, _Args...> |
580 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) noexcept( |
581 | is_nothrow_constructible_v<_Tp, _Args...>) // strengthened |
582 | : __base(in_place, std::forward<_Args>(__args)...) {} |
583 | |
584 | template <class _Up, class... _Args> |
585 | requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > |
586 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( |
587 | is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened |
588 | : __base(in_place, __il, std::forward<_Args>(__args)...) {} |
589 | |
590 | template <class... _Args> |
591 | requires is_constructible_v<_Err, _Args...> |
592 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( |
593 | is_nothrow_constructible_v<_Err, _Args...>) // strengthened |
594 | : __base(unexpect, std::forward<_Args>(__args)...) {} |
595 | |
596 | template <class _Up, class... _Args> |
597 | requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > |
598 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( |
599 | is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened |
600 | : __base(unexpect, __il, std::forward<_Args>(__args)...) {} |
601 | |
602 | // [expected.object.dtor], destructor |
603 | |
604 | _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default; |
605 | |
606 | private: |
607 | template <class _Tag, class _OtherTag, class _T1, class _T2, class... _Args> |
608 | _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(_T2& __oldval, _Args&&... __args) { |
609 | if constexpr (is_nothrow_constructible_v<_T1, _Args...>) { |
610 | this->__destroy(); |
611 | this->__construct(_Tag{}, std::forward<_Args>(__args)...); |
612 | } else if constexpr (is_nothrow_move_constructible_v<_T1>) { |
613 | _T1 __tmp(std::forward<_Args>(__args)...); |
614 | this->__destroy(); |
615 | this->__construct(_Tag{}, std::move(__tmp)); |
616 | } else { |
617 | static_assert( |
618 | is_nothrow_move_constructible_v<_T2>, |
619 | "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can " |
620 | "be reverted to the previous state in case an exception is thrown during the assignment." ); |
621 | _T2 __tmp(std::move(__oldval)); |
622 | this->__destroy(); |
623 | auto __trans = std::__make_exception_guard([&] { this->__construct(_OtherTag{}, std::move(__tmp)); }); |
624 | this->__construct(_Tag{}, std::forward<_Args>(__args)...); |
625 | __trans.__complete(); |
626 | } |
627 | } |
628 | |
629 | public: |
630 | // [expected.object.assign], assignment |
631 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; |
632 | |
633 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( |
634 | is_nothrow_copy_assignable_v<_Tp> && is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Err> && |
635 | is_nothrow_copy_constructible_v<_Err>) // strengthened |
636 | requires(is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Err> && |
637 | is_copy_constructible_v<_Err> && |
638 | (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) |
639 | { |
640 | if (this->__has_val() && __rhs.__has_val()) { |
641 | this->__val() = __rhs.__val(); |
642 | } else if (this->__has_val()) { |
643 | __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __rhs.__unex()); |
644 | } else if (__rhs.__has_val()) { |
645 | __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), __rhs.__val()); |
646 | } else { |
647 | this->__unex() = __rhs.__unex(); |
648 | } |
649 | return *this; |
650 | } |
651 | |
652 | _LIBCPP_HIDE_FROM_ABI constexpr expected& |
653 | operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp> && |
654 | is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) |
655 | requires(is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> && is_move_constructible_v<_Err> && |
656 | is_move_assignable_v<_Err> && |
657 | (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) |
658 | { |
659 | if (this->__has_val() && __rhs.__has_val()) { |
660 | this->__val() = std::move(__rhs.__val()); |
661 | } else if (this->__has_val()) { |
662 | __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__rhs.__unex())); |
663 | } else if (__rhs.__has_val()) { |
664 | __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::move(__rhs.__val())); |
665 | } else { |
666 | this->__unex() = std::move(__rhs.__unex()); |
667 | } |
668 | return *this; |
669 | } |
670 | |
671 | template <class _Up = _Tp> |
672 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) |
673 | requires(!is_same_v<expected, remove_cvref_t<_Up>> && !__is_std_unexpected<remove_cvref_t<_Up>>::value && |
674 | is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> && |
675 | (is_nothrow_constructible_v<_Tp, _Up> || is_nothrow_move_constructible_v<_Tp> || |
676 | is_nothrow_move_constructible_v<_Err>)) |
677 | { |
678 | if (this->__has_val()) { |
679 | this->__val() = std::forward<_Up>(__v); |
680 | } else { |
681 | __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::forward<_Up>(__v)); |
682 | } |
683 | return *this; |
684 | } |
685 | |
686 | private: |
687 | template <class _OtherErrQual> |
688 | static constexpr bool __can_assign_from_unexpected = |
689 | _And< is_constructible<_Err, _OtherErrQual>, |
690 | is_assignable<_Err&, _OtherErrQual>, |
691 | _Lazy<_Or, |
692 | is_nothrow_constructible<_Err, _OtherErrQual>, |
693 | is_nothrow_move_constructible<_Tp>, |
694 | is_nothrow_move_constructible<_Err>> >::value; |
695 | |
696 | public: |
697 | template <class _OtherErr> |
698 | requires(__can_assign_from_unexpected<const _OtherErr&>) |
699 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { |
700 | if (this->__has_val()) { |
701 | __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __un.error()); |
702 | } else { |
703 | this->__unex() = __un.error(); |
704 | } |
705 | return *this; |
706 | } |
707 | |
708 | template <class _OtherErr> |
709 | requires(__can_assign_from_unexpected<_OtherErr>) |
710 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { |
711 | if (this->__has_val()) { |
712 | __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__un.error())); |
713 | } else { |
714 | this->__unex() = std::move(__un.error()); |
715 | } |
716 | return *this; |
717 | } |
718 | |
719 | template <class... _Args> |
720 | requires is_nothrow_constructible_v<_Tp, _Args...> |
721 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept { |
722 | this->__destroy(); |
723 | this->__construct(in_place, std::forward<_Args>(__args)...); |
724 | return this->__val(); |
725 | } |
726 | |
727 | template <class _Up, class... _Args> |
728 | requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...> |
729 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept { |
730 | this->__destroy(); |
731 | this->__construct(in_place, __il, std::forward<_Args>(__args)...); |
732 | return this->__val(); |
733 | } |
734 | |
735 | public: |
736 | // [expected.object.swap], swap |
737 | _LIBCPP_HIDE_FROM_ABI constexpr void |
738 | swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp> && |
739 | is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) |
740 | requires(is_swappable_v<_Tp> && is_swappable_v<_Err> && is_move_constructible_v<_Tp> && |
741 | is_move_constructible_v<_Err> && |
742 | (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) |
743 | { |
744 | auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) { |
745 | if constexpr (is_nothrow_move_constructible_v<_Err>) { |
746 | _Err __tmp(std::move(__with_err.__unex())); |
747 | __with_err.__destroy(); |
748 | auto __trans = std::__make_exception_guard([&] { __with_err.__construct(unexpect, std::move(__tmp)); }); |
749 | __with_err.__construct(in_place, std::move(__with_val.__val())); |
750 | __trans.__complete(); |
751 | __with_val.__destroy(); |
752 | __with_val.__construct(unexpect, std::move(__tmp)); |
753 | } else { |
754 | static_assert(is_nothrow_move_constructible_v<_Tp>, |
755 | "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so " |
756 | "that it can be reverted to the previous state in case an exception is thrown during swap." ); |
757 | _Tp __tmp(std::move(__with_val.__val())); |
758 | __with_val.__destroy(); |
759 | auto __trans = std::__make_exception_guard([&] { __with_val.__construct(in_place, std::move(__tmp)); }); |
760 | __with_val.__construct(unexpect, std::move(__with_err.__unex())); |
761 | __trans.__complete(); |
762 | __with_err.__destroy(); |
763 | __with_err.__construct(in_place, std::move(__tmp)); |
764 | } |
765 | }; |
766 | |
767 | if (this->__has_val()) { |
768 | if (__rhs.__has_val()) { |
769 | using std::swap; |
770 | swap(this->__val(), __rhs.__val()); |
771 | } else { |
772 | __swap_val_unex_impl(*this, __rhs); |
773 | } |
774 | } else { |
775 | if (__rhs.__has_val()) { |
776 | __swap_val_unex_impl(__rhs, *this); |
777 | } else { |
778 | using std::swap; |
779 | swap(this->__unex(), __rhs.__unex()); |
780 | } |
781 | } |
782 | } |
783 | |
784 | _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) |
785 | requires requires { __x.swap(__y); } |
786 | { |
787 | __x.swap(__y); |
788 | } |
789 | |
790 | // [expected.object.obs], observers |
791 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { |
792 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
793 | this->__has_val(), "expected::operator-> requires the expected to contain a value" ); |
794 | return std::addressof(this->__val()); |
795 | } |
796 | |
797 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { |
798 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
799 | this->__has_val(), "expected::operator-> requires the expected to contain a value" ); |
800 | return std::addressof(this->__val()); |
801 | } |
802 | |
803 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { |
804 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
805 | this->__has_val(), "expected::operator* requires the expected to contain a value" ); |
806 | return this->__val(); |
807 | } |
808 | |
809 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { |
810 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
811 | this->__has_val(), "expected::operator* requires the expected to contain a value" ); |
812 | return this->__val(); |
813 | } |
814 | |
815 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { |
816 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
817 | this->__has_val(), "expected::operator* requires the expected to contain a value" ); |
818 | return std::move(this->__val()); |
819 | } |
820 | |
821 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { |
822 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
823 | this->__has_val(), "expected::operator* requires the expected to contain a value" ); |
824 | return std::move(this->__val()); |
825 | } |
826 | |
827 | _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); } |
828 | |
829 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); } |
830 | |
831 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { |
832 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible" ); |
833 | if (!this->__has_val()) { |
834 | std::__throw_bad_expected_access<_Err>(std::as_const(error())); |
835 | } |
836 | return this->__val(); |
837 | } |
838 | |
839 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { |
840 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible" ); |
841 | if (!this->__has_val()) { |
842 | std::__throw_bad_expected_access<_Err>(std::as_const(error())); |
843 | } |
844 | return this->__val(); |
845 | } |
846 | |
847 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { |
848 | static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, |
849 | "error_type has to be both copy constructible and constructible from decltype(std::move(error()))" ); |
850 | if (!this->__has_val()) { |
851 | std::__throw_bad_expected_access<_Err>(std::move(error())); |
852 | } |
853 | return std::move(this->__val()); |
854 | } |
855 | |
856 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { |
857 | static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, |
858 | "error_type has to be both copy constructible and constructible from decltype(std::move(error()))" ); |
859 | if (!this->__has_val()) { |
860 | std::__throw_bad_expected_access<_Err>(std::move(error())); |
861 | } |
862 | return std::move(this->__val()); |
863 | } |
864 | |
865 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { |
866 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
867 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
868 | return this->__unex(); |
869 | } |
870 | |
871 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { |
872 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
873 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
874 | return this->__unex(); |
875 | } |
876 | |
877 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { |
878 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
879 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
880 | return std::move(this->__unex()); |
881 | } |
882 | |
883 | _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { |
884 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
885 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
886 | return std::move(this->__unex()); |
887 | } |
888 | |
889 | template <class _Up> |
890 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { |
891 | static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible" ); |
892 | static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type" ); |
893 | return this->__has_val() ? this->__val() : static_cast<_Tp>(std::forward<_Up>(__v)); |
894 | } |
895 | |
896 | template <class _Up> |
897 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { |
898 | static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible" ); |
899 | static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type" ); |
900 | return this->__has_val() ? std::move(this->__val()) : static_cast<_Tp>(std::forward<_Up>(__v)); |
901 | } |
902 | |
903 | template <class _Up = _Err> |
904 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { |
905 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible" ); |
906 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type" ); |
907 | if (has_value()) |
908 | return std::forward<_Up>(__error); |
909 | return error(); |
910 | } |
911 | |
912 | template <class _Up = _Err> |
913 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { |
914 | static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible" ); |
915 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type" ); |
916 | if (has_value()) |
917 | return std::forward<_Up>(__error); |
918 | return std::move(error()); |
919 | } |
920 | |
921 | // [expected.void.monadic], monadic |
922 | template <class _Func> |
923 | requires is_constructible_v<_Err, _Err&> |
924 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { |
925 | using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>; |
926 | static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected" ); |
927 | static_assert(is_same_v<typename _Up::error_type, _Err>, |
928 | "The result of f(value()) must have the same error_type as this expected" ); |
929 | if (has_value()) { |
930 | return std::invoke(std::forward<_Func>(__f), this->__val()); |
931 | } |
932 | return _Up(unexpect, error()); |
933 | } |
934 | |
935 | template <class _Func> |
936 | requires is_constructible_v<_Err, const _Err&> |
937 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { |
938 | using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>; |
939 | static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected" ); |
940 | static_assert(is_same_v<typename _Up::error_type, _Err>, |
941 | "The result of f(value()) must have the same error_type as this expected" ); |
942 | if (has_value()) { |
943 | return std::invoke(std::forward<_Func>(__f), this->__val()); |
944 | } |
945 | return _Up(unexpect, error()); |
946 | } |
947 | |
948 | template <class _Func> |
949 | requires is_constructible_v<_Err, _Err&&> |
950 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { |
951 | using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>; |
952 | static_assert( |
953 | __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected" ); |
954 | static_assert(is_same_v<typename _Up::error_type, _Err>, |
955 | "The result of f(std::move(value())) must have the same error_type as this expected" ); |
956 | if (has_value()) { |
957 | return std::invoke(std::forward<_Func>(__f), std::move(this->__val())); |
958 | } |
959 | return _Up(unexpect, std::move(error())); |
960 | } |
961 | |
962 | template <class _Func> |
963 | requires is_constructible_v<_Err, const _Err&&> |
964 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { |
965 | using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>; |
966 | static_assert( |
967 | __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected" ); |
968 | static_assert(is_same_v<typename _Up::error_type, _Err>, |
969 | "The result of f(std::move(value())) must have the same error_type as this expected" ); |
970 | if (has_value()) { |
971 | return std::invoke(std::forward<_Func>(__f), std::move(this->__val())); |
972 | } |
973 | return _Up(unexpect, std::move(error())); |
974 | } |
975 | |
976 | template <class _Func> |
977 | requires is_constructible_v<_Tp, _Tp&> |
978 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { |
979 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; |
980 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected" ); |
981 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
982 | "The result of f(error()) must have the same value_type as this expected" ); |
983 | if (has_value()) { |
984 | return _Gp(in_place, this->__val()); |
985 | } |
986 | return std::invoke(std::forward<_Func>(__f), error()); |
987 | } |
988 | |
989 | template <class _Func> |
990 | requires is_constructible_v<_Tp, const _Tp&> |
991 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { |
992 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; |
993 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected" ); |
994 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
995 | "The result of f(error()) must have the same value_type as this expected" ); |
996 | if (has_value()) { |
997 | return _Gp(in_place, this->__val()); |
998 | } |
999 | return std::invoke(std::forward<_Func>(__f), error()); |
1000 | } |
1001 | |
1002 | template <class _Func> |
1003 | requires is_constructible_v<_Tp, _Tp&&> |
1004 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { |
1005 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; |
1006 | static_assert( |
1007 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected" ); |
1008 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1009 | "The result of f(std::move(error())) must have the same value_type as this expected" ); |
1010 | if (has_value()) { |
1011 | return _Gp(in_place, std::move(this->__val())); |
1012 | } |
1013 | return std::invoke(std::forward<_Func>(__f), std::move(error())); |
1014 | } |
1015 | |
1016 | template <class _Func> |
1017 | requires is_constructible_v<_Tp, const _Tp&&> |
1018 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { |
1019 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; |
1020 | static_assert( |
1021 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected" ); |
1022 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1023 | "The result of f(std::move(error())) must have the same value_type as this expected" ); |
1024 | if (has_value()) { |
1025 | return _Gp(in_place, std::move(this->__val())); |
1026 | } |
1027 | return std::invoke(std::forward<_Func>(__f), std::move(error())); |
1028 | } |
1029 | |
1030 | template <class _Func> |
1031 | requires is_constructible_v<_Err, _Err&> |
1032 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { |
1033 | using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>; |
1034 | if (!has_value()) { |
1035 | return expected<_Up, _Err>(unexpect, error()); |
1036 | } |
1037 | if constexpr (!is_void_v<_Up>) { |
1038 | return expected<_Up, _Err>( |
1039 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val()); |
1040 | } else { |
1041 | std::invoke(std::forward<_Func>(__f), this->__val()); |
1042 | return expected<_Up, _Err>(); |
1043 | } |
1044 | } |
1045 | |
1046 | template <class _Func> |
1047 | requires is_constructible_v<_Err, const _Err&> |
1048 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { |
1049 | using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>; |
1050 | if (!has_value()) { |
1051 | return expected<_Up, _Err>(unexpect, error()); |
1052 | } |
1053 | if constexpr (!is_void_v<_Up>) { |
1054 | return expected<_Up, _Err>( |
1055 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val()); |
1056 | } else { |
1057 | std::invoke(std::forward<_Func>(__f), this->__val()); |
1058 | return expected<_Up, _Err>(); |
1059 | } |
1060 | } |
1061 | |
1062 | template <class _Func> |
1063 | requires is_constructible_v<_Err, _Err&&> |
1064 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { |
1065 | using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>; |
1066 | if (!has_value()) { |
1067 | return expected<_Up, _Err>(unexpect, std::move(error())); |
1068 | } |
1069 | if constexpr (!is_void_v<_Up>) { |
1070 | return expected<_Up, _Err>( |
1071 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val())); |
1072 | } else { |
1073 | std::invoke(std::forward<_Func>(__f), std::move(this->__val())); |
1074 | return expected<_Up, _Err>(); |
1075 | } |
1076 | } |
1077 | |
1078 | template <class _Func> |
1079 | requires is_constructible_v<_Err, const _Err&&> |
1080 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { |
1081 | using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>; |
1082 | if (!has_value()) { |
1083 | return expected<_Up, _Err>(unexpect, std::move(error())); |
1084 | } |
1085 | if constexpr (!is_void_v<_Up>) { |
1086 | return expected<_Up, _Err>( |
1087 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val())); |
1088 | } else { |
1089 | std::invoke(std::forward<_Func>(__f), std::move(this->__val())); |
1090 | return expected<_Up, _Err>(); |
1091 | } |
1092 | } |
1093 | |
1094 | template <class _Func> |
1095 | requires is_constructible_v<_Tp, _Tp&> |
1096 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { |
1097 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; |
1098 | static_assert(__valid_std_unexpected<_Gp>::value, |
1099 | "The result of f(error()) must be a valid template argument for unexpected" ); |
1100 | if (has_value()) { |
1101 | return expected<_Tp, _Gp>(in_place, this->__val()); |
1102 | } |
1103 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); |
1104 | } |
1105 | |
1106 | template <class _Func> |
1107 | requires is_constructible_v<_Tp, const _Tp&> |
1108 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { |
1109 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; |
1110 | static_assert(__valid_std_unexpected<_Gp>::value, |
1111 | "The result of f(error()) must be a valid template argument for unexpected" ); |
1112 | if (has_value()) { |
1113 | return expected<_Tp, _Gp>(in_place, this->__val()); |
1114 | } |
1115 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); |
1116 | } |
1117 | |
1118 | template <class _Func> |
1119 | requires is_constructible_v<_Tp, _Tp&&> |
1120 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { |
1121 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; |
1122 | static_assert(__valid_std_unexpected<_Gp>::value, |
1123 | "The result of f(std::move(error())) must be a valid template argument for unexpected" ); |
1124 | if (has_value()) { |
1125 | return expected<_Tp, _Gp>(in_place, std::move(this->__val())); |
1126 | } |
1127 | return expected<_Tp, _Gp>( |
1128 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); |
1129 | } |
1130 | |
1131 | template <class _Func> |
1132 | requires is_constructible_v<_Tp, const _Tp&&> |
1133 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { |
1134 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; |
1135 | static_assert(__valid_std_unexpected<_Gp>::value, |
1136 | "The result of f(std::move(error())) must be a valid template argument for unexpected" ); |
1137 | if (has_value()) { |
1138 | return expected<_Tp, _Gp>(in_place, std::move(this->__val())); |
1139 | } |
1140 | return expected<_Tp, _Gp>( |
1141 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); |
1142 | } |
1143 | |
1144 | // [expected.object.eq], equality operators |
1145 | template <class _T2, class _E2> |
1146 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) |
1147 | requires(!is_void_v<_T2>) |
1148 | # if _LIBCPP_STD_VER >= 26 |
1149 | && requires { |
1150 | { *__x == *__y } -> __core_convertible_to<bool>; |
1151 | { __x.error() == __y.error() } -> __core_convertible_to<bool>; |
1152 | } |
1153 | # endif |
1154 | { |
1155 | if (__x.__has_val() != __y.__has_val()) { |
1156 | return false; |
1157 | } else { |
1158 | if (__x.__has_val()) { |
1159 | return __x.__val() == __y.__val(); |
1160 | } else { |
1161 | return __x.__unex() == __y.__unex(); |
1162 | } |
1163 | } |
1164 | } |
1165 | |
1166 | template <class _T2> |
1167 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) |
1168 | # if _LIBCPP_STD_VER >= 26 |
1169 | requires(!__is_std_expected<_T2>::value) && requires { |
1170 | { *__x == __v } -> __core_convertible_to<bool>; |
1171 | } |
1172 | # endif |
1173 | { |
1174 | return __x.__has_val() && static_cast<bool>(__x.__val() == __v); |
1175 | } |
1176 | |
1177 | template <class _E2> |
1178 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) |
1179 | # if _LIBCPP_STD_VER >= 26 |
1180 | requires requires { |
1181 | { __x.error() == __e.error() } -> __core_convertible_to<bool>; |
1182 | } |
1183 | # endif |
1184 | { |
1185 | return !__x.__has_val() && static_cast<bool>(__x.__unex() == __e.error()); |
1186 | } |
1187 | }; |
1188 | |
1189 | template <class _Err> |
1190 | class __expected_void_base { |
1191 | struct __empty_t {}; |
1192 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union, |
1193 | // also guaranteed elision into a potentially-overlapping subobject is unsettled (and |
1194 | // it's not clear that it's implementable, given that the function is allowed to clobber |
1195 | // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. |
1196 | union __union_t { |
1197 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete; |
1198 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) |
1199 | requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) |
1200 | = default; |
1201 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete; |
1202 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) |
1203 | requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) |
1204 | = default; |
1205 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete; |
1206 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&) = delete; |
1207 | |
1208 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t) : __empty_() {} |
1209 | |
1210 | template <class... _Args> |
1211 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args) |
1212 | : __unex_(std::forward<_Args>(__args)...) {} |
1213 | |
1214 | template <class _Func, class... _Args> |
1215 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( |
1216 | __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) |
1217 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} |
1218 | |
1219 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
1220 | requires(is_trivially_destructible_v<_Err>) |
1221 | = default; |
1222 | |
1223 | // __repr's destructor handles this |
1224 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
1225 | requires(!is_trivially_destructible_v<_Err>) |
1226 | {} |
1227 | |
1228 | _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; |
1229 | _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; |
1230 | }; |
1231 | |
1232 | static constexpr bool __put_flag_in_tail = __fits_in_tail_padding<__union_t, bool>; |
1233 | static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail; |
1234 | |
1235 | struct __repr { |
1236 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete; |
1237 | |
1238 | template <class... _Args> |
1239 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag) : __union_(in_place, __tag), __has_val_(true) {} |
1240 | |
1241 | template <class... _Args> |
1242 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args) |
1243 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} |
1244 | |
1245 | template <class... _Args> |
1246 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag, |
1247 | _Args&&... __args) |
1248 | : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} |
1249 | |
1250 | template <class _OtherUnion> |
1251 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other) |
1252 | requires(__allow_reusing_expected_tail_padding) |
1253 | : __union_(__conditional_no_unique_address_invoke_tag{}, |
1254 | [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }), |
1255 | __has_val_(__has_val) {} |
1256 | |
1257 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete; |
1258 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) |
1259 | requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) |
1260 | = default; |
1261 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete; |
1262 | _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) |
1263 | requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) |
1264 | = default; |
1265 | |
1266 | _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete; |
1267 | _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&) = delete; |
1268 | |
1269 | _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() |
1270 | requires(is_trivially_destructible_v<_Err>) |
1271 | = default; |
1272 | |
1273 | _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() |
1274 | requires(!is_trivially_destructible_v<_Err>) |
1275 | { |
1276 | __destroy_union_member(); |
1277 | } |
1278 | |
1279 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() |
1280 | requires(__allow_reusing_expected_tail_padding && is_trivially_destructible_v<_Err>) |
1281 | { |
1282 | std::destroy_at(&__union_.__v); |
1283 | } |
1284 | |
1285 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() |
1286 | requires(__allow_reusing_expected_tail_padding && !is_trivially_destructible_v<_Err>) |
1287 | { |
1288 | __destroy_union_member(); |
1289 | std::destroy_at(&__union_.__v); |
1290 | } |
1291 | |
1292 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t) |
1293 | requires(__allow_reusing_expected_tail_padding) |
1294 | { |
1295 | std::construct_at(&__union_.__v, in_place); |
1296 | __has_val_ = true; |
1297 | } |
1298 | |
1299 | template <class... _Args> |
1300 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args) |
1301 | requires(__allow_reusing_expected_tail_padding) |
1302 | { |
1303 | std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...); |
1304 | __has_val_ = false; |
1305 | } |
1306 | |
1307 | private: |
1308 | template <class> |
1309 | friend class __expected_void_base; |
1310 | |
1311 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member() |
1312 | requires(!is_trivially_destructible_v<_Err>) |
1313 | { |
1314 | if (!__has_val_) |
1315 | std::destroy_at(std::addressof(__union_.__v.__unex_)); |
1316 | } |
1317 | |
1318 | template <class _OtherUnion> |
1319 | _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other) |
1320 | requires(__allow_reusing_expected_tail_padding) |
1321 | { |
1322 | if (__has_val) |
1323 | return __union_t(in_place); |
1324 | else |
1325 | return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_); |
1326 | } |
1327 | |
1328 | _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_; |
1329 | _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_; |
1330 | }; |
1331 | |
1332 | template <class _OtherUnion> |
1333 | _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other) |
1334 | requires(__put_flag_in_tail) |
1335 | { |
1336 | if (__has_val) |
1337 | return __repr(in_place); |
1338 | else |
1339 | return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_); |
1340 | } |
1341 | |
1342 | protected: |
1343 | template <class... _Args> |
1344 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(_Args&&... __args) |
1345 | : __repr_(in_place, std::forward<_Args>(__args)...) {} |
1346 | |
1347 | template <class _OtherUnion> |
1348 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(bool __has_val, _OtherUnion&& __other) |
1349 | requires(__put_flag_in_tail) |
1350 | : __repr_(__conditional_no_unique_address_invoke_tag{}, |
1351 | [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {} |
1352 | |
1353 | _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() { |
1354 | if constexpr (__put_flag_in_tail) |
1355 | std::destroy_at(&__repr_.__v); |
1356 | else |
1357 | __repr_.__v.__destroy_union(); |
1358 | } |
1359 | |
1360 | template <class _Tag, class... _Args> |
1361 | _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) { |
1362 | if constexpr (__put_flag_in_tail) |
1363 | std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...); |
1364 | else |
1365 | __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...); |
1366 | } |
1367 | |
1368 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; } |
1369 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; } |
1370 | _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; } |
1371 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; } |
1372 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; } |
1373 | |
1374 | private: |
1375 | _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_; |
1376 | }; |
1377 | |
1378 | template <class _Tp, class _Err> |
1379 | requires is_void_v<_Tp> |
1380 | class expected<_Tp, _Err> : private __expected_void_base<_Err> { |
1381 | static_assert(__valid_std_unexpected<_Err>::value, |
1382 | "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a " |
1383 | "valid argument for unexpected<E> is ill-formed" ); |
1384 | |
1385 | template <class, class> |
1386 | friend class expected; |
1387 | |
1388 | template <class _Up, class _OtherErr, class _OtherErrQual> |
1389 | using __can_convert _LIBCPP_NODEBUG = |
1390 | _And< is_void<_Up>, |
1391 | is_constructible<_Err, _OtherErrQual>, |
1392 | _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>, |
1393 | _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>, |
1394 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, |
1395 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>; |
1396 | |
1397 | using __base _LIBCPP_NODEBUG = __expected_void_base<_Err>; |
1398 | |
1399 | public: |
1400 | using value_type = _Tp; |
1401 | using error_type = _Err; |
1402 | using unexpected_type = unexpected<_Err>; |
1403 | |
1404 | template <class _Up> |
1405 | using rebind = expected<_Up, error_type>; |
1406 | |
1407 | // [expected.void.ctor], constructors |
1408 | _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __base(in_place) {} |
1409 | |
1410 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; |
1411 | |
1412 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) |
1413 | requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) |
1414 | = default; |
1415 | |
1416 | _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept( |
1417 | is_nothrow_copy_constructible_v<_Err>) // strengthened |
1418 | requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) |
1419 | : __base(__rhs.__has_val(), __rhs.__union()) {} |
1420 | |
1421 | _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) |
1422 | requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) |
1423 | = default; |
1424 | |
1425 | _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>) |
1426 | requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) |
1427 | : __base(__rhs.__has_val(), std::move(__rhs.__union())) {} |
1428 | |
1429 | template <class _Up, class _OtherErr> |
1430 | requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value |
1431 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) |
1432 | expected(const expected<_Up, _OtherErr>& __rhs) noexcept( |
1433 | is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened |
1434 | : __base(__rhs.__has_val(), __rhs.__union()) {} |
1435 | |
1436 | template <class _Up, class _OtherErr> |
1437 | requires __can_convert<_Up, _OtherErr, _OtherErr>::value |
1438 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) |
1439 | expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened |
1440 | : __base(__rhs.__has_val(), std::move(__rhs.__union())) {} |
1441 | |
1442 | template <class _OtherErr> |
1443 | requires is_constructible_v<_Err, const _OtherErr&> |
1444 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected( |
1445 | const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened |
1446 | : __base(unexpect, __unex.error()) {} |
1447 | |
1448 | template <class _OtherErr> |
1449 | requires is_constructible_v<_Err, _OtherErr> |
1450 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) |
1451 | expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened |
1452 | : __base(unexpect, std::move(__unex.error())) {} |
1453 | |
1454 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __base(in_place) {} |
1455 | |
1456 | template <class... _Args> |
1457 | requires is_constructible_v<_Err, _Args...> |
1458 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( |
1459 | is_nothrow_constructible_v<_Err, _Args...>) // strengthened |
1460 | : __base(unexpect, std::forward<_Args>(__args)...) {} |
1461 | |
1462 | template <class _Up, class... _Args> |
1463 | requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > |
1464 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( |
1465 | is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened |
1466 | : __base(unexpect, __il, std::forward<_Args>(__args)...) {} |
1467 | |
1468 | private: |
1469 | template <class _Func, class... _Args> |
1470 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( |
1471 | __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) |
1472 | : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} |
1473 | |
1474 | public: |
1475 | // [expected.void.dtor], destructor |
1476 | |
1477 | _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default; |
1478 | |
1479 | private: |
1480 | template <class... _Args> |
1481 | _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(unexpect_t, _Args&&... __args) { |
1482 | _LIBCPP_ASSERT_INTERNAL(this->__has_val(), "__reinit_expected(unexpect_t, ...) needs value to be set" ); |
1483 | |
1484 | this->__destroy(); |
1485 | auto __trans = std::__make_exception_guard([&] { this->__construct(in_place); }); |
1486 | this->__construct(unexpect, std::forward<_Args>(__args)...); |
1487 | __trans.__complete(); |
1488 | } |
1489 | |
1490 | _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(in_place_t) { |
1491 | _LIBCPP_ASSERT_INTERNAL(!this->__has_val(), "__reinit_expected(in_place_t, ...) needs value to be unset" ); |
1492 | |
1493 | this->__destroy(); |
1494 | this->__construct(in_place); |
1495 | } |
1496 | |
1497 | public: |
1498 | // [expected.void.assign], assignment |
1499 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; |
1500 | |
1501 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( |
1502 | is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened |
1503 | requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) |
1504 | { |
1505 | if (this->__has_val()) { |
1506 | if (!__rhs.__has_val()) { |
1507 | __reinit_expected(unexpect, __rhs.__unex()); |
1508 | } |
1509 | } else { |
1510 | if (__rhs.__has_val()) { |
1511 | __reinit_expected(in_place); |
1512 | } else { |
1513 | this->__unex() = __rhs.__unex(); |
1514 | } |
1515 | } |
1516 | return *this; |
1517 | } |
1518 | |
1519 | _LIBCPP_HIDE_FROM_ABI constexpr expected& |
1520 | operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) |
1521 | requires(is_move_assignable_v<_Err> && is_move_constructible_v<_Err>) |
1522 | { |
1523 | if (this->__has_val()) { |
1524 | if (!__rhs.__has_val()) { |
1525 | __reinit_expected(unexpect, std::move(__rhs.__unex())); |
1526 | } |
1527 | } else { |
1528 | if (__rhs.__has_val()) { |
1529 | __reinit_expected(in_place); |
1530 | } else { |
1531 | this->__unex() = std::move(__rhs.__unex()); |
1532 | } |
1533 | } |
1534 | return *this; |
1535 | } |
1536 | |
1537 | template <class _OtherErr> |
1538 | requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>) |
1539 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { |
1540 | if (this->__has_val()) { |
1541 | __reinit_expected(unexpect, __un.error()); |
1542 | } else { |
1543 | this->__unex() = __un.error(); |
1544 | } |
1545 | return *this; |
1546 | } |
1547 | |
1548 | template <class _OtherErr> |
1549 | requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>) |
1550 | _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { |
1551 | if (this->__has_val()) { |
1552 | __reinit_expected(unexpect, std::move(__un.error())); |
1553 | } else { |
1554 | this->__unex() = std::move(__un.error()); |
1555 | } |
1556 | return *this; |
1557 | } |
1558 | |
1559 | _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept { |
1560 | if (!this->__has_val()) { |
1561 | __reinit_expected(in_place); |
1562 | } |
1563 | } |
1564 | |
1565 | // [expected.void.swap], swap |
1566 | _LIBCPP_HIDE_FROM_ABI constexpr void |
1567 | swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) |
1568 | requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) |
1569 | { |
1570 | auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) { |
1571 | // May throw, but will re-engage `__with_val` in that case. |
1572 | __with_val.__reinit_expected(unexpect, std::move(__with_err.__unex())); |
1573 | // Will not throw. |
1574 | __with_err.__reinit_expected(in_place); |
1575 | }; |
1576 | |
1577 | if (this->__has_val()) { |
1578 | if (!__rhs.__has_val()) { |
1579 | __swap_val_unex_impl(*this, __rhs); |
1580 | } |
1581 | } else { |
1582 | if (__rhs.__has_val()) { |
1583 | __swap_val_unex_impl(__rhs, *this); |
1584 | } else { |
1585 | using std::swap; |
1586 | swap(this->__unex(), __rhs.__unex()); |
1587 | } |
1588 | } |
1589 | } |
1590 | |
1591 | _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) |
1592 | requires requires { __x.swap(__y); } |
1593 | { |
1594 | __x.swap(__y); |
1595 | } |
1596 | |
1597 | // [expected.void.obs], observers |
1598 | _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); } |
1599 | |
1600 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); } |
1601 | |
1602 | _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { |
1603 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
1604 | this->__has_val(), "expected::operator* requires the expected to contain a value" ); |
1605 | } |
1606 | |
1607 | _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { |
1608 | static_assert(is_copy_constructible_v<_Err>); |
1609 | if (!this->__has_val()) { |
1610 | std::__throw_bad_expected_access<_Err>(this->__unex()); |
1611 | } |
1612 | } |
1613 | |
1614 | _LIBCPP_HIDE_FROM_ABI constexpr void value() && { |
1615 | static_assert(is_copy_constructible_v<_Err> && is_move_constructible_v<_Err>); |
1616 | if (!this->__has_val()) { |
1617 | std::__throw_bad_expected_access<_Err>(std::move(this->__unex())); |
1618 | } |
1619 | } |
1620 | |
1621 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { |
1622 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
1623 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
1624 | return this->__unex(); |
1625 | } |
1626 | |
1627 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { |
1628 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
1629 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
1630 | return this->__unex(); |
1631 | } |
1632 | |
1633 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { |
1634 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
1635 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
1636 | return std::move(this->__unex()); |
1637 | } |
1638 | |
1639 | _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { |
1640 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( |
1641 | !this->__has_val(), "expected::error requires the expected to contain an error" ); |
1642 | return std::move(this->__unex()); |
1643 | } |
1644 | |
1645 | template <class _Up = _Err> |
1646 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { |
1647 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible" ); |
1648 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type" ); |
1649 | if (has_value()) { |
1650 | return std::forward<_Up>(__error); |
1651 | } |
1652 | return error(); |
1653 | } |
1654 | |
1655 | template <class _Up = _Err> |
1656 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { |
1657 | static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible" ); |
1658 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type" ); |
1659 | if (has_value()) { |
1660 | return std::forward<_Up>(__error); |
1661 | } |
1662 | return std::move(error()); |
1663 | } |
1664 | |
1665 | // [expected.void.monadic], monadic |
1666 | template <class _Func> |
1667 | requires is_constructible_v<_Err, _Err&> |
1668 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { |
1669 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; |
1670 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected" ); |
1671 | static_assert( |
1672 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected" ); |
1673 | if (has_value()) { |
1674 | return std::invoke(std::forward<_Func>(__f)); |
1675 | } |
1676 | return _Up(unexpect, error()); |
1677 | } |
1678 | |
1679 | template <class _Func> |
1680 | requires is_constructible_v<_Err, const _Err&> |
1681 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { |
1682 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; |
1683 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected" ); |
1684 | static_assert( |
1685 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected" ); |
1686 | if (has_value()) { |
1687 | return std::invoke(std::forward<_Func>(__f)); |
1688 | } |
1689 | return _Up(unexpect, error()); |
1690 | } |
1691 | |
1692 | template <class _Func> |
1693 | requires is_constructible_v<_Err, _Err&&> |
1694 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { |
1695 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; |
1696 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected" ); |
1697 | static_assert( |
1698 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected" ); |
1699 | if (has_value()) { |
1700 | return std::invoke(std::forward<_Func>(__f)); |
1701 | } |
1702 | return _Up(unexpect, std::move(error())); |
1703 | } |
1704 | |
1705 | template <class _Func> |
1706 | requires is_constructible_v<_Err, const _Err&&> |
1707 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { |
1708 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; |
1709 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected" ); |
1710 | static_assert( |
1711 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected" ); |
1712 | if (has_value()) { |
1713 | return std::invoke(std::forward<_Func>(__f)); |
1714 | } |
1715 | return _Up(unexpect, std::move(error())); |
1716 | } |
1717 | |
1718 | template <class _Func> |
1719 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { |
1720 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; |
1721 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected" ); |
1722 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1723 | "The result of f(error()) must have the same value_type as this expected" ); |
1724 | if (has_value()) { |
1725 | return _Gp(); |
1726 | } |
1727 | return std::invoke(std::forward<_Func>(__f), error()); |
1728 | } |
1729 | |
1730 | template <class _Func> |
1731 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { |
1732 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; |
1733 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected" ); |
1734 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1735 | "The result of f(error()) must have the same value_type as this expected" ); |
1736 | if (has_value()) { |
1737 | return _Gp(); |
1738 | } |
1739 | return std::invoke(std::forward<_Func>(__f), error()); |
1740 | } |
1741 | |
1742 | template <class _Func> |
1743 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { |
1744 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; |
1745 | static_assert( |
1746 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected" ); |
1747 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1748 | "The result of f(std::move(error())) must have the same value_type as this expected" ); |
1749 | if (has_value()) { |
1750 | return _Gp(); |
1751 | } |
1752 | return std::invoke(std::forward<_Func>(__f), std::move(error())); |
1753 | } |
1754 | |
1755 | template <class _Func> |
1756 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { |
1757 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; |
1758 | static_assert( |
1759 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected" ); |
1760 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, |
1761 | "The result of f(std::move(error())) must have the same value_type as this expected" ); |
1762 | if (has_value()) { |
1763 | return _Gp(); |
1764 | } |
1765 | return std::invoke(std::forward<_Func>(__f), std::move(error())); |
1766 | } |
1767 | |
1768 | template <class _Func> |
1769 | requires is_constructible_v<_Err, _Err&> |
1770 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { |
1771 | using _Up = remove_cv_t<invoke_result_t<_Func>>; |
1772 | if (!has_value()) { |
1773 | return expected<_Up, _Err>(unexpect, error()); |
1774 | } |
1775 | if constexpr (!is_void_v<_Up>) { |
1776 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); |
1777 | } else { |
1778 | std::invoke(std::forward<_Func>(__f)); |
1779 | return expected<_Up, _Err>(); |
1780 | } |
1781 | } |
1782 | |
1783 | template <class _Func> |
1784 | requires is_constructible_v<_Err, const _Err&> |
1785 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { |
1786 | using _Up = remove_cv_t<invoke_result_t<_Func>>; |
1787 | if (!has_value()) { |
1788 | return expected<_Up, _Err>(unexpect, error()); |
1789 | } |
1790 | if constexpr (!is_void_v<_Up>) { |
1791 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); |
1792 | } else { |
1793 | std::invoke(std::forward<_Func>(__f)); |
1794 | return expected<_Up, _Err>(); |
1795 | } |
1796 | } |
1797 | |
1798 | template <class _Func> |
1799 | requires is_constructible_v<_Err, _Err&&> |
1800 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { |
1801 | using _Up = remove_cv_t<invoke_result_t<_Func>>; |
1802 | if (!has_value()) { |
1803 | return expected<_Up, _Err>(unexpect, std::move(error())); |
1804 | } |
1805 | if constexpr (!is_void_v<_Up>) { |
1806 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); |
1807 | } else { |
1808 | std::invoke(std::forward<_Func>(__f)); |
1809 | return expected<_Up, _Err>(); |
1810 | } |
1811 | } |
1812 | |
1813 | template <class _Func> |
1814 | requires is_constructible_v<_Err, const _Err&&> |
1815 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { |
1816 | using _Up = remove_cv_t<invoke_result_t<_Func>>; |
1817 | if (!has_value()) { |
1818 | return expected<_Up, _Err>(unexpect, std::move(error())); |
1819 | } |
1820 | if constexpr (!is_void_v<_Up>) { |
1821 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); |
1822 | } else { |
1823 | std::invoke(std::forward<_Func>(__f)); |
1824 | return expected<_Up, _Err>(); |
1825 | } |
1826 | } |
1827 | |
1828 | template <class _Func> |
1829 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { |
1830 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; |
1831 | static_assert(__valid_std_unexpected<_Gp>::value, |
1832 | "The result of f(error()) must be a valid template argument for unexpected" ); |
1833 | if (has_value()) { |
1834 | return expected<_Tp, _Gp>(); |
1835 | } |
1836 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); |
1837 | } |
1838 | |
1839 | template <class _Func> |
1840 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { |
1841 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; |
1842 | static_assert(__valid_std_unexpected<_Gp>::value, |
1843 | "The result of f(error()) must be a valid template argument for unexpected" ); |
1844 | if (has_value()) { |
1845 | return expected<_Tp, _Gp>(); |
1846 | } |
1847 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); |
1848 | } |
1849 | |
1850 | template <class _Func> |
1851 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { |
1852 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; |
1853 | static_assert(__valid_std_unexpected<_Gp>::value, |
1854 | "The result of f(std::move(error())) must be a valid template argument for unexpected" ); |
1855 | if (has_value()) { |
1856 | return expected<_Tp, _Gp>(); |
1857 | } |
1858 | return expected<_Tp, _Gp>( |
1859 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); |
1860 | } |
1861 | |
1862 | template <class _Func> |
1863 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { |
1864 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; |
1865 | static_assert(__valid_std_unexpected<_Gp>::value, |
1866 | "The result of f(std::move(error())) must be a valid template argument for unexpected" ); |
1867 | if (has_value()) { |
1868 | return expected<_Tp, _Gp>(); |
1869 | } |
1870 | return expected<_Tp, _Gp>( |
1871 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); |
1872 | } |
1873 | |
1874 | // [expected.void.eq], equality operators |
1875 | template <class _T2, class _E2> |
1876 | requires is_void_v<_T2> |
1877 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) |
1878 | # if _LIBCPP_STD_VER >= 26 |
1879 | requires requires { |
1880 | { __x.error() == __y.error() } -> __core_convertible_to<bool>; |
1881 | } |
1882 | # endif |
1883 | { |
1884 | if (__x.__has_val() != __y.__has_val()) { |
1885 | return false; |
1886 | } else { |
1887 | return __x.__has_val() || static_cast<bool>(__x.__unex() == __y.__unex()); |
1888 | } |
1889 | } |
1890 | |
1891 | template <class _E2> |
1892 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) |
1893 | # if _LIBCPP_STD_VER >= 26 |
1894 | requires requires { |
1895 | { __x.error() == __y.error() } -> __core_convertible_to<bool>; |
1896 | } |
1897 | # endif |
1898 | { |
1899 | return !__x.__has_val() && static_cast<bool>(__x.__unex() == __y.error()); |
1900 | } |
1901 | }; |
1902 | |
1903 | _LIBCPP_END_NAMESPACE_STD |
1904 | |
1905 | #endif // _LIBCPP_STD_VER >= 23 |
1906 | |
1907 | _LIBCPP_POP_MACROS |
1908 | |
1909 | #endif // _LIBCPP___EXPECTED_EXPECTED_H |
1910 | |