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