discriminated union to hold value or 'error'.
discriminated union to hold only 'error'.
x.x.5 Unexpected object type; unexpected_type; C++17 and later can also use aliased type unexpected.
362 {
namespace expected_lite {
368 #if nsel_CPP17_OR_GREATER
370 using std::conjunction;
371 using std::is_swappable;
372 using std::is_nothrow_swappable;
382 template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
383 static std::true_type
test(
int );
386 static std::false_type
test(...);
389 struct is_nothrow_swappable
393 template<
typename T >
394 static constexpr
bool satisfies()
396 return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
399 template<
typename T >
400 static auto test(
int ) -> std::integral_constant<bool, satisfies<T>()>{}
403 static auto test(...) -> std::false_type;
409 template<
typename T >
410 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
412 template<
typename T >
413 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
417 template<
typename... >
struct conjunction : std::true_type{};
418 template<
typename B1 >
struct conjunction<B1> : B1{};
420 template<
typename B1,
typename... Bn >
421 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
431 #if nsel_CPP20_OR_GREATER
433 using std::remove_cvref;
437 template<
typename T >
440 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
449 template<
typename T,
typename E >
456 template<
typename T,
typename E >
459 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
462 using value_type = T;
463 using error_type = E;
469 explicit storage_t_impl(
bool has_value )
470 : m_has_value( has_value )
473 void construct_value( value_type
const &
e )
475 new( &m_value ) value_type(
e );
478 void construct_value( value_type &&
e )
480 new( &m_value ) value_type( std::move(
e ) );
483 template<
class... Args >
484 void emplace_value( Args&&...
args )
486 new( &m_value ) value_type( std::forward<Args>(
args)...);
489 template<
class U,
class... Args >
490 void emplace_value( std::initializer_list<U> il, Args&&...
args )
492 new( &m_value ) value_type( il, std::forward<Args>(
args)... );
495 void destruct_value()
497 m_value.~value_type();
500 void construct_error( error_type
const &
e )
502 new( &m_error ) error_type(
e );
505 void construct_error( error_type &&
e )
507 new( &m_error ) error_type( std::move(
e ) );
510 template<
class... Args >
511 void emplace_error( Args&&...
args )
513 new( &m_error ) error_type( std::forward<Args>(
args)...);
516 template<
class U,
class... Args >
517 void emplace_error( std::initializer_list<U> il, Args&&...
args )
519 new( &m_error ) error_type( il, std::forward<Args>(
args)... );
522 void destruct_error()
524 m_error.~error_type();
527 constexpr value_type
const &
value() const &
532 value_type &
value() &
537 constexpr value_type
const &&
value() const &&
539 return std::move( m_value );
544 return std::move( m_value );
547 value_type
const * value_ptr()
const
552 value_type * value_ptr()
557 error_type
const & error() const &
562 error_type & error() &
567 constexpr error_type
const && error() const &&
569 return std::move( m_error );
574 return std::move( m_error );
577 bool has_value()
const
582 void set_has_value(
bool v )
594 bool m_has_value =
false;
599 template<
typename E >
600 struct storage_t_impl<void, E>
602 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
605 using value_type = void;
606 using error_type = E;
612 explicit storage_t_impl(
bool has_value )
613 : m_has_value( has_value )
616 void construct_error( error_type
const &
e )
618 new( &m_error ) error_type(
e );
621 void construct_error( error_type &&
e )
623 new( &m_error ) error_type( std::move(
e ) );
626 template<
class... Args >
627 void emplace_error( Args&&...
args )
629 new( &m_error ) error_type( std::forward<Args>(
args)...);
632 template<
class U,
class... Args >
633 void emplace_error( std::initializer_list<U> il, Args&&...
args )
635 new( &m_error ) error_type( il, std::forward<Args>(
args)... );
638 void destruct_error()
640 m_error.~error_type();
643 error_type
const & error() const &
648 error_type & error() &
653 constexpr error_type
const && error() const &&
655 return std::move( m_error );
660 return std::move( m_error );
663 bool has_value()
const
668 void set_has_value(
bool v )
680 bool m_has_value =
false;
683 template<
typename T,
typename E,
bool isConstructable,
bool isMoveable >
687 storage_t() =
default;
688 ~storage_t() =
default;
690 explicit storage_t(
bool has_value )
691 : storage_t_impl<T, E>( has_value )
694 storage_t( storage_t
const & other ) =
delete;
695 storage_t( storage_t && other ) =
delete;
698 template<
typename T,
typename E >
699 class storage_t<T, E, true, true> :
public storage_t_impl<T, E>
702 storage_t() =
default;
703 ~storage_t() =
default;
705 explicit storage_t(
bool has_value )
706 : storage_t_impl<T, E>( has_value )
709 storage_t( storage_t
const & other )
710 : storage_t_impl<T, E>( other.has_value() )
712 if ( this->has_value() ) this->construct_value( other.value() );
713 else this->construct_error( other.error() );
716 storage_t(storage_t && other )
717 : storage_t_impl<T, E>( other.has_value() )
719 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
720 else this->construct_error( std::move( other.error() ) );
724 template<
typename E >
725 class storage_t<void, E, true, true> :
public storage_t_impl<void, E>
728 storage_t() =
default;
729 ~storage_t() =
default;
731 explicit storage_t(
bool has_value )
732 : storage_t_impl<void, E>( has_value )
735 storage_t( storage_t
const & other )
736 : storage_t_impl<void, E>( other.has_value() )
738 if ( this->has_value() ) ;
739 else this->construct_error( other.error() );
742 storage_t(storage_t && other )
743 : storage_t_impl<void, E>( other.has_value() )
745 if ( this->has_value() ) ;
746 else this->construct_error( std::move( other.error() ) );
750 template<
typename T,
typename E >
751 class storage_t<T, E, true, false> :
public storage_t_impl<T, E>
754 storage_t() =
default;
755 ~storage_t() =
default;
757 explicit storage_t(
bool has_value )
758 : storage_t_impl<T, E>( has_value )
761 storage_t( storage_t
const & other )
762 : storage_t_impl<T, E>(other.has_value())
764 if ( this->has_value() ) this->construct_value( other.value() );
765 else this->construct_error( other.error() );
768 storage_t( storage_t && other ) =
delete;
771 template<
typename E >
772 class storage_t<void, E, true, false> :
public storage_t_impl<void, E>
775 storage_t() =
default;
776 ~storage_t() =
default;
778 explicit storage_t(
bool has_value )
779 : storage_t_impl<void, E>( has_value )
782 storage_t( storage_t
const & other )
783 : storage_t_impl<void, E>(other.has_value())
785 if ( this->has_value() ) ;
786 else this->construct_error( other.error() );
789 storage_t( storage_t && other ) =
delete;
792 template<
typename T,
typename E >
793 class storage_t<T, E, false, true> :
public storage_t_impl<T, E>
796 storage_t() =
default;
797 ~storage_t() =
default;
799 explicit storage_t(
bool has_value )
800 : storage_t_impl<T, E>( has_value )
803 storage_t( storage_t
const & other ) =
delete;
805 storage_t( storage_t && other )
806 : storage_t_impl<T, E>( other.has_value() )
808 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
809 else this->construct_error( std::move( other.error() ) );
813 template<
typename E >
814 class storage_t<void, E, false, true> :
public storage_t_impl<void, E>
817 storage_t() =
default;
818 ~storage_t() =
default;
820 explicit storage_t(
bool has_value )
821 : storage_t_impl<void, E>( has_value )
824 storage_t( storage_t
const & other ) =
delete;
826 storage_t( storage_t && other )
827 : storage_t_impl<void, E>( other.has_value() )
829 if ( this->has_value() ) ;
830 else this->construct_error( std::move( other.error() ) );
839 template<
typename E = std::exception_ptr >
840 class unexpected_type
842 template< typename E >
843 class unexpected_type
847 using error_type = E;
853 constexpr unexpected_type( unexpected_type
const & ) =
default;
854 constexpr unexpected_type( unexpected_type && ) =
default;
856 template<
typename... Args
862 : m_error(
std::forward<Args>(
args )...)
865 template<
typename U,
typename... Args
867 std::is_constructible<E, std::initializer_list<U>, Args&&...>::
value
871 : m_error( il,
std::forward<Args>(
args )...)
874 template<
typename E2
878 && !std::is_same<
typename std20::remove_cvref<E2>::type, unexpected_type >::
value
881 constexpr
explicit unexpected_type( E2 && error )
882 : m_error(
std::forward<E2>( error ) )
885 template<
typename E2
888 && !std::is_constructible<E, unexpected_type<E2> & >::
value
889 && !std::is_constructible<E, unexpected_type<E2> >::
value
890 && !std::is_constructible<E, unexpected_type<E2>
const & >::
value
891 && !std::is_constructible<E, unexpected_type<E2>
const >::
value
892 && !std::is_convertible< unexpected_type<E2> &, E>::
value
893 && !std::is_convertible< unexpected_type<E2> , E>::
value
894 && !std::is_convertible< unexpected_type<E2>
const &, E>::
value
895 && !std::is_convertible< unexpected_type<E2>
const , E>::
value
899 constexpr
explicit unexpected_type( unexpected_type<E2>
const & error )
900 : m_error( E{ error.
value() } )
903 template<
typename E2
906 && !std::is_constructible<E, unexpected_type<E2> & >::
value
907 && !std::is_constructible<E, unexpected_type<E2> >::
value
908 && !std::is_constructible<E, unexpected_type<E2>
const & >::
value
909 && !std::is_constructible<E, unexpected_type<E2>
const >::
value
910 && !std::is_convertible< unexpected_type<E2> &, E>::
value
911 && !std::is_convertible< unexpected_type<E2> , E>::
value
912 && !std::is_convertible< unexpected_type<E2>
const &, E>::
value
913 && !std::is_convertible< unexpected_type<E2>
const , E>::
value
917 constexpr unexpected_type( unexpected_type<E2>
const & error )
918 : m_error( error.
value() )
921 template<
typename E2
924 && !std::is_constructible<E, unexpected_type<E2> & >::
value
925 && !std::is_constructible<E, unexpected_type<E2> >::
value
926 && !std::is_constructible<E, unexpected_type<E2>
const & >::
value
927 && !std::is_constructible<E, unexpected_type<E2>
const >::
value
928 && !std::is_convertible< unexpected_type<E2> &, E>::
value
929 && !std::is_convertible< unexpected_type<E2> , E>::
value
930 && !std::is_convertible< unexpected_type<E2>
const &, E>::
value
931 && !std::is_convertible< unexpected_type<E2>
const , E>::
value
935 constexpr
explicit unexpected_type( unexpected_type<E2> && error )
936 : m_error( E{
std::move( error.
value() ) } )
939 template<
typename E2
942 && !std::is_constructible<E, unexpected_type<E2> & >::
value
943 && !std::is_constructible<E, unexpected_type<E2> >::
value
944 && !std::is_constructible<E, unexpected_type<E2>
const & >::
value
945 && !std::is_constructible<E, unexpected_type<E2>
const >::
value
946 && !std::is_convertible< unexpected_type<E2> &, E>::
value
947 && !std::is_convertible< unexpected_type<E2> , E>::
value
948 && !std::is_convertible< unexpected_type<E2>
const &, E>::
value
949 && !std::is_convertible< unexpected_type<E2>
const , E>::
value
953 constexpr unexpected_type( unexpected_type<E2> && error )
954 : m_error(
std::move( error.
value() ) )
959 nsel_constexpr14 unexpected_type& operator=( unexpected_type
const & ) =
default;
960 nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) =
default;
962 template<
typename E2 = E >
963 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2>
const & other )
965 unexpected_type{ other.value() }.swap( *
this );
969 template<
typename E2 = E >
970 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
972 unexpected_type{ std::move( other.value() ) }.swap( *
this );
983 constexpr E
const &
value() const & noexcept
988 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
992 return std::move( m_error );
995 constexpr E
const &&
value() const && noexcept
997 return std::move( m_error );
1007 swap( unexpected_type & other ) noexcept (
1012 swap( m_error, other.m_error );
1021 #if nsel_CPP17_OR_GREATER
1025 template<
typename E >
1026 unexpected_type( E ) -> unexpected_type< E >;
1032 #if !nsel_CONFIG_NO_EXCEPTIONS
1033 #if nsel_P0323R <= 2
1038 class unexpected_type<
std::exception_ptr >
1041 using error_type = std::exception_ptr;
1043 unexpected_type() =
delete;
1045 ~unexpected_type(){}
1047 explicit unexpected_type( std::exception_ptr
const & error )
1051 explicit unexpected_type(std::exception_ptr && error )
1052 : m_error(
std::move( error ) )
1055 template<
typename E >
1056 explicit unexpected_type( E error )
1057 : m_error(
std::make_exception_ptr( error ) )
1060 std::exception_ptr
const &
value()
const
1065 std::exception_ptr &
value()
1071 std::exception_ptr m_error;
1079 template<
typename E1,
typename E2 >
1080 constexpr
bool operator==( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1082 return x.value() == y.value();
1085 template<
typename E1,
typename E2 >
1086 constexpr
bool operator!=( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1088 return ! ( x == y );
1091 #if nsel_P0323R <= 2
1093 template<
typename E >
1094 constexpr
bool operator<( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1096 return x.value() < y.value();
1099 template<
typename E >
1100 constexpr
bool operator>( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1105 template<
typename E >
1106 constexpr
bool operator<=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1111 template<
typename E >
1112 constexpr
bool operator>=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1121 template<
typename E
1126 void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
1131 #if nsel_P0323R <= 2
1135 inline constexpr
bool operator<( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1140 inline constexpr
bool operator>( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1145 inline constexpr
bool operator<=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1150 inline constexpr
bool operator>=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1159 #if nsel_P0323R <= 3
1161 template<
typename E>
1162 struct is_unexpected : std::false_type {};
1164 template<
typename E>
1165 struct is_unexpected< unexpected_type<E> > : std::true_type {};
1173 template<
typename E>
1175 make_unexpected( E &&
value ) -> unexpected_type< typename std::decay<E>::type >
1177 return unexpected_type< typename std::decay<E>::type >( std::forward<E>(
value) );
1180 #if nsel_P0323R <= 3
1183 make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
1185 return unexpected_type< std::exception_ptr >( std::current_exception() );
1192 template<
typename E >
1193 class bad_expected_access;
1198 class bad_expected_access< void > :
public std::exception
1201 explicit bad_expected_access()
1208 #if !nsel_CONFIG_NO_EXCEPTIONS
1210 template<
typename E >
1211 class bad_expected_access :
public bad_expected_access< void >
1214 using error_type = E;
1216 explicit bad_expected_access( error_type error )
1220 virtual char const * what() const noexcept
override
1222 return "bad_expected_access";
1230 constexpr error_type
const & error() const &
1235 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1239 return std::move( m_error );
1242 constexpr error_type
const && error() const &&
1244 return std::move( m_error );
1257 struct unexpect_t{};
1258 using in_place_unexpected_t = unexpect_t;
1265 #if nsel_CONFIG_NO_EXCEPTIONS
1268 inline bool text(
char const * ) {
return true; }
1271 template<
typename Error >
1274 static void rethrow( Error
const & )
1276 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1277 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1279 assert(
false && detail::text(
"throw bad_expected_access<Error>{ e };") );
1285 struct error_traits<
std::exception_ptr >
1287 static void rethrow( std::exception_ptr
const & )
1289 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1290 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1292 assert(
false && detail::text(
"throw bad_expected_access<std::exception_ptr>{ e };") );
1298 struct error_traits<
std::error_code >
1300 static void rethrow( std::error_code
const & )
1302 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1303 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1305 assert(
false && detail::text(
"throw std::system_error( e );") );
1312 template<
typename Error >
1315 static void rethrow( Error
const &
e )
1317 throw bad_expected_access<Error>{
e };
1322 struct error_traits<
std::exception_ptr >
1324 static void rethrow( std::exception_ptr
const &
e )
1326 std::rethrow_exception(
e );
1331 struct error_traits<
std::error_code >
1333 static void rethrow( std::error_code
const &
e )
1335 throw std::system_error(
e );
1345 using expected_lite::unexpected_type;
1347 namespace expected_lite {
1351 #if nsel_P0323R <= 2
1352 template<
typename T,
typename E = std::exception_ptr >
1355 template< typename T, typename E >
1360 template<
typename,
typename >
friend class expected;
1363 using value_type = T;
1364 using error_type = E;
1365 using unexpected_type = nonstd::unexpected_type<E>;
1367 template<
typename U >
1370 using type = expected<U, error_type>;
1381 contained.construct_value( value_type() );
1387 template<
typename U,
typename G
1391 && !std::is_constructible<T, expected<U, G> & >::
value
1392 && !std::is_constructible<T, expected<U, G> && >::
value
1393 && !std::is_constructible<T, expected<U, G>
const & >::
value
1394 && !std::is_constructible<T, expected<U, G>
const && >::
value
1395 && !std::is_convertible< expected<U, G> & , T>::
value
1396 && !std::is_convertible< expected<U, G> &&, T>::
value
1397 && !std::is_convertible< expected<U, G>
const & , T>::
value
1398 && !std::is_convertible< expected<U, G>
const &&, T>::
value
1403 : contained( other.has_value() )
1405 if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
1406 else contained.construct_error( E{ other.contained.error() } );
1409 template<
typename U,
typename G
1413 && !std::is_constructible<T, expected<U, G> & >::
value
1414 && !std::is_constructible<T, expected<U, G> && >::
value
1415 && !std::is_constructible<T, expected<U, G>
const & >::
value
1416 && !std::is_constructible<T, expected<U, G>
const && >::
value
1417 && !std::is_convertible< expected<U, G> & , T>::
value
1418 && !std::is_convertible< expected<U, G> &&, T>::
value
1419 && !std::is_convertible< expected<U, G>
const &, T>::
value
1420 && !std::is_convertible< expected<U, G>
const &&, T>::
value
1425 : contained( other.has_value() )
1427 if ( has_value() ) contained.construct_value( other.contained.value() );
1428 else contained.construct_error( other.contained.error() );
1431 template<
typename U,
typename G
1435 && !std::is_constructible<T, expected<U, G> & >::
value
1436 && !std::is_constructible<T, expected<U, G> && >::
value
1437 && !std::is_constructible<T, expected<U, G>
const & >::
value
1438 && !std::is_constructible<T, expected<U, G>
const && >::
value
1439 && !std::is_convertible< expected<U, G> & , T>::
value
1440 && !std::is_convertible< expected<U, G> &&, T>::
value
1441 && !std::is_convertible< expected<U, G>
const & , T>::
value
1442 && !std::is_convertible< expected<U, G>
const &&, T>::
value
1447 : contained( other.has_value() )
1449 if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
1450 else contained.construct_error( E{ std::move( other.contained.error() ) } );
1453 template<
typename U,
typename G
1457 && !std::is_constructible<T, expected<U, G> & >::
value
1458 && !std::is_constructible<T, expected<U, G> && >::
value
1459 && !std::is_constructible<T, expected<U, G>
const & >::
value
1460 && !std::is_constructible<T, expected<U, G>
const && >::
value
1461 && !std::is_convertible< expected<U, G> & , T>::
value
1462 && !std::is_convertible< expected<U, G> &&, T>::
value
1463 && !std::is_convertible< expected<U, G>
const & , T>::
value
1464 && !std::is_convertible< expected<U, G>
const &&, T>::
value
1469 : contained( other.has_value() )
1471 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
1472 else contained.construct_error( std::move( other.contained.error() ) );
1475 template<
typename U = T
1483 contained.construct_value(
value );
1486 template<
typename U = T
1490 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::
value
1491 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::
value
1502 contained.construct_value( T{ std::forward<U>(
value ) } );
1505 template<
typename U = T
1509 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::
value
1510 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::
value
1521 contained.construct_value( std::forward<U>(
value ) );
1526 template<
typename G = E
1532 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G>
const & error )
1533 : contained( false )
1535 contained.construct_error( E{ error.value() } );
1538 template<
typename G = E
1545 : contained( false )
1547 contained.construct_error( error.value() );
1550 template<
typename G = E
1557 : contained( false )
1559 contained.construct_error( E{ std::move( error.value() ) } );
1562 template<
typename G = E
1569 : contained( false )
1571 contained.construct_error( std::move( error.value() ) );
1576 template<
typename... Args
1584 contained.emplace_value( std::forward<Args>(
args )... );
1587 template<
typename U,
typename... Args
1589 std::is_constructible<T, std::initializer_list<U>, Args&&...>::
value
1595 contained.emplace_value( il, std::forward<Args>(
args )... );
1600 template<
typename... Args
1606 : contained( false )
1608 contained.emplace_error( std::forward<Args>(
args )... );
1611 template<
typename U,
typename... Args
1613 std::is_constructible<E, std::initializer_list<U>, Args&&...>::
value
1617 : contained( false )
1619 contained.emplace_error( il, std::forward<Args>(
args )... );
1630 if ( has_value() ) contained.destruct_value();
1631 else contained.destruct_error();
1636 expected & operator=( expected
const & other )
1638 expected( other ).swap( *
this );
1642 expected & operator=( expected && other ) noexcept
1649 expected( std::move( other ) ).swap( *
this );
1653 template<
typename U
1655 !std::is_same<expected<T,E>,
typename std20::remove_cvref<U>::type>::
value
1656 && std17::conjunction<std::is_scalar<T>, std::is_same<T, std::decay<U>> >::
value
1661 expected & operator=( U &&
value )
1663 expected( std::forward<U>(
value ) ).swap( *
this );
1667 template<
typename G
1673 expected & operator=( nonstd::unexpected_type<G>
const & error )
1675 expected( unexpect, error.value() ).swap( *
this );
1679 template<
typename G
1685 expected & operator=( nonstd::unexpected_type<G> && error )
1687 expected( unexpect, std::move( error.value() ) ).swap( *
this );
1691 template<
typename... Args
1696 value_type & emplace( Args &&...
args )
1702 template<
typename U,
typename... Args
1704 std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::
value
1707 value_type & emplace( std::initializer_list<U> il, Args &&...
args )
1715 template<
typename U=T,
typename G=E >
1721 swap( expected & other ) noexcept
1729 if (
bool(*
this) &&
bool(other) ) { swap( contained.value(), other.contained.value() ); }
1730 else if ( !
bool(*
this) && !
bool(other) ) { swap( contained.error(), other.contained.error() ); }
1731 else if (
bool(*
this) && !
bool(other) ) { error_type t( std::move( other.error() ) );
1732 other.contained.destruct_error();
1733 other.contained.construct_value( std::move( contained.value() ) );
1734 contained.destruct_value();
1735 contained.construct_error( std::move( t ) );
1736 bool has_value = contained.has_value();
1737 bool other_has_value = other.has_value();
1738 other.contained.set_has_value(has_value);
1739 contained.set_has_value(other_has_value);
1741 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
1746 constexpr value_type
const * operator ->()
const
1748 return assert( has_value() ), contained.value_ptr();
1751 value_type * operator ->()
1753 return assert( has_value() ), contained.value_ptr();
1756 constexpr value_type
const & operator *() const &
1758 return assert( has_value() ), contained.value();
1761 value_type & operator *() &
1763 return assert( has_value() ), contained.value();
1766 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1768 constexpr value_type
const && operator *() const &&
1770 return assert( has_value() ), std::move( contained.value() );
1775 return assert( has_value() ), std::move( contained.value() );
1780 constexpr
explicit operator bool() const noexcept
1785 constexpr
bool has_value() const noexcept
1787 return contained.has_value();
1790 constexpr value_type
const &
value() const &
1793 ? ( contained.value() )
1794 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
1797 value_type &
value() &
1800 ? ( contained.value() )
1801 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
1804 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1806 constexpr value_type
const &&
value() const &&
1808 return std::move( has_value()
1809 ? ( contained.value() )
1810 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
1815 return std::move( has_value()
1816 ? ( contained.value() )
1817 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
1822 constexpr error_type
const & error() const &
1824 return assert( ! has_value() ), contained.error();
1827 error_type & error() &
1829 return assert( ! has_value() ), contained.error();
1832 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1834 constexpr error_type
const && error() const &&
1836 return assert( ! has_value() ), std::move( contained.error() );
1839 error_type && error() &&
1841 return assert( ! has_value() ), std::move( contained.error() );
1846 constexpr unexpected_type get_unexpected()
const
1848 return make_unexpected( contained.error() );
1851 template<
typename Ex >
1852 bool has_exception()
const
1854 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().
value() ) >::type;
1858 template<
typename U
1864 value_type value_or( U && v )
const &
1868 :
static_cast<T
>( std::forward<U>( v ) );
1871 template<
typename U
1877 value_type value_or( U && v ) &&
1880 ? std::move( contained.value() )
1881 : static_cast<T>(
std::forward<U>( v ) );
1928 template<
typename E >
1929 class expected<void, E>
1932 template<
typename,
typename >
friend class expected;
1935 using value_type = void;
1936 using error_type = E;
1937 using unexpected_type = nonstd::unexpected_type<E>;
1941 constexpr expected() noexcept
1952 template<
typename G = E
1957 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G>
const & error )
1958 : contained( false )
1960 contained.construct_error( E{ error.value() } );
1963 template<
typename G = E
1969 : contained( false )
1971 contained.construct_error( error.value() );
1974 template<
typename G = E
1980 : contained( false )
1982 contained.construct_error( E{ std::move( error.value() ) } );
1985 template<
typename G = E
1991 : contained( false )
1993 contained.construct_error( std::move( error.value() ) );
1996 template<
typename... Args
2002 : contained( false )
2004 contained.emplace_error( std::forward<Args>(
args )... );
2007 template<
typename U,
typename... Args
2009 std::is_constructible<E, std::initializer_list<U>, Args&&...>::
value
2013 : contained( false )
2015 contained.emplace_error( il, std::forward<Args>(
args )... );
2022 if ( ! has_value() )
2024 contained.destruct_error();
2030 expected & operator=( expected
const & other )
2032 expected( other ).swap( *
this );
2036 expected & operator=( expected && other ) noexcept
2041 expected( std::move( other ) ).swap( *
this );
2047 expected().swap( *
this );
2052 template<
typename G = E >
2057 swap( expected & other ) noexcept
2064 if ( !
bool(*
this) && !
bool(other) ) { swap( contained.error(), other.contained.error() ); }
2065 else if (
bool(*
this) && !
bool(other) ) { contained.construct_error( std::move( other.error() ) );
2066 bool has_value = contained.has_value();
2067 bool other_has_value = other.has_value();
2068 other.contained.set_has_value(has_value);
2069 contained.set_has_value(other_has_value);
2071 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2076 constexpr
explicit operator bool() const noexcept
2081 constexpr
bool has_value() const noexcept
2083 return contained.has_value();
2088 if ( ! has_value() )
2090 error_traits<error_type>::rethrow( contained.error() );
2094 constexpr error_type
const & error() const &
2096 return assert( ! has_value() ), contained.error();
2099 error_type & error() &
2101 return assert( ! has_value() ), contained.error();
2104 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2106 constexpr error_type
const && error() const &&
2108 return assert( ! has_value() ), std::move( contained.error() );
2111 error_type && error() &&
2113 return assert( ! has_value() ), std::move( contained.error() );
2118 constexpr unexpected_type get_unexpected()
const
2120 return make_unexpected( contained.error() );
2123 template<
typename Ex >
2124 bool has_exception()
const
2126 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().
value() ) >::type;
2164 template<
typename T1,
typename E1,
typename T2,
typename E2 >
2165 constexpr
bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
2167 return bool(x) != bool(y) ? false : bool(x) ==
false ? x.error() == y.error() : *x == *y;
2170 template<
typename T1,
typename E1,
typename T2,
typename E2 >
2171 constexpr
bool operator!=( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
2176 template<
typename E1,
typename E2 >
2177 constexpr
bool operator==( expected<void,E1>
const & x, expected<void,E1>
const & y )
2179 return bool(x) != bool(y) ? false : bool(x) ==
false ? x.error() == y.error() :
true;
2182 #if nsel_P0323R <= 2
2184 template<
typename T,
typename E >
2185 constexpr
bool operator<( expected<T,E>
const & x, expected<T,E>
const & y )
2187 return (!y) ? false : (!x) ?
true : *x < *y;
2190 template<
typename T,
typename E >
2191 constexpr
bool operator>( expected<T,E>
const & x, expected<T,E>
const & y )
2196 template<
typename T,
typename E >
2197 constexpr
bool operator<=( expected<T,E>
const & x, expected<T,E>
const & y )
2202 template<
typename T,
typename E >
2203 constexpr
bool operator>=( expected<T,E>
const & x, expected<T,E>
const & y )
2212 template<
typename T1,
typename E1,
typename T2 >
2213 constexpr
bool operator==( expected<T1,E1>
const & x, T2
const & v )
2215 return bool(x) ? *x == v :
false;
2218 template<
typename T1,
typename E1,
typename T2 >
2219 constexpr
bool operator==(T2
const & v, expected<T1,E1>
const & x )
2221 return bool(x) ? v == *x :
false;
2224 template<
typename T1,
typename E1,
typename T2 >
2225 constexpr
bool operator!=( expected<T1,E1>
const & x, T2
const & v )
2227 return bool(x) ? *x != v :
true;
2230 template<
typename T1,
typename E1,
typename T2 >
2231 constexpr
bool operator!=( T2
const & v, expected<T1,E1>
const & x )
2233 return bool(x) ? v != *x :
true;
2236 #if nsel_P0323R <= 2
2238 template<
typename T,
typename E >
2239 constexpr
bool operator<( expected<T,E>
const & x, T
const & v )
2241 return bool(x) ? *x < v :
true;
2244 template<
typename T,
typename E >
2245 constexpr
bool operator<( T
const & v, expected<T,E>
const & x )
2247 return bool(x) ? v < *x :
false;
2250 template<
typename T,
typename E >
2251 constexpr
bool operator>( T
const & v, expected<T,E>
const & x )
2253 return bool(x) ? *x < v :
false;
2256 template<
typename T,
typename E >
2257 constexpr
bool operator>( expected<T,E>
const & x, T
const & v )
2259 return bool(x) ? v < *x :
false;
2262 template<
typename T,
typename E >
2263 constexpr
bool operator<=( T
const & v, expected<T,E>
const & x )
2265 return bool(x) ? ! ( *x < v ) :
false;
2268 template<
typename T,
typename E >
2269 constexpr
bool operator<=( expected<T,E>
const & x, T
const & v )
2271 return bool(x) ? ! ( v < *x ) :
true;
2274 template<
typename T,
typename E >
2275 constexpr
bool operator>=( expected<T,E>
const & x, T
const & v )
2277 return bool(x) ? ! ( *x < v ) :
false;
2280 template<
typename T,
typename E >
2281 constexpr
bool operator>=( T
const & v, expected<T,E>
const & x )
2283 return bool(x) ? ! ( v < *x ) :
true;
2290 template<
typename T1,
typename E1 ,
typename E2 >
2291 constexpr
bool operator==( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
2293 return (!x) ? x.get_unexpected() == u :
false;
2296 template<
typename T1,
typename E1 ,
typename E2 >
2297 constexpr
bool operator==( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
2302 template<
typename T1,
typename E1 ,
typename E2 >
2303 constexpr
bool operator!=( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
2305 return ! ( x == u );
2308 template<
typename T1,
typename E1 ,
typename E2 >
2309 constexpr
bool operator!=( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
2311 return ! ( x == u );
2314 #if nsel_P0323R <= 2
2316 template<
typename T,
typename E >
2317 constexpr
bool operator<( expected<T,E>
const & x, unexpected_type<E>
const & u )
2319 return (!x) ? ( x.get_unexpected() < u ) :
false;
2322 template<
typename T,
typename E >
2323 constexpr
bool operator<( unexpected_type<E>
const & u, expected<T,E>
const & x )
2325 return (!x) ? ( u < x.get_unexpected() ) :
true ;
2328 template<
typename T,
typename E >
2329 constexpr
bool operator>( expected<T,E>
const & x, unexpected_type<E>
const & u )
2334 template<
typename T,
typename E >
2335 constexpr
bool operator>( unexpected_type<E>
const & u, expected<T,E>
const & x )
2340 template<
typename T,
typename E >
2341 constexpr
bool operator<=( expected<T,E>
const & x, unexpected_type<E>
const & u )
2346 template<
typename T,
typename E >
2347 constexpr
bool operator<=( unexpected_type<E>
const & u, expected<T,E>
const & x)
2352 template<
typename T,
typename E >
2353 constexpr
bool operator>=( expected<T,E>
const & x, unexpected_type<E>
const & u )
2358 template<
typename T,
typename E >
2359 constexpr
bool operator>=( unexpected_type<E>
const & u, expected<T,E>
const & x )
2368 template<
typename T,
typename E
2375 void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
2380 #if nsel_P0323R <= 3
2382 template<
typename T >
2383 constexpr
auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
2385 return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
2390 auto inline make_expected() -> expected<void>
2395 template<
typename T >
2396 constexpr
auto make_expected_from_current_exception() -> expected<T>
2398 return expected<T>( make_unexpected_from_current_exception() );
2401 template<
typename T >
2402 auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
2404 return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
2407 template<
typename T,
typename E >
2408 constexpr
auto make_expected_from_error( E
e ) -> expected<T, typename std::decay<E>::type>
2410 return expected<T, typename std::decay<E>::type>( make_unexpected(
e ) );
2413 template<
typename F
2417 auto make_expected_from_call( F
f ) -> expected<
typename std::result_of<F()>::type >
2421 return make_expected(
f() );
2425 return make_unexpected_from_current_exception();
2429 template<
typename F
2433 auto make_expected_from_call( F
f ) -> expected<void>
2438 return make_expected();
2442 return make_unexpected_from_current_exception();
2450 using namespace expected_lite;
bool operator<(const Digest32< N > &left, const Digest32< N > &right)
bool operator!=(const Digest32< N > &left, const Digest32< N > &right)
#define nsel_REQUIRES_T(...)
#define nonstd_lite_in_place( T)
#define nsel_REQUIRES_0(...)
#define nonstd_lite_in_place_t( T)
#define nsel_REQUIRES_R(R,...)
constexpr bool operator>(const Version< T, N, Mandatory > &left, const Version< T, N, Mandatory > &right)
constexpr bool operator>=(const Version< T, N, Mandatory > &left, const Version< T, N, Mandatory > &right)
constexpr bool operator<=(const Version< T, N, Mandatory > &left, const Version< T, N, Mandatory > &right)
bool operator==(const QString &s, const BoolOption &o)
T value(const QString &key, const T &defaultValue={})
in_place_t in_place(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())