11#include <initializer_list>
19#define likely(x) __builtin_expect(static_cast<long int>((x)), 1)
20#define unlikely(x) __builtin_expect(reinterpret_cast<long int>((x)), 0)
23#define _DEXPECTED_THROW_OR_ABORT(_EXC) (throw(_EXC))
25#define _DEXPECTED_THROW_OR_ABORT(_EXC) (std::abort())
28template <
typename T,
typename E>
35using _bool_constant = std::integral_constant<bool, v>;
40enum class emplace_tag { USE_EMPLACE };
45enum class dunexpected_tag { DUNEXPECTED };
47template <
typename Type>
50 using type =
typename std::remove_cv<typename std::remove_reference<Type>::type>::type;
68 const char *what()
const noexcept override {
return "bad access to DExpected without value"; }
76 : m_error(std::move(_e))
80 E &error() &
noexcept {
return m_error; }
81 const E &error()
const &
noexcept {
return m_error; }
83 E error() &&
noexcept {
return std::move(m_error); }
84 const E error()
const &&
noexcept {
return std::move(m_error); }
90template <
typename Type,
typename... Args>
91auto construct_at(Type *p, Args &&...args)
noexcept(
noexcept(::new((
void *)0) Type(std::declval<Args>()...)))
92 ->
decltype(::new((
void *)0) Type(std::declval<Args>()...))
94 return ::new ((
void *)p) Type(std::forward<Args>(args)...);
97namespace __dexpected {
98template <
typename ObjType>
99void destroy_at_obj(ObjType *p)
104template <
typename ArrType>
105void destroy_at_arr(ArrType *p)
107 for (
auto &elem : *p)
108 destroy_at_obj(std::addressof(elem));
112template <typename Type, typename std::enable_if<std::is_array<Type>::value,
bool>::type =
true>
113void destroy_at(Type *p)
115 __dexpected::destroy_at_arr(p);
118template <typename Type, typename std::enable_if<!std::is_array<Type>::value,
bool>::type =
true>
119void destroy_at(Type *p)
121 __dexpected::destroy_at_obj(p);
124namespace __dexpected {
128 static_assert(std::is_nothrow_move_constructible<T>::value,
"type T must bu nothrow_move_constructible");
129 explicit Guard(T &_x)
130 : m_guarded(std::addressof(_x))
131 , m_tmp(std::move(_x))
133 destroy_at(m_guarded);
138 if (unlikely(m_guarded)) {
139 construct_at(m_guarded, std::move(m_tmp));
145 T &&release()
noexcept {
return std::move(m_tmp); }
153namespace __dexpected {
160template <
typename T,
typename E>
176constexpr bool _can_be_dunexpected()
178 return std::is_object<E>::value and !std::is_array<E>::value and !
_is_dunexpected<E>() and !std::is_const<E>::value and
179 !std::is_volatile<E>::value;
182template <typename Tp,
185 typename std::enable_if<std::is_nothrow_constructible<Tp, Vp>::value and std::is_nothrow_move_constructible<Tp>::value,
187void reinit(Tp *_newVal, Up *_oldVal, Vp &&_arg) noexcept(std::is_nothrow_constructible<Tp, Vp>::value)
190 construct_at(_newVal, std::forward<Vp>(_arg));
193template <
typename Tp,
196 typename std::enable_if<std::is_nothrow_constructible<Tp, Vp>::value and !std::is_nothrow_move_constructible<Tp>::value,
198void reinit(Tp *_newVal, Up *_oldVal, Vp &&_arg)
noexcept(std::is_nothrow_constructible<Tp, Vp>::value)
201 construct_at(_newVal, std::forward<Vp>(_arg));
204template <
typename Tp,
207 typename std::enable_if<!std::is_nothrow_constructible<Tp, Vp>::value and std::is_nothrow_move_constructible<Tp>::value,
209void reinit(Tp *_newVal, Up *_oldVal, Vp &&_arg)
noexcept(std::is_nothrow_constructible<Tp, Vp>::value)
211 Tp _tmp(std::forward<Vp>(_arg));
213 construct_at(_newVal, std::move(_tmp));
220 typename std::enable_if<!std::is_nothrow_constructible<Tp, Vp>::value and !std::is_nothrow_move_constructible<Tp>::value,
222void reinit(Tp *_newVal, Up *_oldVal, Vp &&_arg)
noexcept(std::is_nothrow_constructible<Tp, Vp>::value)
224 __dexpected::Guard<Up> _guard(*_oldVal);
225 construct_at(_newVal, std::forward<Vp>(_arg));
237template <
typename E = DError>
240 static_assert(__dexpected::_can_be_dunexpected<E>(),
"can't be dunexpected");
258 template <
typename Er = E,
259 typename std::enable_if<!std::is_same<typename remove_cvref<Er>::type,
DUnexpected>::value and
260 !std::is_same<typename remove_cvref<Er>::type, emplace_tag>::value and
261 std::is_constructible<E, Er>::value,
263 constexpr explicit DUnexpected(Er &&_e)
noexcept(std::is_nothrow_constructible<E, Er>::value)
264 : m_error(std::forward<Er>(_e))
276 template <
typename... Args>
277 constexpr explicit DUnexpected(emplace_tag, Args &&...args)
noexcept(std::is_nothrow_constructible<E, Args...>::value)
278 : m_error(std::forward<Args>(args)...)
280 static_assert(std::is_constructible<E, Args...>::value,
"can't construct E from args.");
293 template <
typename U,
typename... Args>
294 constexpr explicit DUnexpected(emplace_tag, std::initializer_list<U> _li, Args &&...args)
noexcept(
295 std::is_nothrow_constructible<E, std::initializer_list<U> &, Args...>::value)
296 : m_error(_li, std::forward<Args>(args)...)
314 constexpr const E &
error() const &noexcept {
return m_error; }
320 E &
error() &
noexcept {
return m_error; }
327 constexpr const E &&
error() const &&noexcept {
return std::move(m_error); }
334 E &&
error() &&
noexcept {
return std::move(m_error); }
343 swap(m_error, _other.m_error);
352 template <
typename Er>
355 return _x.m_error == _y.
error();
373template <
typename T,
typename E = DError>
376 template <
typename,
typename>
378 static_assert(!std::is_reference<T>::value,
"type T can't be reference type");
379 static_assert(!std::is_function<T>::value,
"type T can't be function type");
380 static_assert(!std::is_same<typename std::remove_cv<T>::type, dunexpected_tag>::value,
"type T can't be dunexpected_tag");
381 static_assert(!std::is_same<typename std::remove_cv<T>::type, emplace_tag>::value,
"type T can't be emplace_tag");
383 static_assert(__dexpected::_can_be_dunexpected<E>(),
"type E can't be dunexpected");
385 template <
typename U,
typename G,
typename Unex = DUnexpected<E>>
386 static constexpr bool __cons_from_DExpected()
388 return std::is_constructible<T, DExpected<U, G> &>::value or std::is_constructible<T, DExpected<U, G>>::value or
389 std::is_constructible<T, const DExpected<U, G>>::value or
390 std::is_constructible<T, const DExpected<U, G> &>::value or std::is_convertible<DExpected<U, G> &, T>::value or
391 std::is_convertible<DExpected<U, G>, T>::value or std::is_convertible<const DExpected<U, G> &, T>::value or
392 std::is_convertible<const DExpected<U, G>, T>::value or std::is_constructible<Unex, DExpected<U, G> &>::value or
393 std::is_constructible<Unex, DExpected<U, G>>::value or
394 std::is_constructible<Unex, const DExpected<U, G> &>::value or
395 std::is_constructible<Unex, const DExpected<U, G>>::value;
398 template <
typename U,
typename G>
399 static constexpr bool __explicit_conv()
401 return !std::is_convertible<U, T>::value or !std::is_convertible<G, E>::value;
404 static constexpr bool des_value()
406 return !std::is_trivially_destructible<T>::value or !std::is_trivially_destructible<E>::value;
409 template <
typename V>
410 void assign_val(V &&_v)
413 m_value = std::forward<V>(_v);
415 __dexpected::reinit(std::addressof(m_value), std::addressof(m_error), std::forward<V>(_v));
420 template <
typename V>
421 void assign_err(V &&_v)
424 __dexpected::reinit(std::addressof(m_error), std::addressof(m_value), std::forward<V>(_v));
427 m_error = std::forward<V>(_v);
431 template <typename Ep = E, typename std::enable_if<std::is_nothrow_move_constructible<Ep>::value,
bool>::type =
true>
432 void swap_val_err(
DExpected &_other)
noexcept(
433 std::is_nothrow_move_constructible<Ep>::value and std::is_nothrow_move_constructible<T>::value)
436 construct_at(std::addressof(_other.m_value), std::move(m_value));
437 _other.m_has_value =
true;
438 destroy_at(std::addressof(m_value));
439 construct_at(std::addressof(m_error), _guard.release());
443 template <typename Ep = E, typename std::enable_if<!std::is_nothrow_move_constructible<Ep>::value,
bool>::type =
true>
444 void swap_val_err(
DExpected &_other)
noexcept(
445 std::is_nothrow_move_constructible<Ep>::value and std::is_nothrow_move_constructible<T>::value)
448 construct_at(std::addressof(m_error), std::move(_other.m_error));
450 destroy_at(std::addressof(_other.m_error));
451 construct_at(std::addressof(_other.m_value), _guard.release());
452 _other.m_has_value =
true;
456 using value_type = T;
457 using error_type = E;
459 template <
typename U>
465 template <typename std::enable_if<std::is_default_constructible<T>::value,
bool>::type =
true>
466 constexpr DExpected() noexcept(std::is_nothrow_default_constructible<T>::value)
476 typename std::enable_if<std::is_copy_constructible<T>::value and std::is_copy_constructible<E>::value,
bool>::type =
true>
478 std::is_nothrow_copy_constructible<T>::value and std::is_nothrow_copy_constructible<E>::value)
479 : m_has_value(_x.m_has_value)
482 construct_at(std::addressof(m_value), _x.m_value);
484 construct_at(std::addressof(m_error), _x.m_error);
491 typename std::enable_if<std::is_move_constructible<T>::value and std::is_move_constructible<E>::value,
bool>::type =
true>
493 std::is_nothrow_move_constructible<T>::value and std::is_nothrow_move_constructible<E>::value)
494 : m_has_value(_x.m_has_value)
497 construct_at(std::addressof(m_value), std::move(_x).m_value);
499 construct_at(std::addressof(m_error), std::move(_x).m_error);
511 typename std::enable_if<std::is_constructible<T, const U &>::value and std::is_constructible<E, const G &>::value and
512 !__cons_from_DExpected<U, G>() and !__explicit_conv<const U &, const G &>(),
515 std::is_nothrow_constructible<T, const U &>::value and std::is_nothrow_constructible<E, const G &>::value)
516 : m_has_value(_x.m_has_value)
519 construct_at(std::addressof(m_value), _x.m_value);
521 construct_at(std::addressof(m_error), _x.m_error);
534 typename std::enable_if<std::is_constructible<T, const U &>::value and std::is_constructible<E, const G &>::value and
535 !__cons_from_DExpected<U, G>() and __explicit_conv<const U &, const G &>(),
538 std::is_nothrow_constructible<T, const U &>::value and std::is_nothrow_constructible<E, const G &>::value)
539 : m_has_value(_x.m_has_value)
542 construct_at(std::addressof(m_value), _x.m_value);
544 construct_at(std::addressof(m_error), _x.m_error);
554 template <
typename U,
556 typename std::enable_if<std::is_constructible<T, U>::value and std::is_constructible<E, G>::value and
557 !__cons_from_DExpected<U, G>() and !__explicit_conv<U, G>(),
560 std::is_nothrow_constructible<T, U>::value and std::is_nothrow_constructible<E, G>::value)
561 : m_has_value(_x.m_has_value)
564 construct_at(std::addressof(m_value), std::move(_x).m_value);
566 construct_at(std::addressof(m_error), std::move(_x).m_error);
576 template <
typename U,
578 typename std::enable_if<std::is_constructible<T, U>::value and std::is_constructible<E, G>::value and
579 !__cons_from_DExpected<U, G>() and __explicit_conv<U, G>(),
582 std::is_nothrow_constructible<T, U>::value and std::is_nothrow_constructible<E, G>::value)
583 : m_has_value(_x.m_has_value)
586 construct_at(std::addressof(m_value), std::move(_x).m_value);
588 construct_at(std::addressof(m_error), std::move(_x).m_error);
598 template <
typename U = T,
599 typename std::enable_if<!std::is_same<typename remove_cvref<U>::type,
DExpected>::value and
600 !std::is_same<typename remove_cvref<U>::type, emplace_tag>::value and
602 std::is_constructible<T, U>::value and !std::is_convertible<U, T>::value,
604 constexpr explicit DExpected(U &&_v)
noexcept(std::is_nothrow_constructible<T, U>::value)
606 , m_value(std::forward<U>(_v))
618 template <
typename U = T,
619 typename std::enable_if<!std::is_same<typename remove_cvref<U>::type,
DExpected>::value and
620 !std::is_same<typename remove_cvref<U>::type, emplace_tag>::value and
622 std::is_constructible<T, U>::value and std::is_convertible<U, T>::value,
624 constexpr DExpected(U &&_v)
noexcept(std::is_nothrow_constructible<T, U>::value)
626 , m_value(std::forward<U>(_v))
637 template <
typename G = E,
638 typename std::enable_if<std::is_constructible<E, const G &>::value and !std::is_convertible<const G &, E>::value,
642 , m_error(_u.error())
652 template <
typename G = E,
653 typename std::enable_if<std::is_constructible<E, const G &>::value and std::is_convertible<const G &, E>::value,
657 , m_error(_u.error())
670 typename std::enable_if<std::is_constructible<E, G>::value and !std::is_convertible<G, E>::value,
bool>::type =
true>
673 , m_error(std::move(_u).error())
684 template <
typename G = E,
685 typename std::enable_if<std::is_constructible<E, G>::value and std::is_convertible<G, E>::value,
bool>::type =
true>
688 , m_error(std::move(_u).error())
699 template <
typename... Args>
700 constexpr explicit DExpected(emplace_tag, Args &&...args)
noexcept(std::is_nothrow_constructible<T, Args...>::value)
702 , m_value(std::forward<Args>(args)...)
705 static_assert(std::is_constructible<T, Args...>::value,
"can't construct T from args.");
717 template <
typename U,
typename... Args>
718 constexpr explicit DExpected(emplace_tag, std::initializer_list<U> _li, Args &&...args)
noexcept(
719 std::is_nothrow_constructible<T, std::initializer_list<U> &, Args...>::value)
721 , m_value(_li, std::forward<Args>(args)...)
723 static_assert(std::is_constructible<T, std::initializer_list<U> &, Args...>::value,
"can't construct T from args.");
733 template <
typename... Args>
734 constexpr explicit DExpected(dunexpected_tag, Args &&...args)
noexcept(std::is_nothrow_constructible<E, Args...>::value)
736 , m_error(std::forward<Args>(args)...)
739 static_assert(std::is_constructible<E, Args...>::value,
"can't construct E from args.");
751 template <
typename U,
typename... Args>
752 constexpr explicit DExpected(dunexpected_tag, std::initializer_list<U> _li, Args &&...args)
noexcept(
753 std::is_nothrow_constructible<E, std::initializer_list<U> &, Args...>::value)
755 , m_error(_li, std::forward<Args>(args)...)
757 static_assert(std::is_constructible<E, std::initializer_list<U> &, Args...>::value,
"can't construct E from args.");
767 destroy_at(std::addressof(m_value));
769 destroy_at(std::addressof(m_error));
783 template <typename std::enable_if<std::is_copy_assignable<T>::value and std::is_copy_constructible<T>::value and
784 std::is_copy_assignable<E>::value and std::is_copy_constructible<E>::value and
785 (std::is_nothrow_move_constructible<T>::value or
786 std::is_nothrow_move_constructible<E>::value),
789 std::is_nothrow_copy_constructible<T>::value and std::is_nothrow_copy_constructible<E>::value
790 and std::is_nothrow_copy_assignable<T>::value and std::is_nothrow_copy_assignable<E>::value)
793 this->assign_val(_x.m_value);
795 this->assign_err(_x.m_error);
804 template <typename std::enable_if<std::is_move_assignable<T>::value and std::is_move_constructible<T>::value and
805 std::is_move_assignable<E>::value and std::is_move_constructible<E>::value and
806 (std::is_nothrow_move_constructible<T>::value or
807 std::is_nothrow_move_constructible<E>::value),
810 std::is_nothrow_move_constructible<T>::value and std::is_nothrow_move_constructible<E>::value
811 and std::is_nothrow_move_assignable<T>::value and std::is_nothrow_move_assignable<E>::value)
814 assign_val(std::move(_x.m_value));
816 assign_err(std::move(_x.m_error));
827 typename std::enable_if<!std::is_same<DExpected, typename remove_cvref<U>::type>::value and
829 std::is_constructible<T, U>::value and std::is_assignable<T &, U>::value and
830 (std::is_nothrow_constructible<T, U>::value or std::is_nothrow_move_constructible<T>::value or
831 std::is_nothrow_move_constructible<E>::value),
835 assign_val(std::forward<U>(_v));
844 template <
typename G,
845 typename std::enable_if<std::is_constructible<E, const G &>::value and std::is_assignable<E &, const G &>::value and
846 (std::is_nothrow_constructible<E, const G &>::value or
847 std::is_nothrow_move_constructible<T>::value or std::is_move_constructible<E>::value),
851 assign_err(_e.
error());
861 template <
typename G,
862 typename std::enable_if<std::is_constructible<E, G>::value and std::is_assignable<E &, G>::value and
863 (std::is_nothrow_constructible<E, G>::value or
864 std::is_nothrow_move_constructible<T>::value or std::is_move_constructible<E>::value),
868 assign_err(std::move(_e).error());
878 template <
typename... Args>
881 static_assert(std::is_nothrow_constructible<T, Args...>::value,
"type T should have nothrow_constructible");
883 destroy_at(std::addressof(m_value));
885 destroy_at(std::addressof(m_error));
888 construct_at(std::addressof(m_value), std::forward<Args>(args)...);
900 template <
typename U,
typename... Args>
901 T &
emplace(std::initializer_list<U> li, Args &&...args)
noexcept
903 static_assert(std::is_nothrow_constructible<T, std::initializer_list<U> &, Args...>::value,
904 "type T should have a noexcept constructor");
906 destroy_at(std::addressof(m_value));
908 destroy_at(std::addressof(m_error));
910 construct_at(std::addressof(m_value), li, std::forward<Args>(args)...);
919 template <typename std::enable_if<std::is_move_constructible<T>::value and std::is_move_constructible<E>::value and
920 (std::is_nothrow_move_constructible<T>::value or
921 std::is_nothrow_move_constructible<E>::value),
924 swap(
DExpected &_x)
noexcept(std::is_nothrow_move_constructible<T>::value and std::is_nothrow_move_constructible<E>::value)
927 if (_x.m_has_value) {
929 swap(m_value, _x.m_value);
931 this->swap_val_err(_x);
935 _x.swap_val_err(*
this);
938 swap(m_error, _x.m_error);
950 return std::addressof(m_value);
960 return std::addressof(m_value);
990 return std::move(m_value);
1000 return std::move(m_value);
1007 constexpr explicit operator bool() const noexcept {
return m_has_value; }
1013 constexpr bool hasValue() const noexcept {
return m_has_value; }
1021 if (likely(m_has_value)) {
1033 if (likely(m_has_value)) {
1046 if (likely(m_has_value)) {
1047 return std::move(m_value);
1059 if (likely(m_has_value)) {
1060 return std::move(m_value);
1071 assert(!m_has_value);
1081 assert(!m_has_value);
1092 assert(!m_has_value);
1093 return std::move(m_error);
1103 assert(!m_has_value);
1104 return std::move(m_error);
1114 template <
typename U>
1117 static_assert(std::is_copy_constructible<T>::value,
"type T should have an copy constructor.");
1118 static_assert(std::is_convertible<U, T>::value,
"type U must can be converted to T.");
1121 return static_cast<T
>(std::forward<U>(_v));
1131 template <
typename U>
1134 static_assert(std::is_move_constructible<T>::value,
"type T must bu copy_constructible.");
1135 static_assert(std::is_convertible<U, T>::value,
"type U must can be converted to T.");
1137 return std::move(m_value);
1138 return static_cast<T
>(std::forward<U>(_v));
1144 template <typename U, typename E2, typename std::enable_if<!std::is_void<U>::value,
bool>::type =
true>
1147 const DExpected<U, E2> &_y)
noexcept(
noexcept(bool(*_x == *_y)) and
noexcept(
bool(_x.error() == _y.error())))
1150 return _y.hasValue() and bool(*_x == *_y);
1152 return !_y.hasValue() and bool(_x.error() == _x.error());
1158 template <
typename U>
1161 return _x.hasValue() && bool(*_x == _v);
1167 template <
typename E2>
1169 const DUnexpected<E2> &_e)
noexcept(
noexcept(bool(_x.error() == _e.error())))
1171 return !_x.hasValue() && bool(_x.error() == _e.error());
1192template <
typename E>
1195 static_assert(__dexpected::_can_be_dunexpected<E>(),
"type E can't be DUnexpected.");
1196 static constexpr bool des_value() {
return !std::is_trivially_destructible<E>::value; }
1198 template <
typename,
typename>
1201 template <
typename U,
typename G,
typename Unex = DUnexpected<E>>
1202 static constexpr bool __cons_from_DExpected()
1204 return std::is_constructible<Unex, DExpected<U, G> &>::value and std::is_constructible<Unex, DExpected<U, G>>::value and
1205 std::is_constructible<Unex, const DExpected<U, G> &>::value and
1206 std::is_constructible<Unex, const DExpected<U, G>>::value;
1209 template <
typename V>
1210 void assign_err(V &&_v)
1213 construct_at(std::addressof(m_error), std::forward<V>(_v));
1214 m_has_value =
false;
1216 m_error = std::forward<V>(_v);
1221 using value_type = void;
1222 using error_type = E;
1224 template <
typename U>
1233 template <typename std::enable_if<std::is_copy_constructible<E>::value,
bool>::type =
true>
1234 DExpected(
const DExpected &_x)
noexcept(std::is_nothrow_copy_constructible<E>::value)
1235 : m_has_value(_x.m_has_value)
1239 construct_at(std::addressof(m_error), _x.m_error);
1242 template <typename std::enable_if<std::is_move_constructible<E>::value,
bool>::type =
true>
1244 : m_has_value(_x.m_has_value)
1248 construct_at(std::addressof(m_error), std::move(_x).m_error);
1251 template <
typename U,
1253 typename std::enable_if<std::is_void<U>::value and std::is_constructible<E, const G &>::value and
1254 !__cons_from_DExpected<U, G>() and !std::is_convertible<const G &, E>::value,
1257 : m_has_value(_x.m_has_value)
1261 construct_at(std::addressof(m_error), _x.m_error);
1264 template <
typename U,
1266 typename std::enable_if<std::is_void<U>::value and std::is_constructible<E, const G &>::value and
1267 !__cons_from_DExpected<U, G>() and std::is_convertible<const G &, E>::value,
1270 : m_has_value(_x.m_has_value)
1274 construct_at(std::addressof(m_error), _x.m_error);
1277 template <
typename U,
1279 typename std::enable_if<std::is_void<U>::value and std::is_constructible<E, G>::value and
1280 __cons_from_DExpected<U, G>() and !std::is_convertible<G, E>::value,
1283 : m_has_value(_x.m_has_value)
1287 construct_at(std::addressof(m_error), std::move(_x).m_error);
1290 template <
typename U,
1292 typename std::enable_if<std::is_void<U>::value and std::is_constructible<E, G>::value and
1293 __cons_from_DExpected<U, G>() and std::is_convertible<G, E>::value,
1296 : m_has_value(_x.m_has_value)
1300 construct_at(std::addressof(m_error), std::move(_x).m_error);
1303 template <
typename G = E,
1304 typename std::enable_if<std::is_constructible<E, const G &>::value and !std::is_convertible<const G &, E>::value,
1306 constexpr explicit DExpected(
const DUnexpected<G> &_u)
noexcept(std::is_nothrow_constructible<E, const G &>::value)
1307 : m_has_value(
false)
1308 , m_error(_u.
error())
1312 template <
typename G = E,
1313 typename std::enable_if<std::is_constructible<E, const G &>::value and std::is_convertible<const G &, E>::value,
1316 : m_has_value(
false)
1317 , m_error(_u.
error())
1323 typename std::enable_if<std::is_constructible<E, G>::value and !std::is_convertible<G, E>::value,
bool>::type =
true>
1325 : m_has_value(
false)
1326 , m_error(std::move(_u).error())
1330 template <
typename G = E,
1331 typename std::enable_if<std::is_constructible<E, G>::value and std::is_convertible<G, E>::value,
bool>::type =
true>
1333 : m_has_value(
false)
1334 , m_error(std::move(_u).error())
1338 template <
typename... Args>
1339 constexpr explicit DExpected(emplace_tag) noexcept
1344 template <
typename... Args>
1345 constexpr explicit DExpected(dunexpected_tag, Args &&...args)
noexcept(std::is_nothrow_constructible<E, Args...>::value)
1346 : m_has_value(
false)
1347 , m_error(std::forward<Args>(args)...)
1349 static_assert(std::is_constructible<E, Args...>::value,
"type E can't construct from args");
1352 template <
typename U,
typename... Args>
1353 constexpr explicit DExpected(dunexpected_tag,
1354 std::initializer_list<U> _li,
1355 Args &&...args)
noexcept(std::is_nothrow_constructible<E, Args...>::value)
1356 : m_has_value(
false)
1357 , m_error(_li, std::forward<Args>(args)...)
1359 static_assert(std::is_constructible<E, std::initializer_list<U> &, Args...>::value,
"type E can't construct from args");
1364 if (des_value() and !m_has_value) {
1365 destroy_at(std::addressof(m_error));
1372 typename std::enable_if<std::is_copy_constructible<E>::value and std::is_copy_assignable<E>::value,
bool>::type =
true>
1374 std::is_nothrow_copy_constructible<E>::value and std::is_nothrow_copy_assignable<E>::value)
1379 assign_err(_x.m_error);
1384 typename std::enable_if<std::is_move_constructible<E>::value and std::is_move_assignable<E>::value,
bool>::type =
true>
1386 operator=(
DExpected &&_x)
noexcept(std::is_nothrow_move_constructible<E>::value and std::is_nothrow_move_assignable<E>::value)
1391 assign_err(std::move(_x.m_error));
1395 template <
typename G,
1396 typename std::enable_if<std::is_constructible<E, const G &>::value and std::is_assignable<E &, const G &>::value,
1400 assign_err(_e.
error());
1406 typename std::enable_if<std::is_constructible<E, G>::value and std::is_assignable<E &, G>::value,
bool>::type =
true>
1409 assign_err(std::move(_e.
error()));
1413 void emplace()
noexcept
1416 destroy_at(std::addressof(m_error));
1421 template <typename std::enable_if<std::is_move_constructible<E>::value,
bool>::type =
true>
1422 void swap(
DExpected &_x)
noexcept(std::is_nothrow_move_constructible<E>::value)
1425 if (!_x.m_has_value) {
1426 construct_at(std::addressof(m_error), std::move(_x.m_error));
1427 destroy_at(std::addressof(_x.m_error));
1428 m_has_value =
false;
1429 _x.m_has_value =
true;
1432 if (_x.m_has_value) {
1433 construct_at(std::addressof(_x.m_error), std::move(m_error));
1434 destroy_at(std::addressof(m_error));
1436 _x.m_has_value =
false;
1439 swap(m_error, _x.m_error);
1444 constexpr explicit operator bool()
const noexcept {
return m_has_value; }
1446 constexpr bool hasValue()
const noexcept {
return m_has_value; }
1448 void operator*()
const noexcept { assert(m_has_value); }
1450 void value()
const &
1452 if (likely(m_has_value))
1459 if (likely(m_has_value))
1464 const E &error()
const &
noexcept
1466 assert(!m_has_value);
1470 E &error() &
noexcept
1472 assert(!m_has_value);
1476 const E &&error()
const &&
noexcept
1478 assert(!m_has_value);
1479 return std::move(m_error);
1482 E &&error() &&
noexcept
1484 assert(!m_has_value);
1485 return std::move(m_error);
1488 template <typename U, typename E2, typename std::enable_if<std::is_void<U>::value,
bool>::type =
true>
1497 template <
typename E2>
模板类Dtk::Core::DExpected提供存储两个值之一的方式。Dtk::Core::DExpected的对象要么保有一个期待的T类型值,要么保有一个不期待的E类型值,不会没有值。
Definition: dexpected.h:375
constexpr DExpected(emplace_tag, Args &&...args) noexcept(std::is_nothrow_constructible< T, Args... >::value)
Dtk::Core::DExpected的转发构造函数,从参数直接构造出期待值
Definition: dexpected.h:700
T value_or(U &&_v) const &
如果有期待值返回期待值,否则返回传入的默认值
Definition: dexpected.h:1115
const T & operator*() const &noexcept
重载解引用运算符
Definition: dexpected.h:967
DExpected(const DExpected &_x) noexcept(std::is_nothrow_copy_constructible< T >::value and std::is_nothrow_copy_constructible< E >::value)
Dtk::Core::DExpected的拷贝构造函数
Definition: dexpected.h:477
constexpr DExpected(emplace_tag, std::initializer_list< U > _li, Args &&...args) noexcept(std::is_nothrow_constructible< T, std::initializer_list< U > &, Args... >::value)
Dtk::Core::DExpected的转发构造函数,从参数直接构造出期待值
Definition: dexpected.h:718
T * operator->() noexcept
重载箭头运算符
Definition: dexpected.h:957
constexpr DExpected(DUnexpected< G > &&_u) noexcept(std::is_nothrow_constructible< E, G >::value)
Dtk::Core::DExpected的移动构造函数,从Dtk::Core::DUnexpected构造出Dtk::Core::DExpected对象
Definition: dexpected.h:671
DExpected & operator=(DExpected &&_x) noexcept(std::is_nothrow_move_constructible< T >::value and std::is_nothrow_move_constructible< E >::value and std::is_nothrow_move_assignable< T >::value and std::is_nothrow_move_assignable< E >::value)
Dtk::Core::DExpected的移动赋值运算符
Definition: dexpected.h:809
friend constexpr bool operator==(const DExpected &_x, const U &_v) noexcept(noexcept(bool(*_x==_v)))
重载相等运算符
Definition: dexpected.h:1159
T value_or(U &&_v) &&
如果有期待值返回期待值,否则返回传入的默认值
Definition: dexpected.h:1132
T & emplace(std::initializer_list< U > li, Args &&...args) noexcept
从参数直接转发构造期待值
Definition: dexpected.h:901
DExpected(DExpected &&_x) noexcept(std::is_nothrow_move_constructible< T >::value and std::is_nothrow_move_constructible< E >::value)
Dtk::Core::DExpected的移动构造函数
Definition: dexpected.h:492
constexpr DExpected(dunexpected_tag, std::initializer_list< U > _li, Args &&...args) noexcept(std::is_nothrow_constructible< E, std::initializer_list< U > &, Args... >::value)
Dtk::Core::DExpected的转发构造函数,从参数直接构造出不期待值
Definition: dexpected.h:752
DExpected & operator=(const DUnexpected< G > &_e)
Dtk::Core::DExpected的拷贝赋值运算符
Definition: dexpected.h:849
const T * operator->() const noexcept
重载箭头运算符
Definition: dexpected.h:947
const E && error() const &&noexcept
获取Dtk::Core::DExpected的不期待值
Definition: dexpected.h:1090
T & value() &
获取Dtk::Core::DExpected的期待值
Definition: dexpected.h:1031
T && operator*() &&noexcept
重载解引用运算符
Definition: dexpected.h:997
T && value() &&
获取Dtk::Core::DExpected的期待值
Definition: dexpected.h:1057
constexpr DExpected() noexcept(std::is_nothrow_default_constructible< T >::value)
Dtk::Core::DExpected的默认构造函数
Definition: dexpected.h:466
E & error() &noexcept
获取Dtk::Core::DExpected的不期待值
Definition: dexpected.h:1079
DExpected & operator=(const DExpected &_x) noexcept(std::is_nothrow_copy_constructible< T >::value and std::is_nothrow_copy_constructible< E >::value and std::is_nothrow_copy_assignable< T >::value and std::is_nothrow_copy_assignable< E >::value)
Dtk::Core::DExpected的拷贝赋值运算符
Definition: dexpected.h:788
E && error() &&noexcept
获取Dtk::Core::DExpected的不期待值
Definition: dexpected.h:1101
const E & error() const &noexcept
获取Dtk::Core::DExpected的不期待值
Definition: dexpected.h:1069
constexpr DExpected(dunexpected_tag, Args &&...args) noexcept(std::is_nothrow_constructible< E, Args... >::value)
Dtk::Core::DExpected的转发构造函数,从参数直接构造出不期待值
Definition: dexpected.h:734
constexpr DExpected(U &&_v) noexcept(std::is_nothrow_constructible< T, U >::value)
Dtk::Core::DExpected的移动构造函数,直接从期待类型构造出Dtk::Core::DExpected对象
Definition: dexpected.h:604
~DExpected()
Dtk::Core::DExpected的析构函数
Definition: dexpected.h:763
friend bool operator==(const DExpected &_x, const DExpected< U, E2 > &_y) noexcept(noexcept(bool(*_x== *_y)) and noexcept(bool(_x.error()==_y.error())))
重载相等运算符
Definition: dexpected.h:1146
friend constexpr bool operator==(const DExpected &_x, const DUnexpected< E2 > &_e) noexcept(noexcept(bool(_x.error()==_e.error())))
重载相等运算符
Definition: dexpected.h:1168
const T & value() const &
获取Dtk::Core::DExpected的期待值
Definition: dexpected.h:1019
void swap(DExpected &_x) noexcept(std::is_nothrow_move_constructible< T >::value and std::is_nothrow_move_constructible< E >::value)
交换两个Dtk::Core::DExpected的值
Definition: dexpected.h:924
DExpected & operator=(const DExpected &)=delete
Dtk::Core::DExpected的默认拷贝赋值运算符
constexpr bool hasValue() const noexcept
判断Dtk::Core::DExpected是否有值
Definition: dexpected.h:1013
constexpr DExpected(const DUnexpected< G > &_u) noexcept(std::is_nothrow_constructible< E, const G & >::value)
Dtk::Core::DExpected的拷贝构造函数,从Dtk::Core::DUnexpected构造出Dtk::Core::DExpected对象
Definition: dexpected.h:640
T & emplace(Args &&...args) noexcept
从参数直接转发构造期待值
Definition: dexpected.h:879
const T && value() const &&
获取Dtk::Core::DExpected的期待值
Definition: dexpected.h:1044
DExpected & operator=(DUnexpected< G > &&_e)
Dtk::Core::DExpected的移动赋值运算符
Definition: dexpected.h:866
DExpected & operator=(U &&_v)
Dtk::Core::DExpected的转发赋值运算符
Definition: dexpected.h:833
const T && operator*() const &&noexcept
重载解引用运算符
Definition: dexpected.h:987
T & operator*() &noexcept
重载解引用运算符
Definition: dexpected.h:977
friend void swap(DExpected &_x, DExpected &_y) noexcept(noexcept(_x.swap(_y)))
交换两个Dtk::Core::DExpected中的值
Definition: dexpected.h:1177
类模板Dtk::Core::DUnexpected代表一个Dtk::Core::DExpected中存储的不期待的值
Definition: dexpected.h:239
constexpr DUnexpected(emplace_tag, Args &&...args) noexcept(std::is_nothrow_constructible< E, Args... >::value)
直接从参数构造出一个包含错误类型为E的对象的Dtk::Core::DUnexpected对象
Definition: dexpected.h:277
constexpr DUnexpected(DUnexpected &&)=default
Dtk::Core::DUnexpected的默认移动构造函数
DUnexpected & operator=(const DUnexpected &)=default
Dtk::Core::DUnexpected的默认拷贝赋值运算符
E && error() &&noexcept
获取Dtk::Core::DUnexpected持有的不期待值
Definition: dexpected.h:334
constexpr const E && error() const &&noexcept
获取Dtk::Core::DUnexpected持有的不期待值
Definition: dexpected.h:327
constexpr DUnexpected(Er &&_e) noexcept(std::is_nothrow_constructible< E, Er >::value)
使用类型E直接初始化一个Dtk::Core::DUnexpected对象
Definition: dexpected.h:263
constexpr const E & error() const &noexcept
获取Dtk::Core::DUnexpected持有的不期待值
Definition: dexpected.h:314
constexpr DUnexpected(emplace_tag, std::initializer_list< U > _li, Args &&...args) noexcept(std::is_nothrow_constructible< E, std::initializer_list< U > &, Args... >::value)
从参数和初始化列表构造出一个包含错误类型为E的对象的Dtk::Core::DUnexpected对象
Definition: dexpected.h:294
constexpr DUnexpected(const DUnexpected &)=default
Dtk::Core::DUnexpected的默认拷贝构造函数
void swap(DUnexpected &_other)
交换两个Dtk::Core::DUnexpected的值
Definition: dexpected.h:340
DUnexpected & operator=(DUnexpected &&)=default
Dtk::Core::DUnexpected的默认移动赋值运算符
E & error() &noexcept
获取Dtk::Core::DUnexpected持有的不期待值
Definition: dexpected.h:320
friend void swap(DUnexpected &_x, DUnexpected &_y)
交换两个Dtk::Core::DUnexpected的值
Definition: dexpected.h:361
friend constexpr bool operator==(const DUnexpected &_x, const DUnexpected< Er > _y)
重载相等运算符
Definition: dexpected.h:353
Definition: dexpected.h:73
Definition: dexpected.h:127
Definition: dexpected.h:157
Definition: dexpected.h:167
Definition: dexpected.h:49