12 #ifndef NONSTD_EXPECTED_LITE_HPP 13 #define NONSTD_EXPECTED_LITE_HPP 15 #define expected_lite_MAJOR 0 16 #define expected_lite_MINOR 6 17 #define expected_lite_PATCH 2 19 #define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH) 21 #define expected_STRINGIFY( x ) expected_STRINGIFY_( x ) 22 #define expected_STRINGIFY_( x ) #x 26 #define nsel_EXPECTED_DEFAULT 0 27 #define nsel_EXPECTED_NONSTD 1 28 #define nsel_EXPECTED_STD 2 33 # if __has_include(<nonstd/expected.tweak.hpp>) 34 # include <nonstd/expected.tweak.hpp> 36 #define expected_HAVE_TWEAK_HEADER 1 38 #define expected_HAVE_TWEAK_HEADER 0 44 #if !defined( nsel_CONFIG_SELECT_EXPECTED ) 45 # define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD ) 66 # define nsel_P0323R 7 71 #ifndef nsel_CONFIG_NO_EXCEPTIONS 72 # if defined(_MSC_VER) 75 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) 76 # define nsel_CONFIG_NO_EXCEPTIONS 0 78 # define nsel_CONFIG_NO_EXCEPTIONS 1 84 #ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH 85 # define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER ) 91 #ifndef nsel_CPLUSPLUS 92 # if defined(_MSVC_LANG ) && !defined(__clang__) 93 # define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) 95 # define nsel_CPLUSPLUS __cplusplus 99 #define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L ) 100 #define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L ) 101 #define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L ) 102 #define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L ) 103 #define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L ) 104 #define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L ) 108 #if nsel_CPP23_OR_GREATER && defined(__has_include ) 109 # if __has_include( <expected> ) 110 # define nsel_HAVE_STD_EXPECTED 1 112 # define nsel_HAVE_STD_EXPECTED 0 115 # define nsel_HAVE_STD_EXPECTED 0 118 #define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) ) 124 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES 125 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1 129 #if nsel_CPP17_OR_GREATER 138 using std::in_place_t;
139 using std::in_place_type_t;
140 using std::in_place_index_t;
142 #define nonstd_lite_in_place_t( T) std::in_place_t 143 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T> 144 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K> 146 #define nonstd_lite_in_place( T) std::in_place_t{} 147 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{} 148 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{} 152 #else // nsel_CPP17_OR_GREATER 162 template< std::
size_t K >
175 template< std::
size_t K >
187 template< std::
size_t K >
195 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> ) 196 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> ) 197 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> ) 199 #define nonstd_lite_in_place( T) nonstd::in_place_type<T> 200 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T> 201 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K> 205 #endif // nsel_CPP17_OR_GREATER 206 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES 212 #if nsel_USES_STD_EXPECTED 222 #else // nsel_USES_STD_EXPECTED 226 #include <functional> 227 #include <initializer_list> 230 #include <system_error> 231 #include <type_traits> 236 #if nsel_CONFIG_NO_EXCEPTIONS 237 # if nsel_CONFIG_NO_EXCEPTIONS_SEH 238 # include <windows.h> 243 # include <stdexcept> 248 #if nsel_CPP11_OR_GREATER 249 # define nsel_constexpr constexpr 251 # define nsel_constexpr 254 #if nsel_CPP14_OR_GREATER 255 # define nsel_constexpr14 constexpr 257 # define nsel_constexpr14 260 #if nsel_CPP17_OR_GREATER 261 # define nsel_inline17 inline 263 # define nsel_inline17 280 #if defined(_MSC_VER) && !defined(__clang__) 281 # define nsel_COMPILER_MSVC_VER (_MSC_VER ) 282 # define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) ) 284 # define nsel_COMPILER_MSVC_VER 0 285 # define nsel_COMPILER_MSVC_VERSION 0 288 #define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) 290 #if defined(__clang__) 291 # define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) 293 # define nsel_COMPILER_CLANG_VERSION 0 296 #if defined(__GNUC__) && !defined(__clang__) 297 # define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 299 # define nsel_COMPILER_GNUC_VERSION 0 307 #define nsel_REQUIRES_0(...) \ 308 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 > 310 #define nsel_REQUIRES_T(...) \ 311 , typename std::enable_if< (__VA_ARGS__), int >::type = 0 313 #define nsel_REQUIRES_R(R, ...) \ 314 typename std::enable_if< (__VA_ARGS__), R>::type 316 #define nsel_REQUIRES_A(...) \ 317 , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr 322 # define nsel_HAS_CPP0X _HAS_CPP0X 324 # define nsel_HAS_CPP0X 0 332 # pragma clang diagnostic push 333 #elif defined __GNUC__ 334 # pragma GCC diagnostic push 337 #if nsel_COMPILER_MSVC_VERSION >= 140 338 # pragma warning( push ) 339 # define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(disable: codes) ) 341 # define nsel_DISABLE_MSVC_WARNINGS(codes) 345 # define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") 346 #elif defined __GNUC__ 347 # define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") 348 #elif nsel_COMPILER_MSVC_VERSION >= 140 349 # define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) ) 351 # define nsel_RESTORE_WARNINGS() 363 namespace
nonstd {
namespace expected_lite {
369 #if nsel_CPP17_OR_GREATER 371 using std::conjunction;
372 using std::is_swappable;
373 using std::is_nothrow_swappable;
375 #else // nsel_CPP17_OR_GREATER 383 template<
typename T,
typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
384 static std::true_type test(
int );
387 static std::false_type test(...);
390 struct is_nothrow_swappable
394 template<
typename T >
395 static constexpr
bool satisfies()
397 return noexcept(
swap( std::declval<T&>(), std::declval<T&>() ) );
400 template<
typename T >
401 static auto test(
int ) -> std::integral_constant<bool, satisfies<T>()>{}
404 static auto test(...) -> std::false_type;
410 template<
typename T >
411 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
413 template<
typename T >
414 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
418 template<
typename... >
struct conjunction : std::true_type{};
419 template<
typename B1 >
struct conjunction<B1> : B1{};
421 template<
typename B1,
typename... Bn >
422 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
424 #endif // nsel_CPP17_OR_GREATER 432 #if defined(__cpp_lib_remove_cvref) 434 using std::remove_cvref;
438 template<
typename T >
441 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
450 template<
typename T,
typename E >
457 template<
typename T,
typename E >
460 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
463 using value_type = T;
464 using error_type = E;
470 explicit storage_t_impl(
bool has_value )
471 : m_has_value( has_value )
474 void construct_value( value_type
const & e )
476 new( &m_value ) value_type( e );
479 void construct_value( value_type && e )
481 new( &m_value ) value_type( std::move( e ) );
484 template<
class... Args >
485 void emplace_value( Args&&... args )
487 new( &m_value ) value_type( std::forward<Args>(args)...);
490 template<
class U,
class... Args >
491 void emplace_value( std::initializer_list<U> il, Args&&... args )
493 new( &m_value ) value_type( il, std::forward<Args>(args)... );
496 void destruct_value()
498 m_value.~value_type();
501 void construct_error( error_type
const & e )
503 new( &m_error ) error_type( e );
506 void construct_error( error_type && e )
508 new( &m_error ) error_type( std::move( e ) );
511 template<
class... Args >
512 void emplace_error( Args&&... args )
514 new( &m_error ) error_type( std::forward<Args>(args)...);
517 template<
class U,
class... Args >
518 void emplace_error( std::initializer_list<U> il, Args&&... args )
520 new( &m_error ) error_type( il, std::forward<Args>(args)... );
523 void destruct_error()
525 m_error.~error_type();
528 constexpr value_type
const & value()
const &
533 value_type & value() &
538 constexpr value_type
const && value()
const &&
540 return std::move( m_value );
545 return std::move( m_value );
548 value_type
const * value_ptr()
const 553 value_type * value_ptr()
558 error_type
const & error()
const &
563 error_type & error() &
568 constexpr error_type
const && error()
const &&
570 return std::move( m_error );
575 return std::move( m_error );
578 bool has_value()
const 583 void set_has_value(
bool v )
595 bool m_has_value =
false;
600 template<
typename E >
601 struct storage_t_impl<void, E>
603 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
606 using value_type = void;
607 using error_type = E;
613 explicit storage_t_impl(
bool has_value )
614 : m_has_value( has_value )
617 void construct_error( error_type
const & e )
619 new( &m_error ) error_type( e );
622 void construct_error( error_type && e )
624 new( &m_error ) error_type( std::move( e ) );
627 template<
class... Args >
628 void emplace_error( Args&&... args )
630 new( &m_error ) error_type( std::forward<Args>(args)...);
633 template<
class U,
class... Args >
634 void emplace_error( std::initializer_list<U> il, Args&&... args )
636 new( &m_error ) error_type( il, std::forward<Args>(args)... );
639 void destruct_error()
641 m_error.~error_type();
644 error_type
const & error()
const &
649 error_type & error() &
654 constexpr error_type
const && error()
const &&
656 return std::move( m_error );
661 return std::move( m_error );
664 bool has_value()
const 669 void set_has_value(
bool v )
681 bool m_has_value =
false;
684 template<
typename T,
typename E,
bool isConstructable,
bool isMoveable >
688 storage_t() =
default;
689 ~storage_t() =
default;
691 explicit storage_t(
bool has_value )
692 : storage_t_impl<T, E>( has_value )
695 storage_t( storage_t
const & other ) =
delete;
696 storage_t( storage_t && other ) =
delete;
699 template<
typename T,
typename E >
700 class storage_t<T, E, true, true> :
public storage_t_impl<T, E>
703 storage_t() =
default;
704 ~storage_t() =
default;
706 explicit storage_t(
bool has_value )
707 : storage_t_impl<T, E>( has_value )
710 storage_t( storage_t
const & other )
711 : storage_t_impl<T, E>( other.has_value() )
713 if ( this->has_value() ) this->construct_value( other.value() );
714 else this->construct_error( other.error() );
717 storage_t(storage_t && other )
718 : storage_t_impl<T, E>( other.has_value() )
720 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
721 else this->construct_error( std::move( other.error() ) );
725 template<
typename E >
726 class storage_t<void, E, true, true> :
public storage_t_impl<void, E>
729 storage_t() =
default;
730 ~storage_t() =
default;
732 explicit storage_t(
bool has_value )
733 : storage_t_impl<void, E>( has_value )
736 storage_t( storage_t
const & other )
737 : storage_t_impl<void, E>( other.has_value() )
739 if ( this->has_value() ) ;
740 else this->construct_error( other.error() );
743 storage_t(storage_t && other )
744 : storage_t_impl<void, E>( other.has_value() )
746 if ( this->has_value() ) ;
747 else this->construct_error( std::move( other.error() ) );
751 template<
typename T,
typename E >
752 class storage_t<T, E, true, false> :
public storage_t_impl<T, E>
755 storage_t() =
default;
756 ~storage_t() =
default;
758 explicit storage_t(
bool has_value )
759 : storage_t_impl<T, E>( has_value )
762 storage_t( storage_t
const & other )
763 : storage_t_impl<T, E>(other.has_value())
765 if ( this->has_value() ) this->construct_value( other.value() );
766 else this->construct_error( other.error() );
769 storage_t( storage_t && other ) =
delete;
772 template<
typename E >
773 class storage_t<void, E, true, false> :
public storage_t_impl<void, E>
776 storage_t() =
default;
777 ~storage_t() =
default;
779 explicit storage_t(
bool has_value )
780 : storage_t_impl<void, E>( has_value )
783 storage_t( storage_t
const & other )
784 : storage_t_impl<void, E>(other.has_value())
786 if ( this->has_value() ) ;
787 else this->construct_error( other.error() );
790 storage_t( storage_t && other ) =
delete;
793 template<
typename T,
typename E >
794 class storage_t<T, E, false, true> :
public storage_t_impl<T, E>
797 storage_t() =
default;
798 ~storage_t() =
default;
800 explicit storage_t(
bool has_value )
801 : storage_t_impl<T, E>( has_value )
804 storage_t( storage_t
const & other ) =
delete;
806 storage_t( storage_t && other )
807 : storage_t_impl<T, E>( other.has_value() )
809 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
810 else this->construct_error( std::move( other.error() ) );
814 template<
typename E >
815 class storage_t<void, E, false, true> :
public storage_t_impl<void, E>
818 storage_t() =
default;
819 ~storage_t() =
default;
821 explicit storage_t(
bool has_value )
822 : storage_t_impl<void, E>( has_value )
825 storage_t( storage_t
const & other ) =
delete;
827 storage_t( storage_t && other )
828 : storage_t_impl<void, E>( other.has_value() )
830 if ( this->has_value() ) ;
831 else this->construct_error( std::move( other.error() ) );
840 template<
typename E = std::exception_ptr >
841 class unexpected_type
843 template< typename E >
844 class unexpected_type
848 using error_type = E;
854 constexpr unexpected_type( unexpected_type
const & ) =
default;
855 constexpr unexpected_type( unexpected_type && ) =
default;
857 template<
typename... Args
859 std::is_constructible<E, Args&&...>::value
863 : m_error( std::forward<Args>( args )...)
866 template<
typename U,
typename... Args
868 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
871 constexpr
explicit unexpected_type(
nonstd_lite_in_place_t(E), std::initializer_list<U> il, Args &&... args )
872 : m_error( il, std::forward<Args>( args )...)
875 template<
typename E2
877 std::is_constructible<E,E2>::value
879 && !std::is_same<
typename std20::remove_cvref<E2>::type, unexpected_type >::value
882 constexpr
explicit unexpected_type( E2 && error )
883 : m_error( std::forward<E2>( error ) )
886 template<
typename E2
888 std::is_constructible< E, E2>::value
889 && !std::is_constructible<E, unexpected_type<E2> & >::value
890 && !std::is_constructible<E, unexpected_type<E2> >::value
891 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
892 && !std::is_constructible<E, unexpected_type<E2>
const >::value
893 && !std::is_convertible< unexpected_type<E2> &, E>::value
894 && !std::is_convertible< unexpected_type<E2> , E>::value
895 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
896 && !std::is_convertible< unexpected_type<E2>
const , E>::value
897 && !std::is_convertible< E2 const &, E>::value
900 constexpr
explicit unexpected_type( unexpected_type<E2>
const & error )
901 : m_error( E{ error.value() } )
904 template<
typename E2
906 std::is_constructible< E, E2>::value
907 && !std::is_constructible<E, unexpected_type<E2> & >::value
908 && !std::is_constructible<E, unexpected_type<E2> >::value
909 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
910 && !std::is_constructible<E, unexpected_type<E2>
const >::value
911 && !std::is_convertible< unexpected_type<E2> &, E>::value
912 && !std::is_convertible< unexpected_type<E2> , E>::value
913 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
914 && !std::is_convertible< unexpected_type<E2>
const , E>::value
915 && std::is_convertible< E2 const &, E>::value
918 constexpr unexpected_type( unexpected_type<E2>
const & error )
919 : m_error( error.value() )
922 template<
typename E2
924 std::is_constructible< E, E2>::value
925 && !std::is_constructible<E, unexpected_type<E2> & >::value
926 && !std::is_constructible<E, unexpected_type<E2> >::value
927 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
928 && !std::is_constructible<E, unexpected_type<E2>
const >::value
929 && !std::is_convertible< unexpected_type<E2> &, E>::value
930 && !std::is_convertible< unexpected_type<E2> , E>::value
931 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
932 && !std::is_convertible< unexpected_type<E2>
const , E>::value
933 && !std::is_convertible< E2 const &, E>::value
936 constexpr
explicit unexpected_type( unexpected_type<E2> && error )
937 : m_error( E{ std::move( error.value() ) } )
940 template<
typename E2
942 std::is_constructible< E, E2>::value
943 && !std::is_constructible<E, unexpected_type<E2> & >::value
944 && !std::is_constructible<E, unexpected_type<E2> >::value
945 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
946 && !std::is_constructible<E, unexpected_type<E2>
const >::value
947 && !std::is_convertible< unexpected_type<E2> &, E>::value
948 && !std::is_convertible< unexpected_type<E2> , E>::value
949 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
950 && !std::is_convertible< unexpected_type<E2>
const , E>::value
951 && std::is_convertible< E2 const &, E>::value
954 constexpr unexpected_type( unexpected_type<E2> && error )
955 : m_error( std::move( error.value() ) )
960 nsel_constexpr14 unexpected_type& operator=( unexpected_type
const & ) =
default;
961 nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) =
default;
963 template<
typename E2 = E >
964 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2>
const & other )
966 unexpected_type{ other.value() }.swap( *
this );
970 template<
typename E2 = E >
971 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
973 unexpected_type{ std::move( other.value() ) }.
swap( *
this );
984 constexpr E
const & value()
const & noexcept
989 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 993 return std::move( m_error );
996 constexpr E
const && value()
const && noexcept
998 return std::move( m_error );
1006 std17::is_swappable<E>::value
1008 swap( unexpected_type & other ) noexcept (
1009 std17::is_nothrow_swappable<E>::value
1013 swap( m_error, other.m_error );
1022 #if nsel_CPP17_OR_GREATER 1026 template<
typename E >
1027 unexpected_type( E ) -> unexpected_type< E >;
1033 #if !nsel_CONFIG_NO_EXCEPTIONS 1034 #if nsel_P0323R <= 2 1039 class unexpected_type< std::exception_ptr >
1042 using error_type = std::exception_ptr;
1044 unexpected_type() =
delete;
1046 ~unexpected_type(){}
1048 explicit unexpected_type( std::exception_ptr
const & error )
1052 explicit unexpected_type(std::exception_ptr && error )
1053 : m_error( std::move( error ) )
1056 template<
typename E >
1057 explicit unexpected_type( E error )
1058 : m_error( std::make_exception_ptr( error ) )
1061 std::exception_ptr
const & value()
const 1066 std::exception_ptr & value()
1072 std::exception_ptr m_error;
1075 #endif // nsel_P0323R 1076 #endif // !nsel_CONFIG_NO_EXCEPTIONS 1080 template<
typename E1,
typename E2 >
1081 constexpr
bool operator==( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1083 return x.value() == y.value();
1086 template<
typename E1,
typename E2 >
1087 constexpr
bool operator!=( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1089 return ! ( x == y );
1092 #if nsel_P0323R <= 2 1094 template<
typename E >
1095 constexpr
bool operator<( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1097 return x.value() < y.value();
1100 template<
typename E >
1101 constexpr
bool operator>( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1106 template<
typename E >
1107 constexpr
bool operator<=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1112 template<
typename E >
1113 constexpr
bool operator>=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1118 #endif // nsel_P0323R 1122 template<
typename E
1124 std17::is_swappable<E>::value
1127 void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
1132 #if nsel_P0323R <= 2 1136 inline constexpr
bool operator<( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1141 inline constexpr
bool operator>( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1146 inline constexpr
bool operator<=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1151 inline constexpr
bool operator>=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1156 #endif // nsel_P0323R 1160 #if nsel_P0323R <= 3 1162 template<
typename E>
1163 struct is_unexpected : std::false_type {};
1165 template<
typename E>
1166 struct is_unexpected< unexpected_type<E> > : std::true_type {};
1168 #endif // nsel_P0323R 1174 template<
typename E>
1176 make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
1178 return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
1181 #if nsel_P0323R <= 3 1184 make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
1186 return unexpected_type< std::exception_ptr >( std::current_exception() );
1189 #endif // nsel_P0323R 1193 template<
typename E >
1194 class bad_expected_access;
1199 class bad_expected_access< void > :
public std::exception
1202 explicit bad_expected_access()
1209 #if !nsel_CONFIG_NO_EXCEPTIONS 1211 template<
typename E >
1212 class bad_expected_access :
public bad_expected_access< void >
1215 using error_type = E;
1217 explicit bad_expected_access( error_type error )
1221 virtual char const * what()
const noexcept
override 1223 return "bad_expected_access";
1231 constexpr error_type
const & error()
const &
1236 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 1240 return std::move( m_error );
1243 constexpr error_type
const && error()
const &&
1245 return std::move( m_error );
1254 #endif // nsel_CONFIG_NO_EXCEPTIONS 1258 struct unexpect_t{};
1259 using in_place_unexpected_t = unexpect_t;
1266 #if nsel_CONFIG_NO_EXCEPTIONS 1269 inline bool text(
char const * ) {
return true; }
1272 template<
typename Error >
1275 static void rethrow( Error
const & )
1277 #if nsel_CONFIG_NO_EXCEPTIONS_SEH 1278 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1280 assert(
false && detail::text(
"throw bad_expected_access<Error>{ e };") );
1286 struct error_traits< std::exception_ptr >
1288 static void rethrow( std::exception_ptr
const & )
1290 #if nsel_CONFIG_NO_EXCEPTIONS_SEH 1291 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1293 assert(
false && detail::text(
"throw bad_expected_access<std::exception_ptr>{ e };") );
1299 struct error_traits< std::error_code >
1301 static void rethrow( std::error_code
const & )
1303 #if nsel_CONFIG_NO_EXCEPTIONS_SEH 1304 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1306 assert(
false && detail::text(
"throw std::system_error( e );") );
1311 #else // nsel_CONFIG_NO_EXCEPTIONS 1313 template<
typename Error >
1316 static void rethrow( Error
const & e )
1318 throw bad_expected_access<Error>{ e };
1323 struct error_traits< std::exception_ptr >
1325 static void rethrow( std::exception_ptr
const & e )
1327 std::rethrow_exception( e );
1332 struct error_traits< std::error_code >
1334 static void rethrow( std::error_code
const & e )
1336 throw std::system_error( e );
1340 #endif // nsel_CONFIG_NO_EXCEPTIONS 1346 using expected_lite::unexpected_type;
1348 namespace expected_lite {
1352 #if nsel_P0323R <= 2 1353 template<
typename T,
typename E = std::exception_ptr >
1356 template< typename T, typename E >
1361 template<
typename,
typename >
friend class expected;
1364 using value_type = T;
1365 using error_type = E;
1366 using unexpected_type = nonstd::unexpected_type<E>;
1368 template<
typename U >
1371 using type = expected<U, error_type>;
1377 std::is_default_constructible<T>::value
1382 contained.construct_value( value_type() );
1388 template<
typename U,
typename G
1390 std::is_constructible< T, U const &>::value
1391 && std::is_constructible<E, G const &>::value
1392 && !std::is_constructible<T, expected<U, G> & >::value
1393 && !std::is_constructible<T, expected<U, G> && >::value
1394 && !std::is_constructible<T, expected<U, G>
const & >::value
1395 && !std::is_constructible<T, expected<U, G>
const && >::value
1396 && !std::is_convertible< expected<U, G> & , T>::value
1397 && !std::is_convertible< expected<U, G> &&, T>::value
1398 && !std::is_convertible< expected<U, G>
const & , T>::value
1399 && !std::is_convertible< expected<U, G>
const &&, T>::value
1400 && (!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value )
1404 : contained( other.has_value() )
1406 if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
1407 else contained.construct_error( E{ other.contained.error() } );
1410 template<
typename U,
typename G
1412 std::is_constructible< T, U const &>::value
1413 && std::is_constructible<E, G const &>::value
1414 && !std::is_constructible<T, expected<U, G> & >::value
1415 && !std::is_constructible<T, expected<U, G> && >::value
1416 && !std::is_constructible<T, expected<U, G>
const & >::value
1417 && !std::is_constructible<T, expected<U, G>
const && >::value
1418 && !std::is_convertible< expected<U, G> & , T>::value
1419 && !std::is_convertible< expected<U, G> &&, T>::value
1420 && !std::is_convertible< expected<U, G>
const &, T>::value
1421 && !std::is_convertible< expected<U, G>
const &&, T>::value
1422 && !(!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value )
1426 : contained( other.has_value() )
1428 if ( has_value() ) contained.construct_value( other.contained.value() );
1429 else contained.construct_error( other.contained.error() );
1432 template<
typename U,
typename G
1434 std::is_constructible< T, U>::value
1435 && std::is_constructible<E, G>::value
1436 && !std::is_constructible<T, expected<U, G> & >::value
1437 && !std::is_constructible<T, expected<U, G> && >::value
1438 && !std::is_constructible<T, expected<U, G>
const & >::value
1439 && !std::is_constructible<T, expected<U, G>
const && >::value
1440 && !std::is_convertible< expected<U, G> & , T>::value
1441 && !std::is_convertible< expected<U, G> &&, T>::value
1442 && !std::is_convertible< expected<U, G>
const & , T>::value
1443 && !std::is_convertible< expected<U, G>
const &&, T>::value
1444 && (!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value )
1448 : contained( other.has_value() )
1450 if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
1451 else contained.construct_error( E{ std::move( other.contained.error() ) } );
1454 template<
typename U,
typename G
1456 std::is_constructible< T, U>::value
1457 && std::is_constructible<E, G>::value
1458 && !std::is_constructible<T, expected<U, G> & >::value
1459 && !std::is_constructible<T, expected<U, G> && >::value
1460 && !std::is_constructible<T, expected<U, G>
const & >::value
1461 && !std::is_constructible<T, expected<U, G>
const && >::value
1462 && !std::is_convertible< expected<U, G> & , T>::value
1463 && !std::is_convertible< expected<U, G> &&, T>::value
1464 && !std::is_convertible< expected<U, G>
const & , T>::value
1465 && !std::is_convertible< expected<U, G>
const &&, T>::value
1466 && !(!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value )
1470 : contained( other.has_value() )
1472 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
1473 else contained.construct_error( std::move( other.contained.error() ) );
1476 template<
typename U = T
1478 std::is_copy_constructible<U>::value
1484 contained.construct_value( value );
1487 template<
typename U = T
1489 std::is_constructible<T,U&&>::value
1491 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
1492 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
1493 && !std::is_convertible<U&&,T>::value
1498 std::is_nothrow_move_constructible<U>::value &&
1499 std::is_nothrow_move_constructible<E>::value
1503 contained.construct_value( T{ std::forward<U>( value ) } );
1506 template<
typename U = T
1508 std::is_constructible<T,U&&>::value
1510 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
1511 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
1512 && std::is_convertible<U&&,T>::value
1517 std::is_nothrow_move_constructible<U>::value &&
1518 std::is_nothrow_move_constructible<E>::value
1522 contained.construct_value( std::forward<U>( value ) );
1527 template<
typename G = E
1529 std::is_constructible<E, G const & >::value
1530 && !std::is_convertible< G const &, E>::value
1533 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G>
const & error )
1534 : contained(
false )
1536 contained.construct_error( E{ error.value() } );
1539 template<
typename G = E
1541 std::is_constructible<E, G const & >::value
1542 && std::is_convertible< G const &, E>::value
1546 : contained(
false )
1548 contained.construct_error( error.value() );
1551 template<
typename G = E
1553 std::is_constructible<E, G&& >::value
1554 && !std::is_convertible< G&&, E>::value
1558 : contained(
false )
1560 contained.construct_error( E{ std::move( error.value() ) } );
1563 template<
typename G = E
1565 std::is_constructible<E, G&& >::value
1566 && std::is_convertible< G&&, E>::value
1570 : contained(
false )
1572 contained.construct_error( std::move( error.value() ) );
1577 template<
typename... Args
1579 std::is_constructible<T, Args&&...>::value
1585 contained.emplace_value( std::forward<Args>( args )... );
1588 template<
typename U,
typename... Args
1590 std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
1596 contained.emplace_value( il, std::forward<Args>( args )... );
1601 template<
typename... Args
1603 std::is_constructible<E, Args&&...>::value
1607 : contained(
false )
1609 contained.emplace_error( std::forward<Args>( args )... );
1612 template<
typename U,
typename... Args
1614 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
1617 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
1618 : contained(
false )
1620 contained.emplace_error( il, std::forward<Args>( args )... );
1631 if ( has_value() ) contained.destruct_value();
1632 else contained.destruct_error();
1637 expected & operator=( expected
const & other )
1639 expected( other ).swap( *
this );
1643 expected & operator=( expected && other ) noexcept
1645 std::is_nothrow_move_constructible< T>::value
1646 && std::is_nothrow_move_assignable< T>::value
1647 && std::is_nothrow_move_constructible<E>::value
1648 && std::is_nothrow_move_assignable< E>::value )
1650 expected( std::move( other ) ).swap( *
this );
1654 template<
typename U
1656 !std::is_same<expected<T,E>,
typename std20::remove_cvref<U>::type>::value
1657 && std17::conjunction<std::is_scalar<T>, std::is_same<T, std::decay<U>> >::value
1658 && std::is_constructible<T ,U>::value
1659 && std::is_assignable< T&,U>::value
1660 && std::is_nothrow_move_constructible<E>::value )
1662 expected & operator=( U && value )
1664 expected( std::forward<U>( value ) ).swap( *
this );
1668 template<
typename G = E
1670 std::is_constructible<E, G const&>::value &&
1671 std::is_copy_constructible<G>::value
1672 && std::is_copy_assignable<G>::value
1675 expected & operator=( nonstd::unexpected_type<G>
const & error )
1677 expected( unexpect, error.value() ).
swap( *
this );
1681 template<
typename G = E
1683 std::is_constructible<E, G&&>::value &&
1684 std::is_move_constructible<G>::value
1685 && std::is_move_assignable<G>::value
1688 expected & operator=( nonstd::unexpected_type<G> && error )
1690 expected( unexpect, std::move( error.value() ) ).swap( *
this );
1694 template<
typename... Args
1696 std::is_nothrow_constructible<T, Args&&...>::value
1699 value_type & emplace( Args &&... args )
1705 template<
typename U,
typename... Args
1707 std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value
1710 value_type & emplace( std::initializer_list<U> il, Args &&... args )
1718 template<
typename U=T,
typename G=E >
1720 std17::is_swappable< U>::value
1721 && std17::is_swappable<G>::value
1722 && ( std::is_move_constructible<U>::value || std::is_move_constructible<G>::value )
1724 swap( expected & other ) noexcept
1726 std::is_nothrow_move_constructible<T>::value && std17::is_nothrow_swappable<T&>::value &&
1727 std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
1732 if (
bool(*
this) &&
bool(other) ) {
swap( contained.value(), other.contained.value() ); }
1733 else if ( !
bool(*
this) && ! bool(other) ) {
swap( contained.error(), other.contained.error() ); }
1734 else if (
bool(*
this) && ! bool(other) ) { error_type t( std::move( other.error() ) );
1735 other.contained.destruct_error();
1736 other.contained.construct_value( std::move( contained.value() ) );
1737 contained.destruct_value();
1738 contained.construct_error( std::move( t ) );
1739 bool has_value = contained.has_value();
1740 bool other_has_value = other.has_value();
1741 other.contained.set_has_value(has_value);
1742 contained.set_has_value(other_has_value);
1744 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
1749 constexpr value_type
const * operator ->()
const 1751 return assert( has_value() ), contained.value_ptr();
1754 value_type * operator ->()
1756 return assert( has_value() ), contained.value_ptr();
1759 constexpr value_type
const & operator *()
const &
1761 return assert( has_value() ), contained.value();
1764 value_type & operator *() &
1766 return assert( has_value() ), contained.value();
1769 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 1771 constexpr value_type
const && operator *()
const &&
1773 return std::move( ( assert( has_value() ), contained.value() ) );
1778 return std::move( ( assert( has_value() ), contained.value() ) );
1783 constexpr
explicit operator bool()
const noexcept
1788 constexpr
bool has_value()
const noexcept
1790 return contained.has_value();
1793 constexpr value_type
const & value()
const &
1796 ? ( contained.value() )
1797 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
1800 value_type & value() &
1803 ? ( contained.value() )
1804 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
1807 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 1809 constexpr value_type
const && value()
const &&
1811 return std::move( has_value()
1812 ? ( contained.value() )
1813 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
1818 return std::move( has_value()
1819 ? ( contained.value() )
1820 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
1825 constexpr error_type
const & error()
const &
1827 return assert( ! has_value() ), contained.error();
1830 error_type & error() &
1832 return assert( ! has_value() ), contained.error();
1835 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 1837 constexpr error_type
const && error()
const &&
1839 return std::move( ( assert( ! has_value() ), contained.error() ) );
1842 error_type && error() &&
1844 return std::move( ( assert( ! has_value() ), contained.error() ) );
1849 constexpr unexpected_type get_unexpected()
const 1851 return make_unexpected( contained.error() );
1854 template<
typename Ex >
1855 bool has_exception()
const 1857 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
1858 return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
1861 template<
typename U
1863 std::is_copy_constructible< T>::value
1864 && std::is_convertible<U&&, T>::value
1867 value_type value_or( U && v )
const &
1871 :
static_cast<T
>( std::forward<U>( v ) );
1874 template<
typename U
1876 std::is_move_constructible< T>::value
1877 && std::is_convertible<U&&, T>::value
1880 value_type value_or( U && v ) &&
1883 ? std::move( contained.value() )
1884 : static_cast<T>( std::forward<U>( v ) );
1923 , std::is_copy_constructible<T>::value && std::is_copy_constructible<E>::value
1924 , std::is_move_constructible<T>::value && std::is_move_constructible<E>::value
1931 template<
typename E >
1932 class expected<void, E>
1935 template<
typename,
typename >
friend class expected;
1938 using value_type = void;
1939 using error_type = E;
1940 using unexpected_type = nonstd::unexpected_type<E>;
1944 constexpr expected() noexcept
1955 template<
typename G = E
1957 !std::is_convertible<G const &, E>::value
1960 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G>
const & error )
1961 : contained(
false )
1963 contained.construct_error( E{ error.value() } );
1966 template<
typename G = E
1968 std::is_convertible<G const &, E>::value
1972 : contained(
false )
1974 contained.construct_error( error.value() );
1977 template<
typename G = E
1979 !std::is_convertible<G&&, E>::value
1983 : contained(
false )
1985 contained.construct_error( E{ std::move( error.value() ) } );
1988 template<
typename G = E
1990 std::is_convertible<G&&, E>::value
1994 : contained(
false )
1996 contained.construct_error( std::move( error.value() ) );
1999 template<
typename... Args
2001 std::is_constructible<E, Args&&...>::value
2005 : contained(
false )
2007 contained.emplace_error( std::forward<Args>( args )... );
2010 template<
typename U,
typename... Args
2012 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
2015 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
2016 : contained(
false )
2018 contained.emplace_error( il, std::forward<Args>( args )... );
2025 if ( ! has_value() )
2027 contained.destruct_error();
2033 expected & operator=( expected
const & other )
2035 expected( other ).swap( *
this );
2039 expected & operator=( expected && other ) noexcept
2041 std::is_nothrow_move_assignable<E>::value &&
2042 std::is_nothrow_move_constructible<E>::value )
2044 expected( std::move( other ) ).swap( *
this );
2050 expected().swap( *
this );
2055 template<
typename G = E >
2057 std17::is_swappable<G>::value
2058 && std::is_move_constructible<G>::value
2060 swap( expected & other ) noexcept
2062 std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
2067 if ( !
bool(*
this) && !
bool(other) ) {
swap( contained.error(), other.contained.error() ); }
2068 else if (
bool(*
this) && ! bool(other) ) { contained.construct_error( std::move( other.error() ) );
2069 bool has_value = contained.has_value();
2070 bool other_has_value = other.has_value();
2071 other.contained.set_has_value(has_value);
2072 contained.set_has_value(other_has_value);
2074 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2079 constexpr
explicit operator bool()
const noexcept
2084 constexpr
bool has_value()
const noexcept
2086 return contained.has_value();
2091 if ( ! has_value() )
2093 error_traits<error_type>::rethrow( contained.error() );
2097 constexpr error_type
const & error()
const &
2099 return assert( ! has_value() ), contained.error();
2102 error_type & error() &
2104 return assert( ! has_value() ), contained.error();
2107 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 2109 constexpr error_type
const && error()
const &&
2111 return std::move( ( assert( ! has_value() ), contained.error() ) );
2114 error_type && error() &&
2116 return std::move( ( assert( ! has_value() ), contained.error() ) );
2121 constexpr unexpected_type get_unexpected()
const 2123 return make_unexpected( contained.error() );
2126 template<
typename Ex >
2127 bool has_exception()
const 2129 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
2130 return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
2159 , std::is_copy_constructible<E>::value
2160 , std::is_move_constructible<E>::value
2167 template<
typename T1,
typename E1,
typename T2,
typename E2 >
2168 constexpr
bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
2170 return bool(x) != bool(y) ? false : bool(x) ==
false ? x.error() == y.error() : *x == *y;
2173 template<
typename T1,
typename E1,
typename T2,
typename E2 >
2174 constexpr
bool operator!=( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
2179 template<
typename E1,
typename E2 >
2180 constexpr
bool operator==( expected<void,E1>
const & x, expected<void,E1>
const & y )
2182 return bool(x) != bool(y) ? false : bool(x) ==
false ? x.error() == y.error() :
true;
2185 #if nsel_P0323R <= 2 2187 template<
typename T,
typename E >
2188 constexpr
bool operator<( expected<T,E>
const & x, expected<T,E>
const & y )
2190 return (!y) ? false : (!x) ?
true : *x < *y;
2193 template<
typename T,
typename E >
2194 constexpr
bool operator>( expected<T,E>
const & x, expected<T,E>
const & y )
2199 template<
typename T,
typename E >
2200 constexpr
bool operator<=( expected<T,E>
const & x, expected<T,E>
const & y )
2205 template<
typename T,
typename E >
2206 constexpr
bool operator>=( expected<T,E>
const & x, expected<T,E>
const & y )
2215 template<
typename T1,
typename E1,
typename T2 >
2216 constexpr
bool operator==( expected<T1,E1>
const & x, T2
const & v )
2218 return bool(x) ? *x == v :
false;
2221 template<
typename T1,
typename E1,
typename T2 >
2222 constexpr
bool operator==(T2
const & v, expected<T1,E1>
const & x )
2224 return bool(x) ? v == *x :
false;
2227 template<
typename T1,
typename E1,
typename T2 >
2228 constexpr
bool operator!=( expected<T1,E1>
const & x, T2
const & v )
2230 return bool(x) ? *x != v :
true;
2233 template<
typename T1,
typename E1,
typename T2 >
2234 constexpr
bool operator!=( T2
const & v, expected<T1,E1>
const & x )
2236 return bool(x) ? v != *x :
true;
2239 #if nsel_P0323R <= 2 2241 template<
typename T,
typename E >
2242 constexpr
bool operator<( expected<T,E>
const & x, T
const & v )
2244 return bool(x) ? *x < v :
true;
2247 template<
typename T,
typename E >
2248 constexpr
bool operator<( T const & v, expected<T,E>
const & x )
2250 return bool(x) ? v < *x :
false;
2253 template<
typename T,
typename E >
2254 constexpr
bool operator>( T
const & v, expected<T,E>
const & x )
2256 return bool(x) ? *x < v :
false;
2259 template<
typename T,
typename E >
2260 constexpr
bool operator>( expected<T,E>
const & x, T
const & v )
2262 return bool(x) ? v < *x :
false;
2265 template<
typename T,
typename E >
2266 constexpr
bool operator<=( T const & v, expected<T,E>
const & x )
2268 return bool(x) ? ! ( *x < v ) :
false;
2271 template<
typename T,
typename E >
2272 constexpr
bool operator<=( expected<T,E>
const & x, T
const & v )
2274 return bool(x) ? ! ( v < *x ) :
true;
2277 template<
typename T,
typename E >
2278 constexpr
bool operator>=( expected<T,E>
const & x, T
const & v )
2280 return bool(x) ? ! ( *x < v ) :
false;
2283 template<
typename T,
typename E >
2284 constexpr
bool operator>=( T
const & v, expected<T,E>
const & x )
2286 return bool(x) ? ! ( v < *x ) :
true;
2289 #endif // nsel_P0323R 2293 template<
typename T1,
typename E1 ,
typename E2 >
2294 constexpr
bool operator==( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
2296 return (!x) ? x.get_unexpected() == u :
false;
2299 template<
typename T1,
typename E1 ,
typename E2 >
2300 constexpr
bool operator==( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
2305 template<
typename T1,
typename E1 ,
typename E2 >
2306 constexpr
bool operator!=( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
2308 return ! ( x == u );
2311 template<
typename T1,
typename E1 ,
typename E2 >
2312 constexpr
bool operator!=( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
2314 return ! ( x == u );
2317 #if nsel_P0323R <= 2 2319 template<
typename T,
typename E >
2320 constexpr
bool operator<( expected<T,E>
const & x, unexpected_type<E>
const & u )
2322 return (!x) ? ( x.get_unexpected() < u ) :
false;
2325 template<
typename T,
typename E >
2326 constexpr
bool operator<( unexpected_type<E>
const & u, expected<T,E>
const & x )
2328 return (!x) ? ( u < x.get_unexpected() ) :
true ;
2331 template<
typename T,
typename E >
2332 constexpr
bool operator>( expected<T,E>
const & x, unexpected_type<E>
const & u )
2337 template<
typename T,
typename E >
2338 constexpr
bool operator>( unexpected_type<E>
const & u, expected<T,E>
const & x )
2343 template<
typename T,
typename E >
2344 constexpr
bool operator<=( expected<T,E>
const & x, unexpected_type<E>
const & u )
2349 template<
typename T,
typename E >
2350 constexpr
bool operator<=( unexpected_type<E>
const & u, expected<T,E>
const & x)
2355 template<
typename T,
typename E >
2356 constexpr
bool operator>=( expected<T,E>
const & x, unexpected_type<E>
const & u )
2361 template<
typename T,
typename E >
2362 constexpr
bool operator>=( unexpected_type<E>
const & u, expected<T,E>
const & x )
2367 #endif // nsel_P0323R 2371 template<
typename T,
typename E
2373 ( std::is_void<T>::value || std::is_move_constructible<T>::value )
2374 && std::is_move_constructible<E>::value
2375 && std17::is_swappable<T>::value
2376 && std17::is_swappable<E>::value )
2378 void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
2383 #if nsel_P0323R <= 3 2385 template<
typename T >
2386 constexpr
auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
2388 return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
2393 auto inline make_expected() -> expected<void>
2398 template<
typename T >
2399 constexpr
auto make_expected_from_current_exception() -> expected<T>
2401 return expected<T>( make_unexpected_from_current_exception() );
2404 template<
typename T >
2405 auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
2407 return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
2410 template<
typename T,
typename E >
2411 constexpr
auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
2413 return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
2416 template<
typename F
2417 nsel_REQUIRES_T( ! std::is_same<
typename std::result_of<F()>::type,
void>::value )
2420 auto make_expected_from_call( F f ) -> expected< typename std::result_of<F()>::type >
2424 return make_expected( f() );
2428 return make_unexpected_from_current_exception();
2432 template<
typename F
2433 nsel_REQUIRES_T( std::is_same<
typename std::result_of<F()>::type,
void>::value )
2436 auto make_expected_from_call( F f ) -> expected<void>
2441 return make_expected();
2445 return make_unexpected_from_current_exception();
2449 #endif // nsel_P0323R 2453 using namespace expected_lite;
2464 template<
typename T,
typename E >
2472 return arg ? std::hash<T>{}(*arg) :
result_type{};
2477 template<
typename T,
typename E >
2485 return arg ? std::hash<T>{}(*arg) :
result_type{};
2494 template<
typename E >
2505 #if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141 2506 template<
typename E >
2507 using unexpected = unexpected_type<E>;
2512 #undef nsel_REQUIRES 2513 #undef nsel_REQUIRES_0 2514 #undef nsel_REQUIRES_T 2518 #endif // nsel_USES_STD_EXPECTED 2520 #endif // NONSTD_EXPECTED_LITE_HPP
#define nsel_REQUIRES_R(R,...)
nonstd::expected< T &, E > argument_type
constexpr result_type operator()(argument_type const &arg) const
nonstd::expected< T, E > argument_type
void swap(linb::any &lhs, linb::any &rhs) noexcept
in_place_t in_place(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
#define nsel_REQUIRES_0(...)
bool operator>=(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
#define nsel_DISABLE_MSVC_WARNINGS(codes)
in_place_t in_place_index(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
#define nonstd_lite_in_place( T)
bool operator>(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
#define nsel_REQUIRES_T(...)
constexpr result_type operator()(argument_type const &arg) const
#define nsel_RESTORE_WARNINGS()
#define nonstd_lite_in_place_t( T)
bool operator==(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
void swap(message_t &a, message_t &b) ZMQ_NOTHROW
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
bool operator!=(const detail::socket_base &a, const detail::socket_base &b) ZMQ_NOTHROW
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())