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