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.") noexcept :
14 explicit expected_exception(
const exception& e) :
17 ~expected_exception()
override =
default;
19 NEFORCE_NODISCARD
const char* type() const noexcept
override {
return "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>
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&&>>;
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> &&
70 !is_volatile_v<ErrorT>;
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>>>
88 constexpr explicit unexpected(Err&& error)
noexcept(is_nothrow_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,
97 typename = enable_if_t<is_constructible_v<ErrorT, std::initializer_list<U>&, Args...>>>
98 constexpr explicit unexpected(
99 inplace_construct_tag , 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)...) {}
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_); }
114 constexpr void swap(unexpected& other)
noexcept(is_nothrow_swappable_v<ErrorT>) {
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>
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");
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 =
150 disjunction_v<negation<is_convertible<U, T>>, negation<is_convertible<Err, ErrorT>>>;
152 template <
typename U>
153 static constexpr bool same_value = is_same_v<typename U::value_type, T>;
155 template <
typename U>
156 static constexpr bool same_error = is_same_v<typename U::error_type, ErrorT>;
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) {
181 value_ = _NEFORCE forward<U>(val);
183 _NEFORCE reinitialize(_NEFORCE
addressof(value_), _NEFORCE
addressof(error_), _NEFORCE forward<U>(val));
188 template <
typename U>
189 constexpr void assign_error(U&& err) {
191 _NEFORCE reinitialize(_NEFORCE
addressof(error_), _NEFORCE
addressof(value_), _NEFORCE forward<U>(err));
194 error_ = _NEFORCE forward<U>(err);
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_);
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)()) {}
228 constexpr expected() noexcept(is_nothrow_default_constructible_v<T>) :
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_) {
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_) {
252 template <
typename U,
typename Gr,
253 enable_if_t<(is_constructible_v<T, const U&>) && (is_constructible_v<ErrorT, const 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(
258 conjunction_v<is_nothrow_constructible<T, const U&>, is_nothrow_constructible<ErrorT, const Gr&>>) :
259 has_value_(other.has_value_) {
267 template <
typename U,
typename Gr,
268 enable_if_t<(is_constructible_v<T, const U&>) && (is_constructible_v<ErrorT, const Gr&>) &&
269 (!constructible_from_expected<U, Gr>::value) &&
270 !explicit_conversion<const U&, const Gr&>,
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_) {
282 template <
typename U,
typename Gr,
283 enable_if_t<is_constructible_v<T, U> && is_constructible_v<ErrorT, Gr> &&
284 (!constructible_from_expected<U, Gr>::value) && explicit_conversion<U, Gr>,
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_) {
296 template <
typename U,
typename Gr,
297 enable_if_t<is_constructible_v<T, U> && is_constructible_v<ErrorT, Gr> &&
298 (!constructible_from_expected<U, Gr>::value) && !explicit_conversion<U, Gr>,
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_) {
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>,
315 constexpr explicit expected(U&& value)
noexcept(is_nothrow_constructible_v<T, U>) :
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>,
324 constexpr expected(U&& value)
noexcept(is_nothrow_constructible_v<T, U>) :
325 value_(_NEFORCE
forward<U>(value)),
328 template <
typename Gr = ErrorT,
329 enable_if_t<is_constructible_v<ErrorT, const Gr&> && !is_convertible_v<const Gr&, ErrorT>,
int> = 0>
330 constexpr explicit expected(
const unexpected<Gr>& unex)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
331 error_(unex.error()) {}
333 template <
typename Gr = ErrorT,
334 enable_if_t<is_constructible_v<ErrorT, const Gr&> && is_convertible_v<const Gr&, ErrorT>,
int> = 0>
335 constexpr expected(
const unexpected<Gr>& unex)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
336 error_(unex.error()) {}
338 template <
typename Gr = ErrorT,
339 enable_if_t<is_constructible_v<ErrorT, Gr> && !is_convertible_v<Gr, ErrorT>,
int> = 0>
340 constexpr explicit expected(unexpected<Gr>&& unex)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
341 error_(_NEFORCE
move(unex).error()) {}
343 template <
typename Gr = ErrorT,
344 enable_if_t<is_constructible_v<ErrorT, Gr> && is_convertible_v<Gr, ErrorT>,
int> = 0>
345 constexpr expected(unexpected<Gr>&& unex)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
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,
355 enable_if_t<is_constructible_v<T, std::initializer_list<U>&, Args...>,
int> = 0>
356 constexpr explicit expected(
357 inplace_construct_tag , 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)...),
363 constexpr explicit expected(unexpect_t ,
365 error_(_NEFORCE
forward<Args>(args)...) {}
367 template <
typename U,
typename... Args,
368 enable_if_t<is_constructible_v<ErrorT, std::initializer_list<U>&, Args...>,
int> = 0>
369 constexpr explicit expected(unexpect_t , std::initializer_list<U> list, Args&&... args)
noexcept(
370 is_nothrow_constructible_v<ErrorT, std::initializer_list<U>&, Args...>) :
371 error_(list, _NEFORCE
forward<Args>(args)...) {}
373 NEFORCE_CONSTEXPR20 ~expected() {
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_);
387 assign_error(other.error_);
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_));
398 assign_error(_NEFORCE
move(other.error_));
403 template <
typename U = T,
404 enable_if_t<(!is_same_v<expected, remove_cvref_t<U>>) && (!is_unexpected<remove_cvref_t<U>>) &&
405 is_constructible_v<T, U> && is_assignable_v<T&, U>,
407 constexpr expected& operator=(U&& value) {
408 assign_value(_NEFORCE forward<U>(value));
412 template <
typename Gr,
413 enable_if_t<is_constructible_v<ErrorT, const Gr&> && is_assignable_v<ErrorT&, const Gr&>,
int> = 0>
414 constexpr expected& operator=(
const unexpected<Gr>& unex) {
415 assign_error(unex.error());
419 template <
typename Gr,
420 enable_if_t<is_constructible_v<ErrorT, const Gr&> && is_assignable_v<ErrorT&, const Gr&>,
int> = 0>
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,
439 enable_if_t<is_nothrow_constructible_v<T, std::initializer_list<U>&, Args...>,
int> = 0>
440 constexpr T& emplace(std::initializer_list<U> list, Args&&... args)
noexcept {
447 _NEFORCE
construct(_NEFORCE
addressof(value_), list, _NEFORCE forward<Args>(args)...);
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&>>) {
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>
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");
560 return static_cast<T
>(_NEFORCE forward<U>(alt));
563 template <
typename U>
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");
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& {
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");
581 return _NEFORCE forward<Gr>(alt);
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");
592 return _NEFORCE forward<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");
601 static_assert(is_same_v<typename Res::error_type, ErrorT>,
"Func must return an expected with same error type");
604 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), value_);
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");
614 static_assert(is_same_v<typename Res::error_type, ErrorT>,
"Func must return an expected with same error type");
617 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), value_);
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");
627 static_assert(is_same_v<typename Res::error_type, ErrorT>,
"Func must return an expected with same error type");
630 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(value_));
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");
640 static_assert(is_same_v<typename Res::error_type, ErrorT>,
"Func must return an expected with same error type");
643 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(value_));
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");
653 static_assert(is_same_v<typename Res::value_type, T>,
"Func must return an expected with same value type");
656 return Res(inplace_construct_tag{}, value_);
658 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), error_);
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");
669 return Res(inplace_construct_tag{}, value_);
671 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), error_);
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");
682 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
684 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_));
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");
695 return Res(inplace_construct_tag{}, _NEFORCE
move(value_));
697 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_));
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{},
732 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(value_)); });
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{},
745 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(value_)); });
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{},
784 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_)); });
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{},
797 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_)); });
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 =
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>>>;
831 template <
typename U>
832 static constexpr bool same_value = is_same_v<typename U::value_type, T>;
834 template <
typename U>
835 static constexpr bool same_error = is_same_v<typename U::error_type, ErrorT>;
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) {
863 error_ = _NEFORCE forward<U>(err);
867 template <
typename Func>
868 explicit constexpr expected(inplace_invoke_tag , Func&& func) :
871 _NEFORCE forward<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 :
884 constexpr expected(
const expected& other)
noexcept(is_nothrow_copy_constructible_v<ErrorT>) :
886 has_value_(other.has_value_) {
892 constexpr expected(expected&& other)
noexcept(is_nothrow_move_constructible_v<ErrorT>) :
894 has_value_(other.has_value_) {
900 template <
typename U,
typename Gr,
901 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, const Gr&> &&
902 (!constructible_from_expected<U, Gr>) && !is_convertible_v<const Gr&, ErrorT>,
904 constexpr explicit expected(
const expected<U, Gr>& other)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
906 has_value_(other.has_value_) {
912 template <
typename U,
typename Gr,
913 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, const Gr&> &&
914 (!constructible_from_expected<U, Gr>) && is_convertible_v<const Gr&, ErrorT>,
916 constexpr expected(
const expected<U, Gr>& other)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
918 has_value_(other.has_value_) {
924 template <
typename U,
typename Gr,
925 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, Gr> && (!constructible_from_expected<U, Gr>) &&
926 !is_convertible_v<Gr, ErrorT>,
928 constexpr explicit expected(expected<U, Gr>&& other)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
930 has_value_(other.has_value_) {
936 template <
typename U,
typename Gr,
937 enable_if_t<is_void_v<U> && is_constructible_v<ErrorT, Gr> && (!constructible_from_expected<U, Gr>) &&
938 is_convertible_v<Gr, ErrorT>,
940 constexpr expected(expected<U, Gr>&& other)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
942 has_value_(other.has_value_) {
948 template <
typename Gr = ErrorT,
949 enable_if_t<is_constructible_v<ErrorT, const Gr&> && !is_convertible_v<const Gr&, ErrorT>,
int> = 0>
950 constexpr explicit expected(
const unexpected<Gr>& unex)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
951 error_(unex.error()),
954 template <
typename Gr = ErrorT,
955 enable_if_t<is_constructible_v<ErrorT, const Gr&> && is_convertible_v<const Gr&, ErrorT>,
int> = 0>
956 constexpr expected(
const unexpected<Gr>& unex)
noexcept(is_nothrow_constructible_v<ErrorT, const Gr&>) :
957 error_(unex.error()),
960 template <
typename Gr = ErrorT,
961 enable_if_t<is_constructible_v<ErrorT, Gr> && !is_convertible_v<Gr, ErrorT>,
int> = 0>
962 constexpr explicit expected(unexpected<Gr>&& unex)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
963 error_(_NEFORCE
move(unex).error()),
966 template <
typename Gr = ErrorT,
967 enable_if_t<is_constructible_v<ErrorT, Gr> && is_convertible_v<Gr, ErrorT>,
int> = 0>
968 constexpr expected(unexpected<Gr>&& unex)
noexcept(is_nothrow_constructible_v<ErrorT, Gr>) :
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,
982 enable_if_t<is_constructible_v<ErrorT, std::initializer_list<U>&, Args...>,
int> = 0>
983 constexpr explicit expected(unexpect_t , std::initializer_list<U> list, Args&&... args)
noexcept(
984 is_nothrow_constructible_v<ErrorT, std::initializer_list<U>&, Args...>) :
985 error_(list, _NEFORCE
forward<Args>(args)...),
988 NEFORCE_CONSTEXPR20 ~expected() {
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_) {
999 assign_error(other.error_);
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_) {
1009 assign_error(_NEFORCE
move(other.error_));
1014 template <
typename Gr,
1015 enable_if_t<is_constructible_v<ErrorT, const Gr&> && is_assignable_v<ErrorT&, const Gr&>,
int> = 0>
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(
1035 conjunction_v<is_nothrow_swappable<ErrorT&>, is_nothrow_move_constructible<ErrorT>>) {
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& {
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");
1101 return _NEFORCE forward<Gr>(alt);
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");
1112 return _NEFORCE forward<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");
1121 static_assert(is_same_v<typename Res::value_type, T>,
"Res value_type must be same with T");
1124 return _NEFORCE
invoke(_NEFORCE forward<Func>(func));
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");
1134 static_assert(is_same_v<typename Res::value_type, T>,
"Res value_type must be same with T");
1137 return _NEFORCE
invoke(_NEFORCE forward<Func>(func));
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");
1147 static_assert(is_same_v<typename Res::value_type, T>,
"Res value_type must be same with T");
1150 return _NEFORCE
invoke(_NEFORCE forward<Func>(func));
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");
1160 static_assert(is_same_v<typename Res::value_type, T>,
"Res value_type must be same with T");
1163 return _NEFORCE
invoke(_NEFORCE forward<Func>(func));
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");
1173 static_assert(is_same_v<typename Res::value_type, T>,
"Res value_type must be same with T");
1178 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), error_);
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");
1191 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), error_);
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");
1204 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_));
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");
1217 return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_));
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{},
1302 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_)); });
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{},
1315 [&]() {
return _NEFORCE
invoke(_NEFORCE forward<Func>(func), _NEFORCE
move(error_)); });
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 * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr bool is_void_v
is_void的便捷变量模板
#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 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr inner::__invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr bool is_constructible_v
is_constructible的便捷变量模板
constexpr bool is_nothrow_constructible_v
is_nothrow_constructible的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
void swap(unique_ptr< T, Deleter > &lhs, unique_ptr< T, Deleter > &rhs) noexcept
交换两个unique_ptr