1#ifndef NEFORCE_CORE_UTILITY_EXPECTED_HPP__
2#define NEFORCE_CORE_UTILITY_EXPECTED_HPP__
7#include <initializer_list>
8NEFORCE_BEGIN_NAMESPACE__
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 :
15 explicit expected_exception(
const exception& e) :
18 ~expected_exception()
override =
default;
19 static constexpr auto static_type =
"expected_exception";
23struct inplace_invoke_tag {
24 constexpr inplace_invoke_tag() noexcept = default;
27struct unexpect_invoke_tag {
28 constexpr unexpect_invoke_tag() noexcept = default;
33 explicit unexpect_t() noexcept = default;
36NEFORCE_INLINE17 constexpr unexpect_t unexpect{};
39template <
typename T,
typename ErrorT,
typename =
void>
42template <
typename ErrorT>
47NEFORCE_INLINE17
constexpr bool is_expected =
false;
48template <
typename T,
typename ErrorT>
49NEFORCE_INLINE17
constexpr bool is_expected<expected<T, ErrorT>> =
true;
52NEFORCE_INLINE17
constexpr bool is_unexpected =
false;
54NEFORCE_INLINE17
constexpr bool is_unexpected<unexpected<T>> =
true;
58template <
typename Func,
typename T>
60template <
typename Func,
typename T>
62template <
typename Func>
64template <
typename Func>
67template <
typename ErrorT>
68NEFORCE_INLINE17
constexpr bool can_be_unexpected =
74template <
typename ErrorT>
76 static_assert(inner::can_be_unexpected<ErrorT>,
"ErrorT should be non-array, unexpected, const or volatile type");
82 constexpr unexpected(
const unexpected&) =
default;
83 constexpr unexpected(unexpected&&) =
default;
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>>>
89 error_(_NEFORCE
forward<Err>(error)) {}
92 constexpr explicit unexpected(inplace_construct_tag ,
94 error_(_NEFORCE
forward<Args>(args)...) {}
96 template <
typename U,
typename... Args,
98 constexpr explicit unexpected(
99 inplace_construct_tag , std::initializer_list<U> list,
101 error_(list, _NEFORCE
forward<Args>(args)...) {}
103 constexpr unexpected& operator=(
const unexpected&) =
default;
104 constexpr unexpected& operator=(unexpected&&) =
default;
106 NEFORCE_NODISCARD
constexpr const ErrorT& error() const& noexcept {
return error_; }
108 NEFORCE_NODISCARD
constexpr ErrorT& error() &
noexcept {
return error_; }
110 NEFORCE_NODISCARD
constexpr const ErrorT&& error() const&& noexcept {
return _NEFORCE
move(error_); }
112 NEFORCE_NODISCARD
constexpr ErrorT&& error() &&
noexcept {
return _NEFORCE
move(error_); }
115 _NEFORCE
swap(error_, other.error_);
118 template <
typename OtherError>
119 NEFORCE_NODISCARD
friend constexpr bool operator==(
const unexpected& lhs,
const unexpected<OtherError>& rhs) {
120 return lhs.error_ == rhs.error();
124#ifdef NEFORCE_STANDARD_17
125template <
typename ErrorT>
126unexpected(ErrorT) -> unexpected<ErrorT>;
130template <
typename T,
typename ErrorT,
typename Dummy>
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");
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>>>;
148 template <
typename U,
typename Err>
149 static constexpr bool explicit_conversion =
152 template <
typename U>
155 template <
typename U>
159 using value_type = T;
160 using error_type = ErrorT;
161 using unexpected_type = unexpected<ErrorT>;
163 template <
typename U>
164 using rebind = expected<U, error_type>;
172 bool has_value_{
false};
174 template <
typename,
typename,
typename>
175 friend class expected;
178 template <
typename U>
179 constexpr void assign_value(U&& val) {
188 template <
typename U>
189 constexpr void assign_error(U&& err) {
198 constexpr void swap_value_error(expected& other)
noexcept(
201 temporary_guard<ErrorT> guard(other.error_);
203 other.has_value_ =
true;
209 temporary_guard<T> guard(value_);
214 other.has_value_ =
true;
218 template <
typename Func>
219 explicit constexpr expected(inplace_invoke_tag , Func&& func) :
220 value_(_NEFORCE
forward<Func>(func)()),
223 template <
typename Func>
224 explicit constexpr expected(unexpect_invoke_tag , Func&& func) :
225 error_(_NEFORCE
forward<Func>(func)()) {}
232 constexpr expected(
const expected& other)
noexcept(
234 has_value_(other.has_value_) {
242 constexpr expected(expected&& other)
noexcept(
244 has_value_(other.has_value_) {
252 template <
typename U,
typename Gr,
254 (!constructible_from_expected<U, Gr>::value) &&
255 explicit_conversion<const U&, const Gr&>,
257 constexpr explicit expected(
const expected<U, Gr>& other)
noexcept(
259 has_value_(other.has_value_) {
267 template <
typename U,
typename Gr,
269 (!constructible_from_expected<U, Gr>::value) &&
270 !explicit_conversion<const U&, const Gr&>,
272 constexpr expected(
const expected<U, Gr>& other)
noexcept(
274 has_value_(other.has_value_) {
282 template <
typename U,
typename Gr,
284 (!constructible_from_expected<U, Gr>::value) && explicit_conversion<U, Gr>,
286 constexpr explicit expected(expected<U, Gr>&& other)
noexcept(
288 has_value_(other.has_value_) {
296 template <
typename U,
typename Gr,
298 (!constructible_from_expected<U, Gr>::value) && !explicit_conversion<U, Gr>,
300 constexpr expected(expected<U, Gr>&& other)
noexcept(
302 has_value_(other.has_value_) {
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>,
316 value_(_NEFORCE
forward<U>(value)),
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>,
325 value_(_NEFORCE
forward<U>(value)),
328 template <
typename Gr = ErrorT,
331 error_(unex.error()) {}
333 template <
typename Gr = ErrorT,
336 error_(unex.error()) {}
338 template <
typename Gr = ErrorT,
341 error_(_NEFORCE
move(unex).error()) {}
343 template <
typename Gr = ErrorT,
346 error_(_NEFORCE
move(unex).error()) {}
349 constexpr explicit expected(inplace_construct_tag ,
351 value_(_NEFORCE
forward<Args>(args)...),
354 template <
typename U,
typename... Args,
356 constexpr explicit expected(
357 inplace_construct_tag , std::initializer_list<U> list,
359 value_(list, _NEFORCE
forward<Args>(args)...),
363 constexpr explicit expected(unexpect_t ,
365 error_(_NEFORCE
forward<Args>(args)...) {}
367 template <
typename U,
typename... Args,
369 constexpr explicit expected(unexpect_t , std::initializer_list<U> list, Args&&... args)
noexcept(
371 error_(list, _NEFORCE
forward<Args>(args)...) {}
373 NEFORCE_CONSTEXPR20 ~expected() {
381 constexpr expected& operator=(
const expected& other)
noexcept(
383 is_nothrow_copy_assignable<T>, is_nothrow_copy_assignable<ErrorT>>) {
384 if (other.has_value_) {
385 assign_value(other.value_);
387 assign_error(other.error_);
392 constexpr expected& operator=(expected&& other)
noexcept(
394 is_nothrow_move_assignable<T>, is_nothrow_move_assignable<ErrorT>>) {
395 if (other.has_value_) {
396 assign_value(_NEFORCE
move(other.value_));
398 assign_error(_NEFORCE
move(other.error_));
403 template <
typename U = T,
407 constexpr expected& operator=(U&& value) {
412 template <
typename Gr,
414 constexpr expected& operator=(
const unexpected<Gr>& unex) {
415 assign_error(unex.error());
419 template <
typename Gr,
421 constexpr expected& operator=(unexpected<Gr>&& unex) {
422 assign_error(_NEFORCE
move(unex).error());
427 constexpr T& emplace(Args&&... args)
noexcept {
438 template <
typename U,
typename... Args,
440 constexpr T& emplace(std::initializer_list<U> list, Args&&... args)
noexcept {
451 constexpr void swap(expected& other)
noexcept(
453 is_nothrow_swappable<T&>, is_nothrow_swappable<ErrorT&>>) {
455 if (other.has_value_) {
456 _NEFORCE
swap(value_, other.value_);
458 this->swap_value_error(other);
461 if (other.has_value_) {
462 other.swap_value_error(*
this);
464 _NEFORCE
swap(error_, other.error_);
469 NEFORCE_NODISCARD
constexpr const T* operator->() const noexcept {
474 NEFORCE_NODISCARD
constexpr T* operator->() noexcept {
479 NEFORCE_NODISCARD
constexpr const T&
operator*() const& noexcept {
484 NEFORCE_NODISCARD
constexpr T&
operator*() &
noexcept {
489 NEFORCE_NODISCARD
constexpr const T&&
operator*() const&& noexcept {
491 return _NEFORCE
move(value_);
494 NEFORCE_NODISCARD
constexpr T&&
operator*() &&
noexcept {
496 return _NEFORCE
move(value_);
499 NEFORCE_NODISCARD
constexpr explicit operator bool() const noexcept {
return has_value_; }
501 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return has_value_; }
503 constexpr const T& value() const& {
505 NEFORCE_LIKELY {
return value_; }
507 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
510 constexpr T& value() & {
512 NEFORCE_LIKELY {
return value_; }
514 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
517 constexpr const T&& value() const&& {
519 NEFORCE_LIKELY {
return _NEFORCE
move(value_); }
521 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
524 constexpr T&& value() && {
526 NEFORCE_LIKELY {
return _NEFORCE
move(value_); }
528 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
531 constexpr const ErrorT& error() const& noexcept {
536 constexpr ErrorT& error() &
noexcept {
541 constexpr const ErrorT&& error() const&& noexcept {
543 return _NEFORCE
move(error_);
546 constexpr ErrorT&& error() &&
noexcept {
548 return _NEFORCE
move(error_);
551 template <
typename U>
560 return static_cast<T
>(_NEFORCE
forward<U>(alt));
563 template <
typename U>
570 return _NEFORCE
move(value_);
572 return static_cast<T
>(_NEFORCE
forward<U>(alt));
575 template <
typename Gr = ErrorT>
576 constexpr ErrorT error_or(Gr&& alt)
const& {
586 template <
typename Gr = ErrorT>
587 constexpr ErrorT error_or(Gr&& alt) && {
594 return _NEFORCE
move(error_);
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");
606 return Res(unexpect, error_);
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");
619 return Res(unexpect, error_);
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");
632 return Res(unexpect, _NEFORCE
move(error_));
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");
645 return Res(unexpect, _NEFORCE
move(error_));
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");
656 return Res(inplace_construct_tag{}, value_);
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");
669 return Res(inplace_construct_tag{}, value_);
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");
682 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
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");
695 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
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>;
707 return Res(inplace_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), value_); });
709 return Res(unexpect, error_);
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>;
719 return Res(inplace_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), value_); });
721 return Res(unexpect, error_);
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>;
731 return Res(inplace_invoke_tag{},
734 return Res(unexpect, _NEFORCE
move(error_));
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>;
744 return Res(inplace_invoke_tag{},
747 return Res(unexpect, _NEFORCE
move(error_));
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>;
757 return Res(inplace_construct_tag{}, value_);
759 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
769 return Res(inplace_construct_tag{}, value_);
771 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
781 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
783 return Res(unexpect_invoke_tag{},
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>;
794 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
796 return Res(unexpect_invoke_tag{},
801 template <
typename U,
typename Err2, enable_if_t<!is_
void_v<U>,
int> = 0>
802 constexpr bool operator==(
const expected<U, Err2>& rhs) {
804 return rhs.has_value() && value_ == *rhs;
806 return !rhs.has_value() && error() == rhs.error();
810 template <
typename U>
812 return has_value() && value_ == value;
815 template <
typename Err2>
816 constexpr bool operator==(
const unexpected<Err2>& unex) {
817 return !has_value() && error() == unex.error();
822template <
typename T,
typename ErrorT>
824 static_assert(inner::can_be_unexpected<ErrorT>,
"ErrorT must be unexpected");
826 template <
typename U,
typename Err,
typename UE = unexpected<ErrorT>>
827 static constexpr bool constructible_from_expected =
829 is_constructible<UE, const expected<U, Err>&>, is_constructible<UE, const expected<U, Err>>>;
831 template <
typename U>
834 template <
typename U>
837 template <
typename,
typename,
typename>
838 friend class expected;
841 using value_type = T;
842 using error_type = ErrorT;
843 using unexpected_type = unexpected<ErrorT>;
845 template <
typename U>
846 using rebind = expected<U, error_type>;
857 template <
typename U>
858 constexpr void assign_error(U&& err) {
867 template <
typename Func>
868 explicit constexpr expected(inplace_invoke_tag , Func&& func) :
874 template <
typename Func>
875 explicit constexpr expected(unexpect_invoke_tag , Func&& func) :
876 error_(_NEFORCE
forward<Func>(func)()),
880 constexpr expected() noexcept :
886 has_value_(other.has_value_) {
894 has_value_(other.has_value_) {
900 template <
typename U,
typename Gr,
906 has_value_(other.has_value_) {
912 template <
typename U,
typename Gr,
918 has_value_(other.has_value_) {
924 template <
typename U,
typename Gr,
930 has_value_(other.has_value_) {
936 template <
typename U,
typename Gr,
942 has_value_(other.has_value_) {
948 template <
typename Gr = ErrorT,
951 error_(unex.error()),
954 template <
typename Gr = ErrorT,
957 error_(unex.error()),
960 template <
typename Gr = ErrorT,
963 error_(_NEFORCE
move(unex).error()),
966 template <
typename Gr = ErrorT,
969 error_(_NEFORCE
move(unex).error()),
972 constexpr explicit expected(inplace_construct_tag ) noexcept :
976 constexpr explicit expected(unexpect_t ,
978 error_(_NEFORCE
forward<Args>(args)...),
981 template <
typename U,
typename... Args,
983 constexpr explicit expected(unexpect_t , std::initializer_list<U> list, Args&&... args)
noexcept(
985 error_(list, _NEFORCE
forward<Args>(args)...),
988 NEFORCE_CONSTEXPR20 ~expected() {
994 constexpr expected& operator=(
const expected& other)
noexcept(
996 if (other.has_value_) {
999 assign_error(other.error_);
1004 constexpr expected& operator=(expected&& other)
noexcept(
1006 if (other.has_value_) {
1009 assign_error(_NEFORCE
move(other.error_));
1014 template <
typename Gr,
1016 constexpr expected& operator=(
const unexpected<Gr>& unex) {
1017 assign_error(unex.error());
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()));
1027 constexpr void emplace() noexcept {
1034 constexpr void swap(expected& other)
noexcept(
1037 if (!other.has_value_) {
1041 other.has_value_ =
true;
1044 if (other.has_value_) {
1048 other.has_value_ =
false;
1050 _NEFORCE
swap(error_, other.error_);
1055 NEFORCE_NODISCARD
constexpr explicit operator bool() const noexcept {
return has_value_; }
1057 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return has_value_; }
1061 constexpr void value() const& {
1065 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1068 constexpr void value() && {
1072 NEFORCE_THROW_EXCEPTION(expected_exception(error_));
1075 constexpr const ErrorT& error() const& noexcept {
1080 constexpr ErrorT& error() &
noexcept {
1085 constexpr const ErrorT&& error() const&& noexcept {
1087 return _NEFORCE
move(error_);
1090 constexpr ErrorT&& error() &&
noexcept {
1092 return _NEFORCE
move(error_);
1095 template <
typename Gr = ErrorT>
1096 constexpr ErrorT error_or(Gr&& alt)
const& {
1106 template <
typename Gr = ErrorT>
1107 constexpr ErrorT error_or(Gr&& alt) && {
1114 return _NEFORCE
move(error_);
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");
1126 return Res(unexpect, error_);
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");
1139 return Res(unexpect, error_);
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");
1152 return Res(unexpect, _NEFORCE
move(error_));
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");
1165 return Res(unexpect, _NEFORCE
move(error_));
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");
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");
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");
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");
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>;
1227 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1229 return Res(unexpect, error_);
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>;
1239 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1241 return Res(unexpect, error_);
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>;
1251 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1253 return Res(unexpect, _NEFORCE
move(error_));
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>;
1263 return Res(inplace_invoke_tag{}, _NEFORCE
forward<Func>(func));
1265 return Res(unexpect, _NEFORCE
move(error_));
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>;
1277 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
1289 return Res(unexpect_invoke_tag{}, [&]() {
return _NEFORCE
invoke(_NEFORCE
forward<Func>(func), error_); });
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>;
1301 return Res(unexpect_invoke_tag{},
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>;
1314 return Res(unexpect_invoke_tag{},
1319 template <
typename U,
typename Err2, enable_if_t<is_
void_v<U>,
int> = 0>
1320 constexpr bool operator==(
const expected<U, Err2>& rhs) {
1322 return rhs.has_value();
1324 return !rhs.has_value() && error() == rhs.error();
1328 template <
typename Err2>
1329 constexpr bool operator==(
const unexpected<Err2>& unex) {
1330 return !has_value() && error() == unex.error();
1334NEFORCE_END_NAMESPACE__
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
获取异常码