1#ifndef NEFORCE_CORE_UTILITY_EXPECTED_HPP__
2#define NEFORCE_CORE_UTILITY_EXPECTED_HPP__
5NEFORCE_BEGIN_NAMESPACE__
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 :
12 explicit expected_exception(
const exception& e) :
15 ~expected_exception()
override =
default;
16 static constexpr auto static_type =
"expected_exception";
20struct inplace_invoke_tag {
21 constexpr inplace_invoke_tag() noexcept = default;
24struct unexpect_invoke_tag {
25 constexpr unexpect_invoke_tag() noexcept = default;
30 explicit unexpect_t() noexcept = default;
33NEFORCE_INLINE17 constexpr unexpect_t unexpect{};
36template <
typename T,
typename ErrorT,
typename =
void>
39template <
typename ErrorT>
44NEFORCE_INLINE17
constexpr bool is_expected =
false;
45template <
typename T,
typename ErrorT>
46NEFORCE_INLINE17
constexpr bool is_expected<expected<T, ErrorT>> =
true;
49NEFORCE_INLINE17
constexpr bool is_unexpected =
false;
51NEFORCE_INLINE17
constexpr bool is_unexpected<unexpected<T>> =
true;
55template <
typename Func,
typename T>
57template <
typename Func,
typename T>
59template <
typename Func>
61template <
typename Func>
64template <
typename ErrorT>
65NEFORCE_INLINE17
constexpr bool can_be_unexpected =
71template <
typename ErrorT>
73 static_assert(inner::can_be_unexpected<ErrorT>,
"ErrorT should be non-array, unexpected, const or volatile type");
79 constexpr unexpected(
const unexpected&) =
default;
80 constexpr unexpected(unexpected&&) =
default;
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>>>
86 error_(_NEFORCE
forward<Err>(error)) {}
89 constexpr explicit unexpected(inplace_construct_tag,
91 error_(_NEFORCE
forward<Args>(args)...) {}
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)...) {}
99 constexpr unexpected& operator=(
const unexpected&) =
default;
100 constexpr unexpected& operator=(unexpected&&) =
default;
102 NEFORCE_NODISCARD
constexpr const ErrorT& error() const& noexcept {
return error_; }
104 NEFORCE_NODISCARD
constexpr ErrorT& error() &
noexcept {
return error_; }
106 NEFORCE_NODISCARD
constexpr const ErrorT&& error() const&& noexcept {
return _NEFORCE
move(error_); }
108 NEFORCE_NODISCARD
constexpr ErrorT&& error() &&
noexcept {
return _NEFORCE
move(error_); }
111 _NEFORCE
swap(error_, other.error_);
114 template <
typename OtherError>
115 NEFORCE_NODISCARD
friend constexpr bool operator==(
const unexpected& lhs,
const unexpected<OtherError>& rhs) {
116 return lhs.error_ == rhs.error();
120#ifdef NEFORCE_STANDARD_17
121template <
typename ErrorT>
122unexpected(ErrorT) -> unexpected<ErrorT>;
126template <
typename T,
typename ErrorT,
typename Dummy>
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");
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>>>;
144 template <
typename U,
typename Err>
145 static constexpr bool explicit_conversion =
148 template <
typename U>
151 template <
typename U>
155 using value_type = T;
156 using error_type = ErrorT;
157 using unexpected_type = unexpected<ErrorT>;
159 template <
typename U>
160 using rebind = expected<U, error_type>;
168 bool has_value_{
false};
170 template <
typename,
typename,
typename>
171 friend class expected;
174 template <
typename U>
175 constexpr void assign_value(U&& val) {
184 template <
typename U>
185 constexpr void assign_error(U&& err) {
194 constexpr void swap_value_error(expected& other)
noexcept(
197 temporary_guard<ErrorT> guard(other.error_);
199 other.has_value_ =
true;
205 temporary_guard<T> guard(value_);
210 other.has_value_ =
true;
214 template <
typename Func>
215 explicit constexpr expected(inplace_invoke_tag, Func&& func) :
216 value_(_NEFORCE
forward<Func>(func)()),
219 template <
typename Func>
220 explicit constexpr expected(unexpect_invoke_tag, Func&& func) :
221 error_(_NEFORCE
forward<Func>(func)()) {}
228 constexpr expected(
const expected& other)
noexcept(
230 has_value_(other.has_value_) {
238 constexpr expected(expected&& other)
noexcept(
240 has_value_(other.has_value_) {
248 template <
typename U,
typename Gr,
250 (!constructible_from_expected<U, Gr>::value) &&
251 explicit_conversion<const U&, const Gr&>,
253 constexpr explicit expected(
const expected<U, Gr>& other)
noexcept(
255 has_value_(other.has_value_) {
263 template <
typename U,
typename Gr,
265 (!constructible_from_expected<U, Gr>::value) &&
266 !explicit_conversion<const U&, const Gr&>,
268 constexpr expected(
const expected<U, Gr>& other)
noexcept(
270 has_value_(other.has_value_) {
278 template <
typename U,
typename Gr,
280 (!constructible_from_expected<U, Gr>::value) && explicit_conversion<U, Gr>,
282 constexpr explicit expected(expected<U, Gr>&& other)
noexcept(
284 has_value_(other.has_value_) {
292 template <
typename U,
typename Gr,
294 (!constructible_from_expected<U, Gr>::value) && !explicit_conversion<U, Gr>,
296 constexpr expected(expected<U, Gr>&& other)
noexcept(
298 has_value_(other.has_value_) {
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>,
312 value_(_NEFORCE
forward<U>(value)),
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>,
321 value_(_NEFORCE
forward<U>(value)),
324 template <
typename Gr = ErrorT,
327 error_(unex.error()) {}
329 template <
typename Gr = ErrorT,
332 error_(unex.error()) {}
334 template <
typename Gr = ErrorT,
337 error_(_NEFORCE
move(unex).error()) {}
339 template <
typename Gr = ErrorT,
342 error_(_NEFORCE
move(unex).error()) {}
345 constexpr explicit expected(inplace_construct_tag,
347 value_(_NEFORCE
forward<Args>(args)...),
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)...),
359 error_(_NEFORCE
forward<Args>(args)...) {}
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)...) {}
367 NEFORCE_CONSTEXPR20 ~expected() {
375 constexpr expected& operator=(
const expected& other)
noexcept(
377 is_nothrow_copy_assignable<T>, is_nothrow_copy_assignable<ErrorT>>) {
378 if (other.has_value_) {
379 assign_value(other.value_);
381 assign_error(other.error_);
386 constexpr expected& operator=(expected&& other)
noexcept(
388 is_nothrow_move_assignable<T>, is_nothrow_move_assignable<ErrorT>>) {
389 if (other.has_value_) {
390 assign_value(_NEFORCE
move(other.value_));
392 assign_error(_NEFORCE
move(other.error_));
397 template <
typename U = T,
401 constexpr expected& operator=(U&& value) {
406 template <
typename Gr,
408 constexpr expected& operator=(
const unexpected<Gr>& unex) {
409 assign_error(unex.error());
413 template <
typename Gr,
415 constexpr expected& operator=(unexpected<Gr>&& unex) {
416 assign_error(_NEFORCE
move(unex).error());
421 constexpr T& emplace(Args&&... args)
noexcept {
432 template <
typename U,
typename... Args,
434 constexpr T& emplace(std::initializer_list<U> list, Args&&... args)
noexcept {
445 constexpr void swap(expected& other)
noexcept(
447 is_nothrow_swappable<T&>, is_nothrow_swappable<ErrorT&>>) {
449 if (other.has_value_) {
450 _NEFORCE
swap(value_, other.value_);
452 this->swap_value_error(other);
455 if (other.has_value_) {
456 other.swap_value_error(*
this);
458 _NEFORCE
swap(error_, other.error_);
463 NEFORCE_NODISCARD
constexpr const T* operator->() const noexcept {
468 NEFORCE_NODISCARD
constexpr T* operator->() noexcept {
473 NEFORCE_NODISCARD
constexpr const T&
operator*() const& noexcept {
478 NEFORCE_NODISCARD
constexpr T&
operator*() &
noexcept {
483 NEFORCE_NODISCARD
constexpr const T&&
operator*() const&& noexcept {
485 return _NEFORCE
move(value_);
488 NEFORCE_NODISCARD
constexpr T&&
operator*() &&
noexcept {
490 return _NEFORCE
move(value_);
493 NEFORCE_NODISCARD
constexpr explicit operator bool() const noexcept {
return has_value_; }
495 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return has_value_; }
497 constexpr const T& value() const& {
499 NEFORCE_LIKELY {
return value_; }
501 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
504 constexpr T& value() & {
506 NEFORCE_LIKELY {
return value_; }
508 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
511 constexpr const T&& value() const&& {
513 NEFORCE_LIKELY {
return _NEFORCE
move(value_); }
515 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
518 constexpr T&& value() && {
520 NEFORCE_LIKELY {
return _NEFORCE
move(value_); }
522 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
525 constexpr const ErrorT& error() const& noexcept {
530 constexpr ErrorT& error() &
noexcept {
535 constexpr const ErrorT&& error() const&& noexcept {
537 return _NEFORCE
move(error_);
540 constexpr ErrorT&& error() &&
noexcept {
542 return _NEFORCE
move(error_);
545 template <
typename U>
554 return static_cast<T
>(_NEFORCE
forward<U>(alt));
557 template <
typename U>
564 return _NEFORCE
move(value_);
566 return static_cast<T
>(_NEFORCE
forward<U>(alt));
569 template <
typename Gr = ErrorT>
570 constexpr ErrorT error_or(Gr&& alt)
const& {
580 template <
typename Gr = ErrorT>
581 constexpr ErrorT error_or(Gr&& alt) && {
588 return _NEFORCE
move(error_);
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");
600 return Res(unexpect, error_);
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");
613 return Res(unexpect, error_);
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");
626 return Res(unexpect, _NEFORCE
move(error_));
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");
639 return Res(unexpect, _NEFORCE
move(error_));
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");
650 return Res(inplace_construct_tag{}, value_);
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");
663 return Res(inplace_construct_tag{}, value_);
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");
676 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
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");
689 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
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>;
701 return Res(inplace_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), value_); });
703 return Res(unexpect, error_);
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>;
713 return Res(inplace_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), value_); });
715 return Res(unexpect, error_);
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>;
725 return Res(inplace_invoke_tag{},
728 return Res(unexpect, _NEFORCE
move(error_));
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>;
738 return Res(inplace_invoke_tag{},
741 return Res(unexpect, _NEFORCE
move(error_));
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>;
751 return Res(inplace_construct_tag{}, value_);
753 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
763 return Res(inplace_construct_tag{}, value_);
765 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
775 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
777 return Res(unexpect_invoke_tag{},
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>;
788 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
790 return Res(unexpect_invoke_tag{},
795 template <
typename U,
typename Err2, enable_if_t<!is_
void_v<U>,
int> = 0>
796 constexpr bool operator==(
const expected<U, Err2>& rhs) {
798 return rhs.has_value() && value_ == *rhs;
800 return !rhs.has_value() && error() == rhs.error();
804 template <
typename U>
806 return has_value() && value_ == value;
809 template <
typename Err2>
810 constexpr bool operator==(
const unexpected<Err2>& unex) {
811 return !has_value() && error() == unex.error();
816template <
typename T,
typename ErrorT>
818 static_assert(inner::can_be_unexpected<ErrorT>,
"ErrorT must be unexpected");
820 template <
typename U,
typename Err,
typename UE = unexpected<ErrorT>>
821 static constexpr bool constructible_from_expected =
823 is_constructible<UE, const expected<U, Err>&>, is_constructible<UE, const expected<U, Err>>>;
825 template <
typename U>
828 template <
typename U>
831 template <
typename,
typename,
typename>
832 friend class expected;
835 using value_type = T;
836 using error_type = ErrorT;
837 using unexpected_type = unexpected<ErrorT>;
839 template <
typename U>
840 using rebind = expected<U, error_type>;
851 template <
typename U>
852 constexpr void assign_error(U&& err) {
861 template <
typename Func>
862 explicit constexpr expected(inplace_invoke_tag, Func&& func) :
868 template <
typename Func>
869 explicit constexpr expected(unexpect_invoke_tag, Func&& func) :
870 error_(_NEFORCE
forward<Func>(func)()),
874 constexpr expected() noexcept :
880 has_value_(other.has_value_) {
888 has_value_(other.has_value_) {
894 template <
typename U,
typename Gr,
900 has_value_(other.has_value_) {
906 template <
typename U,
typename Gr,
912 has_value_(other.has_value_) {
918 template <
typename U,
typename Gr,
924 has_value_(other.has_value_) {
930 template <
typename U,
typename Gr,
936 has_value_(other.has_value_) {
942 template <
typename Gr = ErrorT,
945 error_(unex.error()),
948 template <
typename Gr = ErrorT,
951 error_(unex.error()),
954 template <
typename Gr = ErrorT,
957 error_(_NEFORCE
move(unex).error()),
960 template <
typename Gr = ErrorT,
963 error_(_NEFORCE
move(unex).error()),
966 constexpr explicit expected(inplace_construct_tag) noexcept :
971 error_(_NEFORCE
forward<Args>(args)...),
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)...),
981 NEFORCE_CONSTEXPR20 ~expected() {
987 constexpr expected& operator=(
const expected& other)
noexcept(
989 if (other.has_value_) {
992 assign_error(other.error_);
997 constexpr expected& operator=(expected&& other)
noexcept(
999 if (other.has_value_) {
1002 assign_error(_NEFORCE
move(other.error_));
1007 template <
typename Gr,
1009 constexpr expected& operator=(
const unexpected<Gr>& unex) {
1010 assign_error(unex.error());
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()));
1020 constexpr void emplace() noexcept {
1027 constexpr void swap(expected& other)
noexcept(
1030 if (!other.has_value_) {
1034 other.has_value_ =
true;
1037 if (other.has_value_) {
1041 other.has_value_ =
false;
1043 _NEFORCE
swap(error_, other.error_);
1048 NEFORCE_NODISCARD
constexpr explicit operator bool() const noexcept {
return has_value_; }
1050 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return has_value_; }
1054 constexpr void value() const& {
1058 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1061 constexpr void value() && {
1065 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1068 constexpr const ErrorT& error() const& noexcept {
1073 constexpr ErrorT& error() &
noexcept {
1078 constexpr const ErrorT&& error() const&& noexcept {
1080 return _NEFORCE
move(error_);
1083 constexpr ErrorT&& error() &&
noexcept {
1085 return _NEFORCE
move(error_);
1088 template <
typename Gr = ErrorT>
1089 constexpr ErrorT error_or(Gr&& alt)
const& {
1099 template <
typename Gr = ErrorT>
1100 constexpr ErrorT error_or(Gr&& alt) && {
1107 return _NEFORCE
move(error_);
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");
1119 return Res(unexpect, error_);
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");
1132 return Res(unexpect, error_);
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");
1145 return Res(unexpect, _NEFORCE
move(error_));
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");
1158 return Res(unexpect, _NEFORCE
move(error_));
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");
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");
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");
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");
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>;
1220 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1222 return Res(unexpect, error_);
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>;
1232 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1234 return Res(unexpect, error_);
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>;
1244 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1246 return Res(unexpect, _NEFORCE
move(error_));
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>;
1256 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1258 return Res(unexpect, _NEFORCE
move(error_));
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>;
1270 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
1282 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
1294 return Res(unexpect_invoke_tag{},
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>;
1307 return Res(unexpect_invoke_tag{},
1312 template <
typename U,
typename Err2, enable_if_t<is_
void_v<U>,
int> = 0>
1313 constexpr bool operator==(
const expected<U, Err2>& rhs) {
1315 return rhs.has_value();
1317 return !rhs.has_value() && error() == rhs.error();
1321 template <
typename Err2>
1322 constexpr bool operator==(
const unexpected<Err2>& unex) {
1323 return !has_value() && error() == unex.error();
1327NEFORCE_END_NAMESPACE__
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
获取异常类型