NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
expected.hpp
1#ifndef NEFORCE_CORE_UTILITY_EXPECTED_HPP__
2#define NEFORCE_CORE_UTILITY_EXPECTED_HPP__
5NEFORCE_BEGIN_NAMESPACE__
6
7struct expected_exception final : exception {
8 explicit expected_exception(const char* info = "Expected Operation Failed.", const char* type = static_type,
9 const int code = 0) noexcept :
10 exception(info, type, code) {}
11
12 explicit expected_exception(const exception& e) :
13 exception(e) {}
14
15 ~expected_exception() override = default;
16 static constexpr auto static_type = "expected_exception";
17};
18
19
20struct inplace_invoke_tag {
21 constexpr inplace_invoke_tag() noexcept = default;
22};
23
24struct unexpect_invoke_tag {
25 constexpr unexpect_invoke_tag() noexcept = default;
26};
27
28
29struct unexpect_t {
30 explicit unexpect_t() noexcept = default;
31};
32
33NEFORCE_INLINE17 constexpr unexpect_t unexpect{};
34
35
36template <typename T, typename ErrorT, typename = void>
37class expected;
38
39template <typename ErrorT>
40class unexpected;
41
42
43template <typename T>
44NEFORCE_INLINE17 constexpr bool is_expected = false;
45template <typename T, typename ErrorT>
46NEFORCE_INLINE17 constexpr bool is_expected<expected<T, ErrorT>> = true;
47
48template <typename T>
49NEFORCE_INLINE17 constexpr bool is_unexpected = false;
50template <typename T>
51NEFORCE_INLINE17 constexpr bool is_unexpected<unexpected<T>> = true;
52
53
54NEFORCE_BEGIN_INNER__
55template <typename Func, typename T>
56using expected_invoke_result = remove_cvref_t<invoke_result_t<Func&&, T&&>>;
57template <typename Func, typename T>
58using expected_transform_result = remove_cv_t<invoke_result_t<Func&&, T&&>>;
59template <typename Func>
60using expected_invoke_narg_result = remove_cvref_t<invoke_result_t<Func&&>>;
61template <typename Func>
62using expected_transform_narg_result = remove_cv_t<invoke_result_t<Func&&>>;
63
64template <typename ErrorT>
65NEFORCE_INLINE17 constexpr bool can_be_unexpected =
66 is_object_v<ErrorT> && !is_array_v<ErrorT> && !is_unexpected<ErrorT> && !is_const_v<ErrorT> &&
68NEFORCE_END_INNER__
69
70
71template <typename ErrorT>
72class unexpected {
73 static_assert(inner::can_be_unexpected<ErrorT>, "ErrorT should be non-array, unexpected, const or volatile type");
74
75private:
76 ErrorT error_;
77
78public:
79 constexpr unexpected(const unexpected&) = default;
80 constexpr unexpected(unexpected&&) = default;
81
82 template <typename Err = ErrorT, typename = enable_if_t<!is_same_v<remove_cvref_t<Err>, unexpected> &&
83 !is_same_v<remove_cvref_t<Err>, inplace_construct_tag> &&
84 is_constructible_v<ErrorT, Err>>>
85 constexpr explicit unexpected(Err&& error) noexcept(is_nothrow_constructible_v<ErrorT, Err>) :
86 error_(_NEFORCE forward<Err>(error)) {}
87
88 template <typename... Args, typename = enable_if_t<is_constructible_v<ErrorT, Args...>>>
89 constexpr explicit unexpected(inplace_construct_tag,
90 Args&&... args) noexcept(is_nothrow_constructible_v<ErrorT, Args...>) :
91 error_(_NEFORCE forward<Args>(args)...) {}
92
93 template <typename U, typename... Args,
95 constexpr explicit unexpected(inplace_construct_tag, std::initializer_list<U> list, Args&&... args) noexcept(
97 error_(list, _NEFORCE forward<Args>(args)...) {}
98
99 constexpr unexpected& operator=(const unexpected&) = default;
100 constexpr unexpected& operator=(unexpected&&) = default;
101
102 NEFORCE_NODISCARD constexpr const ErrorT& error() const& noexcept { return error_; }
103
104 NEFORCE_NODISCARD constexpr ErrorT& error() & noexcept { return error_; }
105
106 NEFORCE_NODISCARD constexpr const ErrorT&& error() const&& noexcept { return _NEFORCE move(error_); }
107
108 NEFORCE_NODISCARD constexpr ErrorT&& error() && noexcept { return _NEFORCE move(error_); }
109
110 constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<ErrorT>) {
111 _NEFORCE swap(error_, other.error_);
112 }
113
114 template <typename OtherError>
115 NEFORCE_NODISCARD friend constexpr bool operator==(const unexpected& lhs, const unexpected<OtherError>& rhs) {
116 return lhs.error_ == rhs.error();
117 }
118};
119
120#ifdef NEFORCE_STANDARD_17
121template <typename ErrorT>
122unexpected(ErrorT) -> unexpected<ErrorT>;
123#endif
124
125
126template <typename T, typename ErrorT, typename Dummy>
127class expected {
128 static_assert(!is_reference_v<T>, "T must not be reference type");
129 static_assert(!is_function_v<T>, "T must not be function type");
130 static_assert(!is_same_v<remove_cv_t<T>, inplace_construct_tag>, "T must not be same with inplace_construct_tag");
131 static_assert(!is_same_v<remove_cv_t<T>, unexpect_t>, "T must not be same with unexpected_t");
132 static_assert(!is_unexpected<remove_cv_t<T>>, "T must not be unexpected");
133 static_assert(inner::can_be_unexpected<ErrorT>, "ErrorT must be unexpected");
134
135 template <typename U, typename Err, typename UE = unexpected<ErrorT>>
136 using constructible_from_expected =
137 disjunction<is_constructible<T, expected<U, Err>&>, is_constructible<T, expected<U, Err>>,
138 is_constructible<T, const expected<U, Err>&>, is_constructible<T, const expected<U, Err>>,
139 is_convertible<expected<U, Err>&, T>, is_convertible<expected<U, Err>, T>,
140 is_convertible<const expected<U, Err>&, T>, is_convertible<const expected<U, Err>, T>,
141 is_constructible<UE, expected<U, Err>&>, is_constructible<UE, expected<U, Err>>,
142 is_constructible<UE, const expected<U, Err>&>, is_constructible<UE, const expected<U, Err>>>;
143
144 template <typename U, typename Err>
145 static constexpr bool explicit_conversion =
146 disjunction_v<negation<is_convertible<U, T>>, negation<is_convertible<Err, ErrorT>>>;
147
148 template <typename U>
149 static constexpr bool same_value = is_same_v<typename U::value_type, T>;
150
151 template <typename U>
152 static constexpr bool same_error = is_same_v<typename U::error_type, ErrorT>;
153
154public:
155 using value_type = T;
156 using error_type = ErrorT;
157 using unexpected_type = unexpected<ErrorT>;
158
159 template <typename U>
160 using rebind = expected<U, error_type>;
161
162private:
163 union {
164 T value_;
165 ErrorT error_{};
166 };
167
168 bool has_value_{false};
169
170 template <typename, typename, typename>
171 friend class expected;
172
173private:
174 template <typename U>
175 constexpr void assign_value(U&& val) {
176 if (has_value_) {
177 value_ = _NEFORCE forward<U>(val);
178 } else {
179 _NEFORCE reinitialize(_NEFORCE addressof(value_), _NEFORCE addressof(error_), _NEFORCE forward<U>(val));
180 has_value_ = true;
181 }
182 }
183
184 template <typename U>
185 constexpr void assign_error(U&& err) {
186 if (has_value_) {
187 _NEFORCE reinitialize(_NEFORCE addressof(error_), _NEFORCE addressof(value_), _NEFORCE forward<U>(err));
188 has_value_ = false;
189 } else {
190 error_ = _NEFORCE forward<U>(err);
191 }
192 }
193
194 constexpr void swap_value_error(expected& other) noexcept(
195 conjunction_v<is_nothrow_move_constructible<ErrorT>, is_nothrow_move_constructible<T>>) {
196 NEFORCE_IF_CONSTEXPR(is_nothrow_move_constructible_v<ErrorT>) {
197 temporary_guard<ErrorT> guard(other.error_);
198 _NEFORCE construct(_NEFORCE addressof(other.value_), _NEFORCE move(value_));
199 other.has_value_ = true;
200 _NEFORCE destroy(_NEFORCE addressof(value_));
201 _NEFORCE construct(_NEFORCE addressof(error_), guard.release());
202 has_value_ = false;
203 }
204 else {
205 temporary_guard<T> guard(value_);
206 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other.error_));
207 has_value_ = false;
208 _NEFORCE destroy(_NEFORCE addressof(other.error_));
209 _NEFORCE construct(_NEFORCE addressof(other.value_), guard.release());
210 other.has_value_ = true;
211 }
212 }
213
214 template <typename Func>
215 explicit constexpr expected(inplace_invoke_tag, Func&& func) :
216 value_(_NEFORCE forward<Func>(func)()),
217 has_value_(true) {}
218
219 template <typename Func>
220 explicit constexpr expected(unexpect_invoke_tag, Func&& func) :
221 error_(_NEFORCE forward<Func>(func)()) {}
222
223public:
224 constexpr expected() noexcept(is_nothrow_default_constructible_v<T>) :
225 value_(),
226 has_value_(true) {}
227
228 constexpr expected(const expected& other) noexcept(
229 conjunction_v<is_nothrow_copy_constructible<T>, is_nothrow_copy_constructible<ErrorT>>) :
230 has_value_(other.has_value_) {
231 if (has_value_) {
232 _NEFORCE construct(_NEFORCE addressof(value_), other.value_);
233 } else {
234 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
235 }
236 }
237
238 constexpr expected(expected&& other) noexcept(
239 conjunction_v<is_nothrow_move_constructible<T>, is_nothrow_move_constructible<ErrorT>>) :
240 has_value_(other.has_value_) {
241 if (has_value_) {
242 _NEFORCE construct(_NEFORCE addressof(value_), _NEFORCE move(other).value_);
243 } else {
244 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
245 }
246 }
247
248 template <typename U, typename Gr,
250 (!constructible_from_expected<U, Gr>::value) &&
251 explicit_conversion<const U&, const Gr&>,
252 int> = 0>
253 constexpr explicit expected(const expected<U, Gr>& other) noexcept(
254 conjunction_v<is_nothrow_constructible<T, const U&>, is_nothrow_constructible<ErrorT, const Gr&>>) :
255 has_value_(other.has_value_) {
256 if (has_value_) {
257 _NEFORCE construct(_NEFORCE addressof(value_), other.value_);
258 } else {
259 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
260 }
261 }
262
263 template <typename U, typename Gr,
265 (!constructible_from_expected<U, Gr>::value) &&
266 !explicit_conversion<const U&, const Gr&>,
267 int> = 0>
268 constexpr expected(const expected<U, Gr>& other) noexcept(
269 conjunction_v<is_nothrow_constructible<T, const U&>, is_nothrow_constructible<ErrorT, const Gr&>>) :
270 has_value_(other.has_value_) {
271 if (has_value_) {
272 _NEFORCE construct(_NEFORCE addressof(value_), other.value_);
273 } else {
274 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
275 }
276 }
277
278 template <typename U, typename Gr,
280 (!constructible_from_expected<U, Gr>::value) && explicit_conversion<U, Gr>,
281 int> = 0>
282 constexpr explicit expected(expected<U, Gr>&& other) noexcept(
283 conjunction_v<is_nothrow_constructible<T, U>, is_nothrow_constructible<ErrorT, Gr>>) :
284 has_value_(other.has_value_) {
285 if (has_value_) {
286 _NEFORCE construct(_NEFORCE addressof(value_), _NEFORCE move(other).value_);
287 } else {
288 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
289 }
290 }
291
292 template <typename U, typename Gr,
294 (!constructible_from_expected<U, Gr>::value) && !explicit_conversion<U, Gr>,
295 int> = 0>
296 constexpr expected(expected<U, Gr>&& other) noexcept(
297 conjunction_v<is_nothrow_constructible<T, U>, is_nothrow_constructible<ErrorT, Gr>>) :
298 has_value_(other.has_value_) {
299 if (has_value_) {
300 _NEFORCE construct(_NEFORCE addressof(value_), _NEFORCE move(other).value_);
301 } else {
302 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
303 }
304 }
305
306 template <typename U = T, enable_if_t<(!is_same_v<remove_cvref_t<U>, expected>) &&
307 (!is_same_v<remove_cvref_t<U>, inplace_construct_tag>) &&
308 (!is_unexpected<remove_cvref_t<U>>) && is_constructible_v<T, U> &&
309 !is_convertible_v<U, T>,
310 int> = 0>
311 constexpr explicit expected(U&& value) noexcept(is_nothrow_constructible_v<T, U>) :
312 value_(_NEFORCE forward<U>(value)),
313 has_value_(true) {}
314
315 template <typename U = T, enable_if_t<(!is_same_v<remove_cvref_t<U>, expected>) &&
316 (!is_same_v<remove_cvref_t<U>, inplace_construct_tag>) &&
317 (!is_unexpected<remove_cvref_t<U>>) && is_constructible_v<T, U> &&
318 is_convertible_v<U, T>,
319 int> = 0>
320 constexpr expected(U&& value) noexcept(is_nothrow_constructible_v<T, U>) :
321 value_(_NEFORCE forward<U>(value)),
322 has_value_(true) {}
323
324 template <typename Gr = ErrorT,
326 constexpr explicit expected(const unexpected<Gr>& unex) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
327 error_(unex.error()) {}
328
329 template <typename Gr = ErrorT,
331 constexpr expected(const unexpected<Gr>& unex) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
332 error_(unex.error()) {}
333
334 template <typename Gr = ErrorT,
336 constexpr explicit expected(unexpected<Gr>&& unex) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
337 error_(_NEFORCE move(unex).error()) {}
338
339 template <typename Gr = ErrorT,
341 constexpr expected(unexpected<Gr>&& unex) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
342 error_(_NEFORCE move(unex).error()) {}
343
344 template <typename... Args, enable_if_t<is_constructible_v<T, Args...>, int> = 0>
345 constexpr explicit expected(inplace_construct_tag,
346 Args&&... args) noexcept(is_nothrow_constructible_v<T, Args...>) :
347 value_(_NEFORCE forward<Args>(args)...),
348 has_value_(true) {}
349
350 template <typename U, typename... Args,
352 constexpr explicit expected(inplace_construct_tag, std::initializer_list<U> list, Args&&... args) noexcept(
354 value_(list, _NEFORCE forward<Args>(args)...),
355 has_value_(true) {}
356
357 template <typename... Args, enable_if_t<is_constructible_v<ErrorT, Args...>, int> = 0>
358 constexpr explicit expected(unexpect_t, Args&&... args) noexcept(is_nothrow_constructible_v<ErrorT, Args...>) :
359 error_(_NEFORCE forward<Args>(args)...) {}
360
361 template <typename U, typename... Args,
363 constexpr explicit expected(unexpect_t, std::initializer_list<U> list, Args&&... args) noexcept(
365 error_(list, _NEFORCE forward<Args>(args)...) {}
366
367 NEFORCE_CONSTEXPR20 ~expected() {
368 if (has_value_) {
369 _NEFORCE destroy(_NEFORCE addressof(value_));
370 } else {
371 _NEFORCE destroy(_NEFORCE addressof(error_));
372 }
373 }
374
375 constexpr expected& operator=(const expected& other) noexcept(
376 conjunction_v<is_nothrow_copy_constructible<T>, is_nothrow_copy_constructible<ErrorT>,
377 is_nothrow_copy_assignable<T>, is_nothrow_copy_assignable<ErrorT>>) {
378 if (other.has_value_) {
379 assign_value(other.value_);
380 } else {
381 assign_error(other.error_);
382 }
383 return *this;
384 }
385
386 constexpr expected& operator=(expected&& other) noexcept(
387 conjunction_v<is_nothrow_move_constructible<T>, is_nothrow_move_constructible<ErrorT>,
388 is_nothrow_move_assignable<T>, is_nothrow_move_assignable<ErrorT>>) {
389 if (other.has_value_) {
390 assign_value(_NEFORCE move(other.value_));
391 } else {
392 assign_error(_NEFORCE move(other.error_));
393 }
394 return *this;
395 }
396
397 template <typename U = T,
400 int> = 0>
401 constexpr expected& operator=(U&& value) {
402 assign_value(_NEFORCE forward<U>(value));
403 return *this;
404 }
405
406 template <typename Gr,
408 constexpr expected& operator=(const unexpected<Gr>& unex) {
409 assign_error(unex.error());
410 return *this;
411 }
412
413 template <typename Gr,
415 constexpr expected& operator=(unexpected<Gr>&& unex) {
416 assign_error(_NEFORCE move(unex).error());
417 return *this;
418 }
419
420 template <typename... Args, enable_if_t<is_nothrow_constructible_v<T, Args...>, int> = 0>
421 constexpr T& emplace(Args&&... args) noexcept {
422 if (has_value_) {
423 _NEFORCE destroy(_NEFORCE addressof(value_));
424 } else {
425 _NEFORCE destroy(_NEFORCE addressof(error_));
426 has_value_ = true;
427 }
428 _NEFORCE construct(_NEFORCE addressof(value_), _NEFORCE forward<Args>(args)...);
429 return value_;
430 }
431
432 template <typename U, typename... Args,
434 constexpr T& emplace(std::initializer_list<U> list, Args&&... args) noexcept {
435 if (has_value_) {
436 _NEFORCE destroy(_NEFORCE addressof(value_));
437 } else {
438 _NEFORCE destroy(_NEFORCE addressof(error_));
439 has_value_ = true;
440 }
441 _NEFORCE construct(_NEFORCE addressof(value_), list, _NEFORCE forward<Args>(args)...);
442 return value_;
443 }
444
445 constexpr void swap(expected& other) noexcept(
446 conjunction_v<is_nothrow_move_constructible<T>, is_nothrow_move_constructible<ErrorT>,
447 is_nothrow_swappable<T&>, is_nothrow_swappable<ErrorT&>>) {
448 if (has_value_) {
449 if (other.has_value_) {
450 _NEFORCE swap(value_, other.value_);
451 } else {
452 this->swap_value_error(other);
453 }
454 } else {
455 if (other.has_value_) {
456 other.swap_value_error(*this);
457 } else {
458 _NEFORCE swap(error_, other.error_);
459 }
460 }
461 }
462
463 NEFORCE_NODISCARD constexpr const T* operator->() const noexcept {
464 NEFORCE_CONSTEXPR_ASSERT(has_value_);
465 return _NEFORCE addressof(value_);
466 }
467
468 NEFORCE_NODISCARD constexpr T* operator->() noexcept {
469 NEFORCE_CONSTEXPR_ASSERT(has_value_);
470 return _NEFORCE addressof(value_);
471 }
472
473 NEFORCE_NODISCARD constexpr const T& operator*() const& noexcept {
474 NEFORCE_CONSTEXPR_ASSERT(has_value_);
475 return value_;
476 }
477
478 NEFORCE_NODISCARD constexpr T& operator*() & noexcept {
479 NEFORCE_CONSTEXPR_ASSERT(has_value_);
480 return value_;
481 }
482
483 NEFORCE_NODISCARD constexpr const T&& operator*() const&& noexcept {
484 NEFORCE_CONSTEXPR_ASSERT(has_value_);
485 return _NEFORCE move(value_);
486 }
487
488 NEFORCE_NODISCARD constexpr T&& operator*() && noexcept {
489 NEFORCE_CONSTEXPR_ASSERT(has_value_);
490 return _NEFORCE move(value_);
491 }
492
493 NEFORCE_NODISCARD constexpr explicit operator bool() const noexcept { return has_value_; }
494
495 NEFORCE_NODISCARD constexpr bool has_value() const noexcept { return has_value_; }
496
497 constexpr const T& value() const& {
498 if (has_value_) {
499 NEFORCE_LIKELY { return value_; }
500 }
501 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
502 }
503
504 constexpr T& value() & {
505 if (has_value_) {
506 NEFORCE_LIKELY { return value_; }
507 }
508 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
509 }
510
511 constexpr const T&& value() const&& {
512 if (has_value_) {
513 NEFORCE_LIKELY { return _NEFORCE move(value_); }
514 }
515 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
516 }
517
518 constexpr T&& value() && {
519 if (has_value_) {
520 NEFORCE_LIKELY { return _NEFORCE move(value_); }
521 }
522 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
523 }
524
525 constexpr const ErrorT& error() const& noexcept {
526 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
527 return error_;
528 }
529
530 constexpr ErrorT& error() & noexcept {
531 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
532 return error_;
533 }
534
535 constexpr const ErrorT&& error() const&& noexcept {
536 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
537 return _NEFORCE move(error_);
538 }
539
540 constexpr ErrorT&& error() && noexcept {
541 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
542 return _NEFORCE move(error_);
543 }
544
545 template <typename U>
546 constexpr T
547 value_or(U&& alt) const& noexcept(conjunction_v<is_nothrow_copy_constructible<T>, is_nothrow_convertible<U, T>>) {
548 static_assert(is_copy_constructible_v<T>, "T must be copy constructible");
549 static_assert(is_convertible_v<U, T>, "U must be convertible to T");
550
551 if (has_value_) {
552 return value_;
553 }
554 return static_cast<T>(_NEFORCE forward<U>(alt));
555 }
556
557 template <typename U>
558 constexpr T
559 value_or(U&& alt) && noexcept(conjunction_v<is_nothrow_move_constructible<T>, is_nothrow_convertible<U, T>>) {
560 static_assert(is_move_constructible_v<T>, "T must be move constructible");
561 static_assert(is_convertible_v<U, T>, "U must be convertible to T");
562
563 if (has_value_) {
564 return _NEFORCE move(value_);
565 }
566 return static_cast<T>(_NEFORCE forward<U>(alt));
567 }
568
569 template <typename Gr = ErrorT>
570 constexpr ErrorT error_or(Gr&& alt) const& {
571 static_assert(is_copy_constructible_v<ErrorT>, "ErrorT must be copy constructible");
572 static_assert(is_convertible_v<Gr, ErrorT>, "Gr must be convertible to ErrorT");
573
574 if (has_value_) {
575 return _NEFORCE forward<Gr>(alt);
576 }
577 return error_;
578 }
579
580 template <typename Gr = ErrorT>
581 constexpr ErrorT error_or(Gr&& alt) && {
582 static_assert(is_move_constructible_v<ErrorT>, "ErrorT must be move constructible");
583 static_assert(is_convertible_v<Gr, ErrorT>, "Gr must be convertible to ErrorT");
584
585 if (has_value_) {
586 return _NEFORCE forward<Gr>(alt);
587 }
588 return _NEFORCE move(error_);
589 }
590
591 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT&>, int> = 0>
592 constexpr auto and_then(Func&& func) & {
593 using Res = inner::expected_invoke_result<Func, T&>;
594 static_assert(is_expected<Res>, "Func must return an expected type");
595 static_assert(is_same_v<typename Res::error_type, ErrorT>, "Func must return an expected with same error type");
596
597 if (has_value()) {
598 return _NEFORCE invoke(_NEFORCE forward<Func>(func), value_);
599 } else {
600 return Res(unexpect, error_);
601 }
602 }
603
604 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT&>, int> = 0>
605 constexpr auto and_then(Func&& func) const& {
606 using Res = inner::expected_invoke_result<Func, const T&>;
607 static_assert(is_expected<Res>, "Func must return an expected type");
608 static_assert(is_same_v<typename Res::error_type, ErrorT>, "Func must return an expected with same error type");
609
610 if (has_value()) {
611 return _NEFORCE invoke(_NEFORCE forward<Func>(func), value_);
612 } else {
613 return Res(unexpect, error_);
614 }
615 }
616
617 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT>, int> = 0>
618 constexpr auto and_then(Func&& func) && {
619 using Res = inner::expected_invoke_result<Func, T&&>;
620 static_assert(is_expected<Res>, "Func must return an expected type");
621 static_assert(is_same_v<typename Res::error_type, ErrorT>, "Func must return an expected with same error type");
622
623 if (has_value()) {
624 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(value_));
625 } else {
626 return Res(unexpect, _NEFORCE move(error_));
627 }
628 }
629
630 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT>, int> = 0>
631 constexpr auto and_then(Func&& func) const&& {
632 using Res = inner::expected_invoke_result<Func, const T&&>;
633 static_assert(is_expected<Res>, "Func must return an expected type");
634 static_assert(is_same_v<typename Res::error_type, ErrorT>, "Func must return an expected with same error type");
635
636 if (has_value()) {
637 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(value_));
638 } else {
639 return Res(unexpect, _NEFORCE move(error_));
640 }
641 }
642
643 template <typename Func, enable_if_t<is_constructible_v<T, T&>, int> = 0>
644 constexpr auto or_else(Func&& func) & {
645 using Res = inner::expected_invoke_result<Func, ErrorT&>;
646 static_assert(is_expected<Res>, "Func must return an expected type");
647 static_assert(is_same_v<typename Res::value_type, T>, "Func must return an expected with same value type");
648
649 if (has_value()) {
650 return Res(inplace_construct_tag{}, value_);
651 } else {
652 return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_);
653 }
654 }
655
656 template <typename Func, enable_if_t<is_constructible_v<T, const T&>, int> = 0>
657 constexpr auto or_else(Func&& func) const& {
658 using Res = inner::expected_invoke_result<Func, const ErrorT&>;
659 static_assert(is_expected<Res>, "Func must return an expected type");
660 static_assert(is_same_v<typename Res::value_type, T>, "Func must return an expected with same value type");
661
662 if (has_value()) {
663 return Res(inplace_construct_tag{}, value_);
664 } else {
665 return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_);
666 }
667 }
668
669 template <typename Func, enable_if_t<is_constructible_v<T, T>, int> = 0>
670 constexpr auto or_else(Func&& func) && {
671 using Res = inner::expected_invoke_result<Func, ErrorT&&>;
672 static_assert(is_expected<Res>, "Func must return an expected type");
673 static_assert(is_same_v<typename Res::value_type, T>, "Func must return an expected with same value type");
674
675 if (has_value()) {
676 return Res(inplace_construct_tag{}, _NEFORCE move(value_));
677 } else {
678 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_));
679 }
680 }
681
682 template <typename Func, enable_if_t<is_constructible_v<T, const T>, int> = 0>
683 constexpr auto or_else(Func&& func) const&& {
684 using Res = inner::expected_invoke_result<Func, const ErrorT&&>;
685 static_assert(is_expected<Res>, "Func must return an expected type");
686 static_assert(is_same_v<typename Res::value_type, T>, "Func must return an expected with same value type");
687
688 if (has_value()) {
689 return Res(inplace_construct_tag{}, _NEFORCE move(value_));
690 } else {
691 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_));
692 }
693 }
694
695 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT&>, int> = 0>
696 constexpr auto transform(Func&& func) & {
697 using U = inner::expected_transform_result<Func, T&>;
698 using Res = expected<U, ErrorT>;
699
700 if (has_value()) {
701 return Res(inplace_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), value_); });
702 } else {
703 return Res(unexpect, error_);
704 }
705 }
706
707 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT&>, int> = 0>
708 constexpr auto transform(Func&& func) const& {
709 using U = inner::expected_transform_result<Func, const T&>;
710 using Res = expected<U, ErrorT>;
711
712 if (has_value()) {
713 return Res(inplace_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), value_); });
714 } else {
715 return Res(unexpect, error_);
716 }
717 }
718
719 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT>, int> = 0>
720 constexpr auto transform(Func&& func) && {
721 using U = inner::expected_transform_result<Func, T>;
722 using Res = expected<U, ErrorT>;
723
724 if (has_value()) {
725 return Res(inplace_invoke_tag{},
726 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(value_)); });
727 } else {
728 return Res(unexpect, _NEFORCE move(error_));
729 }
730 }
731
732 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT>, int> = 0>
733 constexpr auto transform(Func&& func) const&& {
734 using U = inner::expected_transform_result<Func, const T>;
735 using Res = expected<U, ErrorT>;
736
737 if (has_value()) {
738 return Res(inplace_invoke_tag{},
739 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(value_)); });
740 } else {
741 return Res(unexpect, _NEFORCE move(error_));
742 }
743 }
744
745 template <typename Func, enable_if_t<is_constructible_v<T, T&>, int> = 0>
746 constexpr auto transform_error(Func&& func) & {
747 using Gr = inner::expected_transform_result<Func, ErrorT&>;
748 using Res = expected<T, Gr>;
749
750 if (has_value()) {
751 return Res(inplace_construct_tag{}, value_);
752 } else {
753 return Res(unexpect_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_); });
754 }
755 }
756
757 template <typename Func, enable_if_t<is_constructible_v<T, const T&>, int> = 0>
758 constexpr auto transform_error(Func&& func) const& {
759 using Gr = inner::expected_transform_result<Func, const ErrorT&>;
760 using Res = expected<T, Gr>;
761
762 if (has_value()) {
763 return Res(inplace_construct_tag{}, value_);
764 } else {
765 return Res(unexpect_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_); });
766 }
767 }
768
769 template <typename Func, enable_if_t<is_constructible_v<T, T>, int> = 0>
770 constexpr auto transform_error(Func&& func) && {
771 using Gr = inner::expected_transform_result<Func, ErrorT&&>;
772 using Res = expected<T, Gr>;
773
774 if (has_value()) {
775 return Res(inplace_construct_tag{}, _NEFORCE move(value_));
776 } else {
777 return Res(unexpect_invoke_tag{},
778 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_)); });
779 }
780 }
781
782 template <typename Func, enable_if_t<is_constructible_v<T, const T>, int> = 0>
783 constexpr auto transform_error(Func&& func) const&& {
784 using Gr = inner::expected_transform_result<Func, const ErrorT&&>;
785 using Res = expected<T, Gr>;
786
787 if (has_value()) {
788 return Res(inplace_construct_tag{}, _NEFORCE move(value_));
789 } else {
790 return Res(unexpect_invoke_tag{},
791 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_)); });
792 }
793 }
794
795 template <typename U, typename Err2, enable_if_t<!is_void_v<U>, int> = 0>
796 constexpr bool operator==(const expected<U, Err2>& rhs) {
797 if (has_value()) {
798 return rhs.has_value() && value_ == *rhs;
799 } else {
800 return !rhs.has_value() && error() == rhs.error();
801 }
802 }
803
804 template <typename U>
805 constexpr bool operator==(const U& value) {
806 return has_value() && value_ == value;
807 }
808
809 template <typename Err2>
810 constexpr bool operator==(const unexpected<Err2>& unex) {
811 return !has_value() && error() == unex.error();
812 }
813};
814
815
816template <typename T, typename ErrorT>
817class expected<T, ErrorT, enable_if_t<is_void_v<T>>> {
818 static_assert(inner::can_be_unexpected<ErrorT>, "ErrorT must be unexpected");
819
820 template <typename U, typename Err, typename UE = unexpected<ErrorT>>
821 static constexpr bool constructible_from_expected =
822 disjunction_v<is_constructible<UE, expected<U, Err>&>, is_constructible<UE, expected<U, Err>>,
823 is_constructible<UE, const expected<U, Err>&>, is_constructible<UE, const expected<U, Err>>>;
824
825 template <typename U>
826 static constexpr bool same_value = is_same_v<typename U::value_type, T>;
827
828 template <typename U>
829 static constexpr bool same_error = is_same_v<typename U::error_type, ErrorT>;
830
831 template <typename, typename, typename>
832 friend class expected;
833
834public:
835 using value_type = T;
836 using error_type = ErrorT;
837 using unexpected_type = unexpected<ErrorT>;
838
839 template <typename U>
840 using rebind = expected<U, error_type>;
841
842private:
843 union {
844 struct {
845 } void_;
846 ErrorT error_;
847 };
848
849 bool has_value_;
850
851 template <typename U>
852 constexpr void assign_error(U&& err) {
853 if (has_value_) {
854 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE forward<U>(err));
855 has_value_ = false;
856 } else {
857 error_ = _NEFORCE forward<U>(err);
858 }
859 }
860
861 template <typename Func>
862 explicit constexpr expected(inplace_invoke_tag, Func&& func) :
863 void_(),
864 has_value_(true) {
865 _NEFORCE forward<Func>(func)();
866 }
867
868 template <typename Func>
869 explicit constexpr expected(unexpect_invoke_tag, Func&& func) :
870 error_(_NEFORCE forward<Func>(func)()),
871 has_value_(false) {}
872
873public:
874 constexpr expected() noexcept :
875 void_(),
876 has_value_(true) {}
877
878 constexpr expected(const expected& other) noexcept(is_nothrow_copy_constructible_v<ErrorT>) :
879 void_(),
880 has_value_(other.has_value_) {
881 if (!has_value_) {
882 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
883 }
884 }
885
886 constexpr expected(expected&& other) noexcept(is_nothrow_move_constructible_v<ErrorT>) :
887 void_(),
888 has_value_(other.has_value_) {
889 if (!has_value_) {
890 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
891 }
892 }
893
894 template <typename U, typename Gr,
896 (!constructible_from_expected<U, Gr>) && !is_convertible_v<const Gr&, ErrorT>,
897 int> = 0>
898 constexpr explicit expected(const expected<U, Gr>& other) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
899 void_(),
900 has_value_(other.has_value_) {
901 if (!has_value_) {
902 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
903 }
904 }
905
906 template <typename U, typename Gr,
908 (!constructible_from_expected<U, Gr>) && is_convertible_v<const Gr&, ErrorT>,
909 int> = 0>
910 constexpr expected(const expected<U, Gr>& other) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
911 void_(),
912 has_value_(other.has_value_) {
913 if (!has_value_) {
914 _NEFORCE construct(_NEFORCE addressof(error_), other.error_);
915 }
916 }
917
918 template <typename U, typename Gr,
919 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, Gr> && (!constructible_from_expected<U, Gr>) &&
921 int> = 0>
922 constexpr explicit expected(expected<U, Gr>&& other) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
923 void_(),
924 has_value_(other.has_value_) {
925 if (!has_value_) {
926 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
927 }
928 }
929
930 template <typename U, typename Gr,
931 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, Gr> && (!constructible_from_expected<U, Gr>) &&
933 int> = 0>
934 constexpr expected(expected<U, Gr>&& other) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
935 void_(),
936 has_value_(other.has_value_) {
937 if (!has_value_) {
938 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other).error_);
939 }
940 }
941
942 template <typename Gr = ErrorT,
944 constexpr explicit expected(const unexpected<Gr>& unex) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
945 error_(unex.error()),
946 has_value_(false) {}
947
948 template <typename Gr = ErrorT,
950 constexpr expected(const unexpected<Gr>& unex) noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
951 error_(unex.error()),
952 has_value_(false) {}
953
954 template <typename Gr = ErrorT,
956 constexpr explicit expected(unexpected<Gr>&& unex) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
957 error_(_NEFORCE move(unex).error()),
958 has_value_(false) {}
959
960 template <typename Gr = ErrorT,
962 constexpr expected(unexpected<Gr>&& unex) noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
963 error_(_NEFORCE move(unex).error()),
964 has_value_(false) {}
965
966 constexpr explicit expected(inplace_construct_tag) noexcept :
967 expected() {}
968
969 template <typename... Args, enable_if_t<is_constructible_v<ErrorT, Args...>, int> = 0>
970 constexpr explicit expected(unexpect_t, Args&&... args) noexcept(is_nothrow_constructible_v<ErrorT, Args...>) :
971 error_(_NEFORCE forward<Args>(args)...),
972 has_value_(false) {}
973
974 template <typename U, typename... Args,
976 constexpr explicit expected(unexpect_t, std::initializer_list<U> list, Args&&... args) noexcept(
978 error_(list, _NEFORCE forward<Args>(args)...),
979 has_value_(false) {}
980
981 NEFORCE_CONSTEXPR20 ~expected() {
982 if (!has_value_) {
983 _NEFORCE destroy(_NEFORCE addressof(error_));
984 }
985 }
986
987 constexpr expected& operator=(const expected& other) noexcept(
988 conjunction_v<is_nothrow_copy_constructible<ErrorT>, is_nothrow_copy_assignable<ErrorT>>) {
989 if (other.has_value_) {
990 emplace();
991 } else {
992 assign_error(other.error_);
993 }
994 return *this;
995 }
996
997 constexpr expected& operator=(expected&& other) noexcept(
998 conjunction_v<is_nothrow_move_constructible<ErrorT>, is_nothrow_move_assignable<ErrorT>>) {
999 if (other.has_value_) {
1000 emplace();
1001 } else {
1002 assign_error(_NEFORCE move(other.error_));
1003 }
1004 return *this;
1005 }
1006
1007 template <typename Gr,
1009 constexpr expected& operator=(const unexpected<Gr>& unex) {
1010 assign_error(unex.error());
1011 return *this;
1012 }
1013
1014 template <typename Gr, enable_if_t<is_constructible_v<ErrorT, Gr> && is_assignable_v<ErrorT&, Gr>, int> = 0>
1015 constexpr expected& operator=(unexpected<Gr>&& unex) {
1016 assign_error(_NEFORCE move(unex.error()));
1017 return *this;
1018 }
1019
1020 constexpr void emplace() noexcept {
1021 if (!has_value_) {
1022 _NEFORCE destroy(_NEFORCE addressof(error_));
1023 has_value_ = true;
1024 }
1025 }
1026
1027 constexpr void swap(expected& other) noexcept(
1028 conjunction_v<is_nothrow_swappable<ErrorT&>, is_nothrow_move_constructible<ErrorT>>) {
1029 if (has_value_) {
1030 if (!other.has_value_) {
1031 _NEFORCE construct(_NEFORCE addressof(error_), _NEFORCE move(other.error_));
1032 _NEFORCE destroy(_NEFORCE addressof(other.error_));
1033 has_value_ = false;
1034 other.has_value_ = true;
1035 }
1036 } else {
1037 if (other.has_value_) {
1038 _NEFORCE construct(_NEFORCE addressof(other.error_), _NEFORCE move(error_));
1039 _NEFORCE destroy(_NEFORCE addressof(error_));
1040 has_value_ = true;
1041 other.has_value_ = false;
1042 } else {
1043 _NEFORCE swap(error_, other.error_);
1044 }
1045 }
1046 }
1047
1048 NEFORCE_NODISCARD constexpr explicit operator bool() const noexcept { return has_value_; }
1049
1050 NEFORCE_NODISCARD constexpr bool has_value() const noexcept { return has_value_; }
1051
1052 constexpr void operator*() const noexcept { NEFORCE_CONSTEXPR_ASSERT(has_value_); }
1053
1054 constexpr void value() const& {
1055 if (has_value_) {
1056 return;
1057 }
1058 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1059 }
1060
1061 constexpr void value() && {
1062 if (has_value_) {
1063 return;
1064 }
1065 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1066 }
1067
1068 constexpr const ErrorT& error() const& noexcept {
1069 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
1070 return error_;
1071 }
1072
1073 constexpr ErrorT& error() & noexcept {
1074 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
1075 return error_;
1076 }
1077
1078 constexpr const ErrorT&& error() const&& noexcept {
1079 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
1080 return _NEFORCE move(error_);
1081 }
1082
1083 constexpr ErrorT&& error() && noexcept {
1084 NEFORCE_CONSTEXPR_ASSERT(!has_value_);
1085 return _NEFORCE move(error_);
1086 }
1087
1088 template <typename Gr = ErrorT>
1089 constexpr ErrorT error_or(Gr&& alt) const& {
1090 static_assert(is_copy_constructible_v<ErrorT>, "ErrorT must be copy constructible");
1091 static_assert(is_convertible_v<Gr, ErrorT>, "Gr must be convertible to ErrorT");
1092
1093 if (has_value_) {
1094 return _NEFORCE forward<Gr>(alt);
1095 }
1096 return error_;
1097 }
1098
1099 template <typename Gr = ErrorT>
1100 constexpr ErrorT error_or(Gr&& alt) && {
1101 static_assert(is_move_constructible_v<ErrorT>, "ErrorT must be move constructible");
1102 static_assert(is_convertible_v<Gr, ErrorT>, "Gr must be convertible to ErrorT");
1103
1104 if (has_value_) {
1105 return _NEFORCE forward<Gr>(alt);
1106 }
1107 return _NEFORCE move(error_);
1108 }
1109
1110 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT&>, int> = 0>
1111 constexpr auto and_then(Func&& func) & {
1112 using Res = inner::expected_invoke_narg_result<Func>;
1113 static_assert(is_expected<Res>, "Res must be expected");
1114 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1115
1116 if (has_value()) {
1117 return _NEFORCE invoke(_NEFORCE forward<Func>(func));
1118 } else {
1119 return Res(unexpect, error_);
1120 }
1121 }
1122
1123 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT&>, int> = 0>
1124 constexpr auto and_then(Func&& func) const& {
1125 using Res = inner::expected_invoke_narg_result<Func>;
1126 static_assert(is_expected<Res>, "Res must be expected");
1127 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1128
1129 if (has_value()) {
1130 return _NEFORCE invoke(_NEFORCE forward<Func>(func));
1131 } else {
1132 return Res(unexpect, error_);
1133 }
1134 }
1135
1136 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT>, int> = 0>
1137 constexpr auto and_then(Func&& func) && {
1138 using Res = inner::expected_invoke_narg_result<Func>;
1139 static_assert(is_expected<Res>, "Res must be expected");
1140 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1141
1142 if (has_value()) {
1143 return _NEFORCE invoke(_NEFORCE forward<Func>(func));
1144 } else {
1145 return Res(unexpect, _NEFORCE move(error_));
1146 }
1147 }
1148
1149 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT>, int> = 0>
1150 constexpr auto and_then(Func&& func) const&& {
1151 using Res = inner::expected_invoke_narg_result<Func>;
1152 static_assert(is_expected<Res>, "Res must be expected");
1153 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1154
1155 if (has_value()) {
1156 return _NEFORCE invoke(_NEFORCE forward<Func>(func));
1157 } else {
1158 return Res(unexpect, _NEFORCE move(error_));
1159 }
1160 }
1161
1162 template <typename Func>
1163 constexpr auto or_else(Func&& func) & {
1164 using Res = inner::expected_invoke_result<Func, ErrorT&>;
1165 static_assert(is_expected<Res>, "Res must be expected");
1166 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1167
1168 if (has_value()) {
1169 return Res();
1170 } else {
1171 return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_);
1172 }
1173 }
1174
1175 template <typename Func>
1176 constexpr auto or_else(Func&& func) const& {
1177 using Res = inner::expected_invoke_result<Func, const ErrorT&>;
1178 static_assert(is_expected<Res>, "Res must be expected");
1179 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1180
1181 if (has_value()) {
1182 return Res();
1183 } else {
1184 return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_);
1185 }
1186 }
1187
1188 template <typename Func>
1189 constexpr auto or_else(Func&& func) && {
1190 using Res = inner::expected_invoke_result<Func, ErrorT&&>;
1191 static_assert(is_expected<Res>, "Res must be expected");
1192 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1193
1194 if (has_value()) {
1195 return Res();
1196 } else {
1197 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_));
1198 }
1199 }
1200
1201 template <typename Func>
1202 constexpr auto or_else(Func&& func) const&& {
1203 using Res = inner::expected_invoke_result<Func, const ErrorT&&>;
1204 static_assert(is_expected<Res>, "Res must be expected");
1205 static_assert(is_same_v<typename Res::value_type, T>, "Res value_type must be same with T");
1206
1207 if (has_value()) {
1208 return Res();
1209 } else {
1210 return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_));
1211 }
1212 }
1213
1214 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT&>, int> = 0>
1215 constexpr auto transform(Func&& func) & {
1216 using U = inner::expected_transform_narg_result<Func>;
1217 using Res = expected<U, ErrorT>;
1218
1219 if (has_value()) {
1220 return Res(inplace_invoke_tag{}, _NEFORCE forward<Func>(func));
1221 } else {
1222 return Res(unexpect, error_);
1223 }
1224 }
1225
1226 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT&>, int> = 0>
1227 constexpr auto transform(Func&& func) const& {
1228 using U = inner::expected_transform_narg_result<Func>;
1229 using Res = expected<U, ErrorT>;
1230
1231 if (has_value()) {
1232 return Res(inplace_invoke_tag{}, _NEFORCE forward<Func>(func));
1233 } else {
1234 return Res(unexpect, error_);
1235 }
1236 }
1237
1238 template <typename Func, enable_if_t<is_constructible_v<ErrorT, ErrorT>, int> = 0>
1239 constexpr auto transform(Func&& func) && {
1240 using U = inner::expected_transform_narg_result<Func>;
1241 using Res = expected<U, ErrorT>;
1242
1243 if (has_value()) {
1244 return Res(inplace_invoke_tag{}, _NEFORCE forward<Func>(func));
1245 } else {
1246 return Res(unexpect, _NEFORCE move(error_));
1247 }
1248 }
1249
1250 template <typename Func, enable_if_t<is_constructible_v<ErrorT, const ErrorT>, int> = 0>
1251 constexpr auto transform(Func&& func) const&& {
1252 using U = inner::expected_transform_narg_result<Func>;
1253 using Res = expected<U, ErrorT>;
1254
1255 if (has_value()) {
1256 return Res(inplace_invoke_tag{}, _NEFORCE forward<Func>(func));
1257 } else {
1258 return Res(unexpect, _NEFORCE move(error_));
1259 }
1260 }
1261
1262 template <typename Func>
1263 constexpr auto transform_error(Func&& func) & {
1264 using Gr = inner::expected_transform_result<Func, ErrorT&>;
1265 using Res = expected<T, Gr>;
1266
1267 if (has_value()) {
1268 return Res();
1269 } else {
1270 return Res(unexpect_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_); });
1271 }
1272 }
1273
1274 template <typename Func>
1275 constexpr auto transform_error(Func&& func) const& {
1276 using Gr = inner::expected_transform_result<Func, const ErrorT&>;
1277 using Res = expected<T, Gr>;
1278
1279 if (has_value()) {
1280 return Res();
1281 } else {
1282 return Res(unexpect_invoke_tag{}, [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), error_); });
1283 }
1284 }
1285
1286 template <typename Func>
1287 constexpr auto transform_error(Func&& func) && {
1288 using Gr = inner::expected_transform_result<Func, ErrorT&&>;
1289 using Res = expected<T, Gr>;
1290
1291 if (has_value()) {
1292 return Res();
1293 } else {
1294 return Res(unexpect_invoke_tag{},
1295 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_)); });
1296 }
1297 }
1298
1299 template <typename Func>
1300 constexpr auto transform_error(Func&& func) const&& {
1301 using Gr = inner::expected_transform_result<Func, const ErrorT&&>;
1302 using Res = expected<T, Gr>;
1303
1304 if (has_value()) {
1305 return Res();
1306 } else {
1307 return Res(unexpect_invoke_tag{},
1308 [&]() { return _NEFORCE invoke(_NEFORCE forward<Func>(func), _NEFORCE move(error_)); });
1309 }
1310 }
1311
1312 template <typename U, typename Err2, enable_if_t<is_void_v<U>, int> = 0>
1313 constexpr bool operator==(const expected<U, Err2>& rhs) {
1314 if (has_value()) {
1315 return rhs.has_value();
1316 } else {
1317 return !rhs.has_value() && error() == rhs.error();
1318 }
1319 }
1320
1321 template <typename Err2>
1322 constexpr bool operator==(const unexpected<Err2>& unex) {
1323 return !has_value() && error() == unex.error();
1324 }
1325};
1326
1327NEFORCE_END_NAMESPACE__
1328#endif // NEFORCE_CORE_UTILITY_EXPECTED_HPP__
内存构造和销毁函数
异常处理框架
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 constexpr bool is_void_v
is_void的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_reference_v
is_reference的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_const_v
is_const的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_volatile_v
is_volatile的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_array_v
is_array的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_function_v
is_function的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_convertible_v
is_convertible的便捷变量模板
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
constexpr duration< inner::__common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
NEFORCE_CONSTEXPR14 inner::__invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_cv< T >::type remove_cv_t
remove_cv的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_default_constructible_v
is_nothrow_default_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_constructible_v
is_nothrow_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_assignable_v
is_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_constructible_v
is_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_move_constructible_v
is_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool disjunction_v
disjunction的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
NEFORCE_INLINE17 constexpr bool conjunction_v
conjunction的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
异常基类
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数
NEFORCE_NODISCARD int code() const noexcept
获取异常码
NEFORCE_NODISCARD const char * type() const noexcept
获取异常类型