12 #ifndef NONSTD_EXPECTED_LITE_HPP
13 #define NONSTD_EXPECTED_LITE_HPP
15 #define expected_lite_MAJOR 0
16 #define expected_lite_MINOR 8
17 #define expected_lite_PATCH 0
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
81 # define nsel_P2505R 5
86 #ifndef nsel_CONFIG_NO_EXCEPTIONS
87 # if defined(_MSC_VER)
90 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
91 # define nsel_CONFIG_NO_EXCEPTIONS 0
93 # define nsel_CONFIG_NO_EXCEPTIONS 1
99 #ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH
100 # define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER )
106 #ifndef nsel_CPLUSPLUS
107 # if defined(_MSVC_LANG ) && !defined(__clang__)
108 # define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
110 # define nsel_CPLUSPLUS __cplusplus
114 #define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L )
115 #define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L )
116 #define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L )
117 #define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L )
118 #define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L )
119 #define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L )
123 #if nsel_CPP23_OR_GREATER && defined(__has_include )
124 # if __has_include( <expected> )
125 # define nsel_HAVE_STD_EXPECTED 1
127 # define nsel_HAVE_STD_EXPECTED 0
130 # define nsel_HAVE_STD_EXPECTED 0
133 #define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) )
139 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
140 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
144 #if nsel_CPP17_OR_GREATER
153 using std::in_place_t;
154 using std::in_place_type_t;
155 using std::in_place_index_t;
157 #define nonstd_lite_in_place_t( T) std::in_place_t
158 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
159 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
161 #define nonstd_lite_in_place( T) std::in_place_t{}
162 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
163 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
167 #else // nsel_CPP17_OR_GREATER
177 template< std::
size_t K >
190 template< std::
size_t K >
202 template< std::
size_t K >
210 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
211 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
212 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
214 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
215 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
216 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
220 #endif // nsel_CPP17_OR_GREATER
221 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
227 #if nsel_USES_STD_EXPECTED
234 using std::unexpected;
235 using std::bad_expected_access;
236 using std::unexpect_t;
241 template<
typename E >
242 using unexpected_type = unexpected<E>;
246 template<
typename E>
247 constexpr
auto make_unexpected( E &&
value ) -> unexpected< typename std::decay<E>::type >
249 return unexpected< typename std::decay<E>::type >( std::forward<E>(
value) );
253 #else // nsel_USES_STD_EXPECTED
257 #include <functional>
258 #include <initializer_list>
261 #include <system_error>
262 #include <type_traits>
267 #if nsel_CONFIG_NO_EXCEPTIONS
268 # if nsel_CONFIG_NO_EXCEPTIONS_SEH
269 # include <windows.h>
274 # include <stdexcept>
279 #if nsel_CPP11_OR_GREATER
280 # define nsel_constexpr constexpr
282 # define nsel_constexpr
285 #if nsel_CPP14_OR_GREATER
286 # define nsel_constexpr14 constexpr
288 # define nsel_constexpr14
291 #if nsel_CPP17_OR_GREATER
292 # define nsel_inline17 inline
294 # define nsel_inline17
311 #if defined(_MSC_VER) && !defined(__clang__)
312 # define nsel_COMPILER_MSVC_VER (_MSC_VER )
313 # define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
315 # define nsel_COMPILER_MSVC_VER 0
316 # define nsel_COMPILER_MSVC_VERSION 0
319 #define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
321 #if defined(__clang__)
322 # define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
324 # define nsel_COMPILER_CLANG_VERSION 0
327 #if defined(__GNUC__) && !defined(__clang__)
328 # define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
330 # define nsel_COMPILER_GNUC_VERSION 0
338 #define nsel_REQUIRES_0(...) \
339 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
341 #define nsel_REQUIRES_T(...) \
342 , typename std::enable_if< (__VA_ARGS__), int >::type = 0
344 #define nsel_REQUIRES_R(R, ...) \
345 typename std::enable_if< (__VA_ARGS__), R>::type
347 #define nsel_REQUIRES_A(...) \
348 , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
353 # pragma clang diagnostic push
354 #elif defined __GNUC__
355 # pragma GCC diagnostic push
358 #if nsel_COMPILER_MSVC_VERSION >= 140
359 # define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(push) ) __pragma( warning(disable: codes) )
361 # define nsel_DISABLE_MSVC_WARNINGS(codes)
365 # define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
366 # define nsel_RESTORE_MSVC_WARNINGS()
367 #elif defined __GNUC__
368 # define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
369 # define nsel_RESTORE_MSVC_WARNINGS()
370 #elif nsel_COMPILER_MSVC_VERSION >= 140
371 # define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) )
372 # define nsel_RESTORE_MSVC_WARNINGS() nsel_RESTORE_WARNINGS()
374 # define nsel_RESTORE_WARNINGS()
375 # define nsel_RESTORE_MSVC_WARNINGS()
386 # define nsel_HAS_CPP0X _HAS_CPP0X
388 # define nsel_HAS_CPP0X 0
393 #define nsel_CPP17_000 (nsel_CPP17_OR_GREATER)
397 #define nsel_HAVE_DEPRECATED nsel_CPP17_000
401 #if nsel_HAVE_DEPRECATED
402 # define nsel_deprecated(msg) [[deprecated(msg)]]
404 # define nsel_deprecated(msg)
411 namespace nonstd {
namespace expected_lite {
417 #if nsel_CPP17_OR_GREATER
419 using std::conjunction;
420 using std::is_swappable;
421 using std::is_nothrow_swappable;
423 #else // nsel_CPP17_OR_GREATER
431 template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
432 static std::true_type test(
int );
435 static std::false_type test(...);
438 struct is_nothrow_swappable
442 template<
typename T >
443 static constexpr
bool satisfies()
445 return noexcept(
swap( std::declval<T&>(), std::declval<T&>() ) );
448 template<
typename T >
449 static auto test(
int ) -> std::integral_constant<bool, satisfies<T>()>{}
452 static auto test(...) -> std::false_type;
458 template<
typename T >
459 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
461 template<
typename T >
462 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
466 template<
typename... >
struct conjunction : std::true_type{};
467 template<
typename B1 >
struct conjunction<B1> : B1{};
469 template<
typename B1,
typename... Bn >
470 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
472 #endif // nsel_CPP17_OR_GREATER
480 #if defined(__cpp_lib_remove_cvref)
482 using std::remove_cvref;
486 template<
typename T >
489 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
498 template<
typename T,
typename E >
504 template<
typename T >
505 struct is_expected : std::false_type {};
507 template<
typename T,
typename E >
508 struct is_expected< expected< T, E > > : std::true_type {};
509 #endif // nsel_P2505R >= 3
513 template<
typename T,
typename E >
514 class storage_t_noncopy_nonmove_impl
516 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
519 using value_type = T;
520 using error_type = E;
523 storage_t_noncopy_nonmove_impl() {}
524 ~storage_t_noncopy_nonmove_impl() {}
526 explicit storage_t_noncopy_nonmove_impl(
bool has_value )
527 : m_has_value( has_value )
530 void construct_value()
532 new( &m_value ) value_type();
545 template<
class... Args >
546 void emplace_value( Args&&... args )
548 new( &m_value ) value_type( std::forward<Args>(args)...);
551 template<
class U,
class... Args >
552 void emplace_value( std::initializer_list<U> il, Args&&... args )
554 new( &m_value ) value_type( il, std::forward<Args>(args)... );
557 void destruct_value()
559 m_value.~value_type();
572 template<
class... Args >
573 void emplace_error( Args&&... args )
575 new( &m_error ) error_type( std::forward<Args>(args)...);
578 template<
class U,
class... Args >
579 void emplace_error( std::initializer_list<U> il, Args&&... args )
581 new( &m_error ) error_type( il, std::forward<Args>(args)... );
584 void destruct_error()
586 m_error.~error_type();
589 constexpr value_type
const & value()
const &
594 value_type & value() &
599 constexpr value_type
const && value()
const &&
601 return std::move( m_value );
606 return std::move( m_value );
609 value_type
const * value_ptr()
const
614 value_type * value_ptr()
619 error_type
const & error()
const &
624 error_type & error() &
629 constexpr error_type
const && error()
const &&
631 return std::move( m_error );
636 return std::move( m_error );
639 bool has_value()
const
644 void set_has_value(
bool v )
656 bool m_has_value =
false;
659 template<
typename T,
typename E >
662 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
665 using value_type = T;
666 using error_type = E;
672 explicit storage_t_impl(
bool has_value )
673 : m_has_value( has_value )
676 void construct_value()
678 new( &m_value ) value_type();
681 void construct_value( value_type
const & e )
683 new( &m_value ) value_type( e );
686 void construct_value( value_type && e )
688 new( &m_value ) value_type( std::move( e ) );
691 template<
class... Args >
692 void emplace_value( Args&&... args )
694 new( &m_value ) value_type( std::forward<Args>(args)...);
697 template<
class U,
class... Args >
698 void emplace_value( std::initializer_list<U> il, Args&&... args )
700 new( &m_value ) value_type( il, std::forward<Args>(args)... );
703 void destruct_value()
705 m_value.~value_type();
708 void construct_error( error_type
const & e )
710 new( &m_error ) error_type( e );
713 void construct_error( error_type && e )
715 new( &m_error ) error_type( std::move( e ) );
718 template<
class... Args >
719 void emplace_error( Args&&... args )
721 new( &m_error ) error_type( std::forward<Args>(args)...);
724 template<
class U,
class... Args >
725 void emplace_error( std::initializer_list<U> il, Args&&... args )
727 new( &m_error ) error_type( il, std::forward<Args>(args)... );
730 void destruct_error()
732 m_error.~error_type();
735 constexpr value_type
const & value()
const &
740 value_type & value() &
745 constexpr value_type
const && value()
const &&
747 return std::move( m_value );
752 return std::move( m_value );
755 value_type
const * value_ptr()
const
760 value_type * value_ptr()
765 error_type
const & error()
const &
770 error_type & error() &
775 constexpr error_type
const && error()
const &&
777 return std::move( m_error );
782 return std::move( m_error );
785 bool has_value()
const
790 void set_has_value(
bool v )
802 bool m_has_value =
false;
807 template<
typename E >
808 struct storage_t_impl<
void, E>
810 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
813 using value_type =
void;
814 using error_type = E;
820 explicit storage_t_impl(
bool has_value )
821 : m_has_value( has_value )
824 void construct_error( error_type
const & e )
826 new( &m_error ) error_type( e );
829 void construct_error( error_type && e )
831 new( &m_error ) error_type( std::move( e ) );
834 template<
class... Args >
835 void emplace_error( Args&&... args )
837 new( &m_error ) error_type( std::forward<Args>(args)...);
840 template<
class U,
class... Args >
841 void emplace_error( std::initializer_list<U> il, Args&&... args )
843 new( &m_error ) error_type( il, std::forward<Args>(args)... );
846 void destruct_error()
848 m_error.~error_type();
851 error_type
const & error()
const &
856 error_type & error() &
861 constexpr error_type
const && error()
const &&
863 return std::move( m_error );
868 return std::move( m_error );
871 bool has_value()
const
876 void set_has_value(
bool v )
888 bool m_has_value =
false;
891 template<
typename T,
typename E,
bool isConstructable,
bool isMoveable >
897 template<
typename T,
typename E >
898 class storage_t<T, E, false, false> :
public storage_t_noncopy_nonmove_impl<T, E>
901 storage_t() =
default;
902 ~storage_t() =
default;
904 explicit storage_t(
bool has_value )
905 : storage_t_noncopy_nonmove_impl<T, E>( has_value )
908 storage_t( storage_t
const & other ) =
delete;
909 storage_t( storage_t && other ) =
delete;
913 template<
typename T,
typename E >
914 class storage_t<T, E, true, true> :
public storage_t_impl<T, E>
917 storage_t() =
default;
918 ~storage_t() =
default;
920 explicit storage_t(
bool has_value )
921 : storage_t_impl<T, E>( has_value )
924 storage_t( storage_t
const & other )
925 : storage_t_impl<T, E>( other.has_value() )
927 if ( this->has_value() ) this->construct_value( other.value() );
928 else this->construct_error( other.error() );
931 storage_t(storage_t && other )
932 : storage_t_impl<T, E>( other.has_value() )
934 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
935 else this->construct_error( std::move( other.error() ) );
939 template<
typename E >
940 class storage_t<
void, E, true, true> :
public storage_t_impl<void, E>
943 storage_t() =
default;
944 ~storage_t() =
default;
946 explicit storage_t(
bool has_value )
947 : storage_t_impl<void, E>( has_value )
950 storage_t( storage_t
const & other )
951 : storage_t_impl<void, E>( other.has_value() )
953 if ( this->has_value() ) ;
954 else this->construct_error( other.error() );
957 storage_t(storage_t && other )
958 : storage_t_impl<void, E>( other.has_value() )
960 if ( this->has_value() ) ;
961 else this->construct_error( std::move( other.error() ) );
965 template<
typename T,
typename E >
966 class storage_t<T, E, true, false> :
public storage_t_impl<T, E>
969 storage_t() =
default;
970 ~storage_t() =
default;
972 explicit storage_t(
bool has_value )
973 : storage_t_impl<T, E>( has_value )
976 storage_t( storage_t
const & other )
977 : storage_t_impl<T, E>(other.has_value())
979 if ( this->has_value() ) this->construct_value( other.value() );
980 else this->construct_error( other.error() );
983 storage_t( storage_t && other ) =
delete;
986 template<
typename E >
987 class storage_t<
void, E, true, false> :
public storage_t_impl<void, E>
990 storage_t() =
default;
991 ~storage_t() =
default;
993 explicit storage_t(
bool has_value )
994 : storage_t_impl<void, E>( has_value )
997 storage_t( storage_t
const & other )
998 : storage_t_impl<void, E>(other.has_value())
1000 if ( this->has_value() ) ;
1001 else this->construct_error( other.error() );
1004 storage_t( storage_t && other ) =
delete;
1007 template<
typename T,
typename E >
1008 class storage_t<T, E, false, true> :
public storage_t_impl<T, E>
1011 storage_t() =
default;
1012 ~storage_t() =
default;
1014 explicit storage_t(
bool has_value )
1015 : storage_t_impl<T, E>( has_value )
1018 storage_t( storage_t
const & other ) =
delete;
1020 storage_t( storage_t && other )
1021 : storage_t_impl<T, E>( other.has_value() )
1023 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
1024 else this->construct_error( std::move( other.error() ) );
1028 template<
typename E >
1029 class storage_t<
void, E, false, true> :
public storage_t_impl<void, E>
1032 storage_t() =
default;
1033 ~storage_t() =
default;
1035 explicit storage_t(
bool has_value )
1036 : storage_t_impl<void, E>( has_value )
1039 storage_t( storage_t
const & other ) =
delete;
1041 storage_t( storage_t && other )
1042 : storage_t_impl<void, E>( other.has_value() )
1044 if ( this->has_value() ) ;
1045 else this->construct_error( std::move( other.error() ) );
1049 #if nsel_P2505R >= 3
1051 template<
typename >
1052 struct is_reference_wrapper : std::false_type {};
1053 template<
typename T >
1054 struct is_reference_wrapper<
std::reference_wrapper< T > > : std::true_type {};
1056 template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1059 && (
std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1060 || std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value )
1063 nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1064 noexcept( noexcept( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... ) ) )
1065 -> decltype( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )...) )
1067 return (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... );
1070 template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1073 && is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1076 nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1077 noexcept( noexcept( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) ) )
1078 -> decltype( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) )
1080 return (obj.get().*memfnptr)( std::forward< Args >( args ) ... );
1083 template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1086 && !
std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1087 && !std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1088 && !is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1091 nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1092 noexcept( noexcept( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) ) )
1093 -> decltype( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) )
1095 return ((*std::forward<ObjectT>(obj)).*memfnptr)( std::forward< Args >( args ) ... );
1098 template<
typename MemberT,
typename ClassT,
typename ObjectT
1100 std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1101 || std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1104 nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1105 noexcept( noexcept( std::forward< ObjectT >( obj ).*memobjptr ) )
1106 -> decltype( std::forward< ObjectT >( obj ).*memobjptr )
1108 return std::forward< ObjectT >( obj ).*memobjptr;
1111 template<
typename MemberT,
typename ClassT,
typename ObjectT
1113 is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1116 nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1117 noexcept( noexcept( obj.get().*memobjptr ) )
1118 -> decltype( obj.get().*memobjptr )
1120 return obj.get().*memobjptr;
1123 template<
typename MemberT,
typename ClassT,
typename ObjectT
1125 !
std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1126 && !std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1127 && !is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1130 nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1131 noexcept( noexcept( (*std::forward< ObjectT >( obj )).*memobjptr ) )
1132 -> decltype( (*std::forward< ObjectT >( obj )).*memobjptr )
1134 return (*std::forward< ObjectT >( obj )).*memobjptr;
1137 template<
typename F,
typename... Args
1139 std::is_member_function_pointer<
typename std20::remove_cvref< F >::type >::value
1143 noexcept( noexcept( invoke_member_function_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... ) ) )
1144 -> decltype( invoke_member_function_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... ) )
1146 return invoke_member_function_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... );
1149 template<
typename F,
typename... Args
1151 std::is_member_object_pointer<
typename std20::remove_cvref< F >::type >::value
1155 noexcept( noexcept( invoke_member_object_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... ) ) )
1156 -> decltype( invoke_member_object_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... ) )
1158 return invoke_member_object_impl( std::forward< F >(
f ), std::forward< Args >( args ) ... );
1161 template<
typename F,
typename... Args
1163 !std::is_member_function_pointer<
typename std20::remove_cvref< F >::type >::value
1164 && !std::is_member_object_pointer<
typename std20::remove_cvref< F >::type >::value
1168 noexcept( noexcept( std::forward< F >(
f )( std::forward< Args >( args ) ... ) ) )
1169 -> decltype( std::forward< F >(
f )( std::forward< Args >( args ) ... ) )
1171 return std::forward< F >(
f )( std::forward< Args >( args ) ... );
1174 template<
typename F,
typename ... Args >
1175 using invoke_result_nocvref_t =
typename std20::remove_cvref< decltype( invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
1177 #if nsel_P2505R >= 5
1178 template<
typename F,
typename ... Args >
1179 using transform_invoke_result_t =
typename std::remove_cv< decltype( invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
1181 template<
typename F,
typename ... Args >
1182 using transform_invoke_result_t = invoke_result_nocvref_t
1183 #endif // nsel_P2505R >= 5
1185 template<
typename T >
1186 struct valid_expected_value_type : std::integral_constant< bool, std::is_destructible< T >::value && !std::is_reference< T >::value && !std::is_array< T >::value > {};
1188 #endif // nsel_P2505R >= 3
1193 #if nsel_P0323R <= 2
1194 template<
typename E = std::exception_ptr >
1195 class unexpected_type
1198 class unexpected_type
1202 using error_type = E;
1208 constexpr unexpected_type( unexpected_type
const & ) =
default;
1209 constexpr unexpected_type( unexpected_type && ) =
default;
1211 template<
typename... Args
1217 : m_error( std::forward<Args>( args )...)
1220 template<
typename U,
typename... Args
1225 constexpr
explicit unexpected_type(
nonstd_lite_in_place_t(E), std::initializer_list<U> il, Args &&... args )
1226 : m_error( il, std::forward<Args>( args )...)
1229 template<
typename E2
1233 && !
std::is_same<
typename std20::remove_cvref<E2>::type, unexpected_type >::value
1236 constexpr
explicit unexpected_type( E2 && error )
1237 : m_error( std::forward<E2>( error ) )
1240 template<
typename E2
1247 && !std::is_convertible< unexpected_type<E2> &, E>::value
1248 && !std::is_convertible< unexpected_type<E2> , E>::value
1249 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1250 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1254 constexpr
explicit unexpected_type( unexpected_type<E2>
const & error )
1255 : m_error( E{ error.error() } )
1258 template<
typename E2
1265 && !std::is_convertible< unexpected_type<E2> &, E>::value
1266 && !std::is_convertible< unexpected_type<E2> , E>::value
1267 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1268 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1272 constexpr unexpected_type( unexpected_type<E2>
const & error )
1273 : m_error( error.error() )
1276 template<
typename E2
1283 && !std::is_convertible< unexpected_type<E2> &, E>::value
1284 && !std::is_convertible< unexpected_type<E2> , E>::value
1285 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1286 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1290 constexpr
explicit unexpected_type( unexpected_type<E2> && error )
1291 : m_error( E{ std::move( error.error() ) } )
1294 template<
typename E2
1301 && !std::is_convertible< unexpected_type<E2> &, E>::value
1302 && !std::is_convertible< unexpected_type<E2> , E>::value
1303 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1304 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1308 constexpr unexpected_type( unexpected_type<E2> && error )
1309 : m_error( std::move( error.error() ) )
1314 nsel_constexpr14 unexpected_type& operator=( unexpected_type
const & ) =
default;
1315 nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) =
default;
1317 template<
typename E2 = E >
1318 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2>
const & other )
1320 unexpected_type{ other.error() }.swap( *
this );
1324 template<
typename E2 = E >
1325 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
1327 unexpected_type{ std::move( other.error() ) }.swap( *
this );
1338 constexpr E
const & error()
const & noexcept
1343 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1347 return std::move( m_error );
1350 constexpr E
const && error()
const && noexcept
1352 return std::move( m_error );
1368 constexpr E
const & value()
const & noexcept
1373 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1379 return std::move( m_error );
1384 constexpr E
const && value()
const && noexcept
1386 return std::move( m_error );
1393 template<
typename U=E >
1397 swap( unexpected_type & other ) noexcept (
1402 swap( m_error, other.m_error );
1411 #if nsel_CPP17_OR_GREATER
1415 template<
typename E >
1416 unexpected_type( E ) -> unexpected_type< E >;
1422 #if !nsel_CONFIG_NO_EXCEPTIONS
1423 #if nsel_P0323R <= 2
1428 class unexpected_type<
std::exception_ptr >
1431 using error_type = std::exception_ptr;
1433 unexpected_type() =
delete;
1435 ~unexpected_type(){}
1437 explicit unexpected_type( std::exception_ptr
const & error )
1441 explicit unexpected_type(std::exception_ptr && error )
1442 : m_error( std::move( error ) )
1445 template<
typename E >
1446 explicit unexpected_type( E error )
1447 : m_error( std::make_exception_ptr( error ) )
1450 std::exception_ptr
const & value()
const
1455 std::exception_ptr & value()
1461 std::exception_ptr m_error;
1464 #endif // nsel_P0323R
1465 #endif // !nsel_CONFIG_NO_EXCEPTIONS
1469 template<
typename E1,
typename E2 >
1470 constexpr
bool operator==( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1472 return x.error() == y.error();
1475 template<
typename E1,
typename E2 >
1476 constexpr
bool operator!=( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1478 return ! ( x == y );
1481 #if nsel_P0323R <= 2
1483 template<
typename E >
1484 constexpr
bool operator<( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1486 return x.error() < y.error();
1489 template<
typename E >
1490 constexpr
bool operator>( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1495 template<
typename E >
1496 constexpr
bool operator<=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1501 template<
typename E >
1502 constexpr
bool operator>=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1507 #endif // nsel_P0323R
1511 template<
typename E
1516 void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
1521 #if nsel_P0323R <= 2
1525 inline constexpr
bool operator<( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1530 inline constexpr
bool operator>( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1535 inline constexpr
bool operator<=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1540 inline constexpr
bool operator>=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1545 #endif // nsel_P0323R
1549 #if nsel_P0323R <= 3
1551 template<
typename E>
1552 struct is_unexpected : std::false_type {};
1554 template<
typename E>
1555 struct is_unexpected< unexpected_type<E> > : std::true_type {};
1557 #endif // nsel_P0323R
1563 template<
typename E>
1565 make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
1567 return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
1570 #if nsel_P0323R <= 3
1573 make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
1575 return unexpected_type< std::exception_ptr >( std::current_exception() );
1578 #endif // nsel_P0323R
1582 template<
typename E >
1583 class bad_expected_access;
1588 class bad_expected_access<
void > :
public std::exception
1591 explicit bad_expected_access()
1598 #if !nsel_CONFIG_NO_EXCEPTIONS
1600 template<
typename E >
1601 class bad_expected_access :
public bad_expected_access< void >
1604 using error_type = E;
1606 explicit bad_expected_access( error_type error )
1610 virtual char const * what()
const noexcept
override
1612 return "bad_expected_access";
1620 constexpr error_type
const & error()
const &
1625 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1629 return std::move( m_error );
1632 constexpr error_type
const && error()
const &&
1634 return std::move( m_error );
1643 #endif // nsel_CONFIG_NO_EXCEPTIONS
1647 struct unexpect_t{};
1648 using in_place_unexpected_t = unexpect_t;
1655 #if nsel_CONFIG_NO_EXCEPTIONS
1658 inline bool text(
char const * ) {
return true; }
1661 template<
typename Error >
1664 static void rethrow( Error
const & )
1666 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1667 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1669 assert(
false && detail::text(
"throw bad_expected_access<Error>{ e };") );
1675 struct error_traits<
std::exception_ptr >
1677 static void rethrow( std::exception_ptr
const & )
1679 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1680 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1682 assert(
false && detail::text(
"throw bad_expected_access<std::exception_ptr>{ e };") );
1688 struct error_traits<
std::error_code >
1690 static void rethrow( std::error_code
const & )
1692 #if nsel_CONFIG_NO_EXCEPTIONS_SEH
1693 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1695 assert(
false && detail::text(
"throw std::system_error( e );") );
1700 #else // nsel_CONFIG_NO_EXCEPTIONS
1702 template<
typename Error >
1705 static void rethrow( Error
const & e )
1707 throw bad_expected_access<Error>{ e };
1712 struct error_traits<
std::exception_ptr >
1714 static void rethrow( std::exception_ptr
const & e )
1716 std::rethrow_exception( e );
1721 struct error_traits<
std::error_code >
1723 static void rethrow( std::error_code
const & e )
1725 throw std::system_error( e );
1729 #endif // nsel_CONFIG_NO_EXCEPTIONS
1731 #if nsel_P2505R >= 3
1736 template<
typename T >
1737 struct valid_unexpected_type : std::integral_constant< bool,
1738 std::is_same< T, typename std20::remove_cvref< T >::type >::value
1739 && std::is_object< T >::value
1740 && !std::is_array< T >::value
1743 template<
typename T >
1744 struct valid_unexpected_type< unexpected_type< T > > : std::false_type {};
1747 #endif // nsel_P2505R >= 3
1753 using expected_lite::unexpected_type;
1755 namespace expected_lite {
1759 #if nsel_P0323R <= 2
1760 template<
typename T,
typename E = std::exception_ptr >
1768 template<
typename,
typename >
friend class expected;
1771 using value_type = T;
1772 using error_type = E;
1773 using unexpected_type = nonstd::unexpected_type<E>;
1775 template<
typename U >
1778 using type = expected<U, error_type>;
1789 contained.construct_value();
1795 template<
typename U,
typename G
1803 && !std::is_convertible< expected<U, G> & , T>::value
1804 && !std::is_convertible< expected<U, G> &&, T>::value
1805 && !std::is_convertible< expected<U, G>
const & , T>::value
1806 && !std::is_convertible< expected<U, G>
const &&, T>::value
1811 : contained( other.has_value() )
1813 if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
1814 else contained.construct_error( E{ other.contained.error() } );
1817 template<
typename U,
typename G
1825 && !std::is_convertible< expected<U, G> & , T>::value
1826 && !std::is_convertible< expected<U, G> &&, T>::value
1827 && !std::is_convertible< expected<U, G>
const &, T>::value
1828 && !std::is_convertible< expected<U, G>
const &&, T>::value
1833 : contained( other.has_value() )
1835 if ( has_value() ) contained.construct_value( other.contained.value() );
1836 else contained.construct_error( other.contained.error() );
1839 template<
typename U,
typename G
1847 && !std::is_convertible< expected<U, G> & , T>::value
1848 && !std::is_convertible< expected<U, G> &&, T>::value
1849 && !std::is_convertible< expected<U, G>
const & , T>::value
1850 && !std::is_convertible< expected<U, G>
const &&, T>::value
1855 : contained( other.has_value() )
1857 if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
1858 else contained.construct_error( E{ std::move( other.contained.error() ) } );
1861 template<
typename U,
typename G
1869 && !std::is_convertible< expected<U, G> & , T>::value
1870 && !std::is_convertible< expected<U, G> &&, T>::value
1871 && !std::is_convertible< expected<U, G>
const & , T>::value
1872 && !std::is_convertible< expected<U, G>
const &&, T>::value
1877 : contained( other.has_value() )
1879 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
1880 else contained.construct_error( std::move( other.contained.error() ) );
1883 template<
typename U = T
1891 contained.construct_value( value );
1894 template<
typename U = T
1898 && !
std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
1899 && !
std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
1910 contained.construct_value( T{ std::forward<U>( value ) } );
1913 template<
typename U = T
1917 && !
std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
1918 && !
std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
1929 contained.construct_value( std::forward<U>( value ) );
1934 template<
typename G = E
1940 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G>
const & error )
1941 : contained(
false )
1943 contained.construct_error( E{ error.error() } );
1946 template<
typename G = E
1953 : contained(
false )
1955 contained.construct_error( error.error() );
1958 template<
typename G = E
1965 : contained(
false )
1967 contained.construct_error( E{ std::move( error.error() ) } );
1970 template<
typename G = E
1977 : contained(
false )
1979 contained.construct_error( std::move( error.error() ) );
1984 template<
typename... Args
1992 contained.emplace_value( std::forward<Args>( args )... );
1995 template<
typename U,
typename... Args
2003 contained.emplace_value( il, std::forward<Args>( args )... );
2008 template<
typename... Args
2014 : contained(
false )
2016 contained.emplace_error( std::forward<Args>( args )... );
2019 template<
typename U,
typename... Args
2024 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
2025 : contained(
false )
2027 contained.emplace_error( il, std::forward<Args>( args )... );
2038 if ( has_value() ) contained.destruct_value();
2039 else contained.destruct_error();
2044 expected & operator=( expected
const & other )
2046 expected( other ).swap( *
this );
2050 expected & operator=( expected && other ) noexcept
2057 expected( std::move( other ) ).swap( *
this );
2061 template<
typename U
2063 !
std::is_same<expected<T,E>,
typename std20::remove_cvref<U>::type>::value
2064 && std17::conjunction<std::is_scalar<T>,
std::is_same<T, std::decay<U>> >::value
2069 expected & operator=( U && value )
2071 expected( std::forward<U>( value ) ).swap( *
this );
2075 template<
typename G = E
2082 expected & operator=( nonstd::unexpected_type<G>
const & error )
2084 expected( unexpect, error.error() ).swap( *
this );
2088 template<
typename G = E
2095 expected & operator=( nonstd::unexpected_type<G> && error )
2097 expected( unexpect, std::move( error.error() ) ).swap( *
this );
2101 template<
typename... Args
2106 value_type & emplace( Args &&... args )
2112 template<
typename U,
typename... Args
2114 std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value
2117 value_type & emplace( std::initializer_list<U> il, Args &&... args )
2125 template<
typename U=T,
typename G=E >
2131 swap( expected & other ) noexcept
2139 if (
bool(*
this) &&
bool(other) ) {
swap( contained.value(), other.contained.value() ); }
2140 else if ( !
bool(*
this) && !
bool(other) ) {
swap( contained.error(), other.contained.error() ); }
2141 else if (
bool(*
this) && !
bool(other) ) { error_type t( std::move( other.error() ) );
2142 other.contained.destruct_error();
2143 other.contained.construct_value( std::move( contained.value() ) );
2144 contained.destruct_value();
2145 contained.construct_error( std::move( t ) );
2146 bool has_value = contained.has_value();
2147 bool other_has_value = other.has_value();
2148 other.contained.set_has_value(has_value);
2149 contained.set_has_value(other_has_value);
2151 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2156 constexpr value_type
const * operator ->()
const
2158 return assert( has_value() ), contained.value_ptr();
2161 value_type * operator ->()
2163 return assert( has_value() ), contained.value_ptr();
2166 constexpr value_type
const & operator *()
const &
2168 return assert( has_value() ), contained.value();
2171 value_type & operator *() &
2173 return assert( has_value() ), contained.value();
2176 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2178 constexpr value_type
const && operator *()
const &&
2180 return std::move( ( assert( has_value() ), contained.value() ) );
2185 return std::move( ( assert( has_value() ), contained.value() ) );
2190 constexpr
explicit operator bool()
const noexcept
2195 constexpr
bool has_value()
const noexcept
2197 return contained.has_value();
2202 constexpr value_type
const & value()
const &
2205 ? ( contained.value() )
2206 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
2209 value_type & value() &
2212 ? ( contained.value() )
2213 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
2217 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2219 constexpr value_type
const && value()
const &&
2221 return std::move( has_value()
2222 ? ( contained.value() )
2223 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
2228 return std::move( has_value()
2229 ? ( contained.value() )
2230 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
2235 constexpr error_type
const & error()
const &
2237 return assert( ! has_value() ), contained.error();
2240 error_type & error() &
2242 return assert( ! has_value() ), contained.error();
2245 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2247 constexpr error_type
const && error()
const &&
2249 return std::move( ( assert( ! has_value() ), contained.error() ) );
2252 error_type && error() &&
2254 return std::move( ( assert( ! has_value() ), contained.error() ) );
2259 constexpr unexpected_type get_unexpected()
const
2261 return make_unexpected( contained.error() );
2264 template<
typename Ex >
2265 bool has_exception()
const
2267 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
2271 template<
typename U
2277 value_type value_or( U && v )
const &
2281 :
static_cast<T
>( std::forward<U>( v ) );
2284 template<
typename U
2290 value_type value_or( U && v ) &&
2293 ? std::move( contained.value() )
2294 :
static_cast<T
>( std::forward<U>( v ) );
2297 #if nsel_P2505R >= 4
2298 template<
typename G = E
2307 ?
static_cast< E
>( std::forward< G >( e ) )
2308 : contained.error();
2311 template<
typename G = E
2320 ?
static_cast< E
>( std::forward< G >( e ) )
2321 : std::move( contained.error() );
2323 #endif // nsel_P2505R >= 4
2325 #if nsel_P2505R >= 3
2327 template<
typename F
2329 detail::is_expected < detail::invoke_result_nocvref_t< F, value_type & > > ::value
2330 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, value_type & >::error_type, error_type >::value
2334 nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type & > and_then( F &&
f ) &
2337 ? detail::invoke_result_nocvref_t< F, value_type & >(
detail::invoke( std::forward< F >(
f ), value() ) )
2338 : detail::invoke_result_nocvref_t< F, value_type & >( unexpect, error() );
2343 detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type & > >::value
2344 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
2348 nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type & > and_then( F &&
f )
const &
2351 ? detail::invoke_result_nocvref_t< F, const value_type & >(
detail::invoke( std::forward< F >(
f ), value() ) )
2352 : detail::invoke_result_nocvref_t< F, const value_type & >( unexpect, error() );
2355 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2358 detail::is_expected< detail::invoke_result_nocvref_t< F, value_type && > >::value
2359 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, value_type && >::error_type, error_type >::value
2363 nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type && > and_then( F &&
f ) &&
2366 ? detail::invoke_result_nocvref_t< F, value_type && >(
detail::invoke( std::forward< F >(
f ), std::move( value() ) ) )
2367 : detail::invoke_result_nocvref_t< F, value_type && >( unexpect, std::move( error() ) );
2372 detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type && > >::value
2373 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
2377 nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type && > and_then( F &&
f )
const &&
2380 ? detail::invoke_result_nocvref_t< F, const value_type && >(
detail::invoke( std::forward< F >(
f ), std::move( value() ) ) )
2381 : detail::invoke_result_nocvref_t< F, const value_type && >( unexpect, std::move( error() ) );
2387 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::value
2388 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, error_type & >::value_type, value_type >::value
2392 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F &&
f ) &
2395 ? detail::invoke_result_nocvref_t< F, error_type & >( value() )
2396 : detail::invoke_result_nocvref_t< F, error_type & >(
detail::invoke( std::forward< F >(
f ), error() ) );
2401 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::value
2402 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type, value_type >::value
2406 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F &&
f )
const &
2409 ? detail::invoke_result_nocvref_t< F, const error_type & >( value() )
2410 : detail::invoke_result_nocvref_t< F, const error_type & >(
detail::invoke( std::forward< F >(
f ), error() ) );
2413 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2416 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::value
2417 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, error_type && >::value_type, value_type >::value
2421 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F &&
f ) &&
2424 ? detail::invoke_result_nocvref_t< F, error_type && >( std::move( value() ) )
2425 : detail::invoke_result_nocvref_t< F, error_type && >(
detail::invoke( std::forward< F >(
f ), std::move( error() ) ) );
2430 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::value
2431 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type, value_type >::value
2435 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F &&
f )
const &&
2438 ? detail::invoke_result_nocvref_t< F, const error_type && >( std::move( value() ) )
2439 : detail::invoke_result_nocvref_t< F, const error_type && >(
detail::invoke( std::forward< F >(
f ), std::move( error() ) ) );
2446 && !std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
2447 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type & > >::value
2450 nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type & >, error_type > transform( F &&
f ) &
2453 ? expected< detail::transform_invoke_result_t< F, value_type & >, error_type >(
detail::invoke( std::forward< F >(
f ), **
this ) )
2454 : make_unexpected( error() );
2460 && std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
2466 ? (
detail::invoke( std::forward< F >(
f ), **
this ), expected< void, error_type >() )
2467 : make_unexpected( error() );
2473 && !std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
2474 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type & > >::value
2477 nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type & >, error_type > transform( F &&
f )
const &
2480 ? expected< detail::transform_invoke_result_t< F, const value_type & >, error_type >(
detail::invoke( std::forward< F >(
f ), **
this ) )
2481 : make_unexpected( error() );
2487 && std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
2490 nsel_constexpr expected< void, error_type > transform( F &&
f )
const &
2493 ? (
detail::invoke( std::forward< F >(
f ), **
this ), expected< void, error_type >() )
2494 : make_unexpected( error() );
2497 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2501 && !std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
2502 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type && > >::value
2505 nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type && >, error_type > transform( F &&
f ) &&
2508 ? expected< detail::transform_invoke_result_t< F, value_type && >, error_type >(
detail::invoke( std::forward< F >(
f ), std::move( **
this ) ) )
2509 : make_unexpected( std::move( error() ) );
2515 && std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
2521 ? (
detail::invoke( std::forward< F >(
f ), **
this ), expected< void, error_type >() )
2522 : make_unexpected( std::move( error() ) );
2528 && !std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
2529 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type && > >::value
2532 nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type && >, error_type > transform( F &&
f )
const &&
2535 ? expected< detail::transform_invoke_result_t< F, const value_type && >, error_type >(
detail::invoke( std::forward< F >(
f ), std::move( **
this ) ) )
2536 : make_unexpected( std::move( error() ) );
2542 && std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
2545 nsel_constexpr expected< void, error_type > transform( F &&
f )
const &&
2548 ? (
detail::invoke( std::forward< F >(
f ), **
this ), expected< void, error_type >() )
2549 : make_unexpected( std::move( error() ) );
2555 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::value
2559 nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type & > > transform_error( F &&
f ) &
2562 ? expected< value_type, detail::transform_invoke_result_t< F, error_type & > >(
in_place, **this )
2563 : make_unexpected(
detail::invoke( std::forward< F >(
f ), error() ) );
2568 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::value
2572 nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F &&
f )
const &
2575 ? expected< value_type, detail::transform_invoke_result_t< F, const error_type & > >(
in_place, **this )
2576 : make_unexpected(
detail::invoke( std::forward< F >(
f ), error() ) );
2579 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2582 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::value
2586 nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type && > > transform_error( F &&
f ) &&
2589 ? expected< value_type, detail::transform_invoke_result_t< F, error_type && > >(
in_place, std::move( **
this ) )
2590 : make_unexpected(
detail::invoke( std::forward< F >(
f ), std::move( error() ) ) );
2595 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::value
2599 nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F &&
f )
const &&
2602 ? expected< value_type, detail::transform_invoke_result_t< F, const error_type && > >(
in_place, std::move( **
this ) )
2603 : make_unexpected(
detail::invoke( std::forward< F >(
f ), std::move( error() ) ) );
2606 #endif // nsel_P2505R >= 3
2651 template<
typename E >
2652 class expected<
void, E>
2655 template<
typename,
typename >
friend class expected;
2658 using value_type =
void;
2659 using error_type = E;
2660 using unexpected_type = nonstd::unexpected_type<E>;
2664 constexpr expected() noexcept
2675 template<
typename G = E
2681 : contained(
false )
2683 contained.construct_error( E{
error.error() } );
2686 template<
typename G = E
2692 : contained(
false )
2694 contained.construct_error(
error.error() );
2697 template<
typename G = E
2703 : contained(
false )
2705 contained.construct_error( E{ std::move(
error.error() ) } );
2708 template<
typename G = E
2714 : contained(
false )
2716 contained.construct_error( std::move(
error.error() ) );
2719 template<
typename... Args
2725 : contained(
false )
2727 contained.emplace_error( std::forward<Args>( args )... );
2730 template<
typename U,
typename... Args
2735 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
2736 : contained(
false )
2738 contained.emplace_error( il, std::forward<Args>( args )... );
2745 if ( ! has_value() )
2747 contained.destruct_error();
2753 expected & operator=( expected
const & other )
2755 expected( other ).swap( *
this );
2759 expected & operator=( expected && other ) noexcept
2764 expected( std::move( other ) ).swap( *
this );
2770 expected().swap( *
this );
2775 template<
typename G = E >
2780 swap( expected & other ) noexcept
2787 if ( !
bool(*
this) && !
bool(other) ) {
swap( contained.error(), other.contained.error() ); }
2788 else if (
bool(*
this) && !
bool(other) ) { contained.construct_error( std::move( other.error() ) );
2789 bool has_value = contained.has_value();
2790 bool other_has_value = other.has_value();
2791 other.contained.set_has_value(has_value);
2792 contained.set_has_value(other_has_value);
2794 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2799 constexpr
explicit operator bool()
const noexcept
2804 constexpr
bool has_value()
const noexcept
2806 return contained.has_value();
2811 if ( ! has_value() )
2813 error_traits<error_type>::rethrow( contained.error() );
2817 constexpr error_type
const &
error()
const &
2819 return assert( ! has_value() ), contained.error();
2822 error_type &
error() &
2824 return assert( ! has_value() ), contained.error();
2827 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2829 constexpr error_type
const &&
error()
const &&
2831 return std::move( ( assert( ! has_value() ), contained.error() ) );
2834 error_type &&
error() &&
2836 return std::move( ( assert( ! has_value() ), contained.error() ) );
2841 constexpr unexpected_type get_unexpected()
const
2843 return make_unexpected( contained.error() );
2846 template<
typename Ex >
2847 bool has_exception()
const
2849 using ContainedEx =
typename std::remove_reference< decltype( get_unexpected().
value() ) >::type;
2853 #if nsel_P2505R >= 4
2854 template<
typename G = E
2863 ?
static_cast< E
>( std::forward< G >( e ) )
2864 : contained.error();
2867 template<
typename G = E
2876 ?
static_cast< E
>( std::forward< G >( e ) )
2877 : std::move( contained.error() );
2879 #endif // nsel_P2505R >= 4
2881 #if nsel_P2505R >= 3
2885 detail::is_expected< detail::invoke_result_nocvref_t< F > >::
value
2886 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::
value
2893 ? detail::invoke_result_nocvref_t< F >(
detail::invoke( std::forward< F >(
f ) ) )
2894 : detail::invoke_result_nocvref_t< F >( unexpect,
error() );
2899 detail::is_expected< detail::invoke_result_nocvref_t< F > >::
value
2900 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::
value
2904 nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F &&
f )
const &
2907 ? detail::invoke_result_nocvref_t< F >(
detail::invoke( std::forward< F >(
f ) ) )
2908 : detail::invoke_result_nocvref_t< F >( unexpect,
error() );
2911 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2914 detail::is_expected< detail::invoke_result_nocvref_t< F > >::
value
2915 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::
value
2922 ? detail::invoke_result_nocvref_t< F >(
detail::invoke( std::forward< F >(
f ) ) )
2923 : detail::invoke_result_nocvref_t< F >( unexpect, std::move(
error() ) );
2928 detail::is_expected< detail::invoke_result_nocvref_t< F > >::
value
2929 &&
std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::
value
2933 nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F &&
f )
const &&
2936 ? detail::invoke_result_nocvref_t< F >(
detail::invoke( std::forward< F >(
f ) ) )
2937 : detail::invoke_result_nocvref_t< F >( unexpect, std::move(
error() ) );
2943 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::
value
2944 && std::is_void<
typename detail::invoke_result_nocvref_t< F, error_type & >::value_type >::
value
2947 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F &&
f ) &
2950 ? detail::invoke_result_nocvref_t< F, error_type & >()
2951 : detail::invoke_result_nocvref_t< F, error_type & >(
detail::invoke( std::forward< F >(
f ),
error() ) );
2956 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::
value
2957 && std::is_void<
typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type >::
value
2960 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F &&
f )
const &
2963 ? detail::invoke_result_nocvref_t< F, const error_type & >()
2964 : detail::invoke_result_nocvref_t< F, const error_type & >(
detail::invoke( std::forward< F >(
f ),
error() ) );
2967 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2970 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::
value
2971 && std::is_void<
typename detail::invoke_result_nocvref_t< F, error_type && >::value_type >::
value
2974 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F &&
f ) &&
2977 ? detail::invoke_result_nocvref_t< F, error_type && >()
2978 : detail::invoke_result_nocvref_t< F, error_type && >(
detail::invoke( std::forward< F >(
f ), std::move(
error() ) ) );
2983 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::
value
2984 && std::is_void<
typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type >::
value
2987 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F &&
f )
const &&
2990 ? detail::invoke_result_nocvref_t< F, const error_type && >()
2991 : detail::invoke_result_nocvref_t< F, const error_type && >(
detail::invoke( std::forward< F >(
f ), std::move(
error() ) ) );
2998 && !std::is_void< detail::transform_invoke_result_t< F > >::
value
3001 nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F &&
f ) &
3004 ? expected< detail::transform_invoke_result_t< F >, error_type >(
detail::invoke( std::forward< F >(
f ) ) )
3005 : make_unexpected(
error() );
3011 && std::is_void< detail::transform_invoke_result_t< F > >::
value
3017 ? (
detail::invoke( std::forward< F >(
f ) ), expected< void, error_type >() )
3018 : make_unexpected(
error() );
3024 && !std::is_void< detail::transform_invoke_result_t< F > >::
value
3027 nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F &&
f )
const &
3030 ? expected< detail::transform_invoke_result_t< F >, error_type >(
detail::invoke( std::forward< F >(
f ) ) )
3031 : make_unexpected(
error() );
3037 && std::is_void< detail::transform_invoke_result_t< F > >::
value
3040 nsel_constexpr expected< void, error_type > transform( F &&
f )
const &
3043 ? (
detail::invoke( std::forward< F >(
f ) ), expected< void, error_type >() )
3044 : make_unexpected(
error() );
3047 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
3051 && !std::is_void< detail::transform_invoke_result_t< F > >::
value
3054 nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F &&
f ) &&
3057 ? expected< detail::transform_invoke_result_t< F >, error_type >(
detail::invoke( std::forward< F >(
f ) ) )
3058 : make_unexpected(
error() );
3064 && std::is_void< detail::transform_invoke_result_t< F > >::
value
3070 ? (
detail::invoke( std::forward< F >(
f ) ), expected< void, error_type >() )
3071 : make_unexpected(
error() );
3077 && !std::is_void< detail::transform_invoke_result_t< F > >::
value
3080 nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F &&
f )
const &&
3083 ? expected< detail::transform_invoke_result_t< F >, error_type >(
detail::invoke( std::forward< F >(
f ) ) )
3084 : make_unexpected(
error() );
3090 && std::is_void< detail::transform_invoke_result_t< F > >::
value
3093 nsel_constexpr expected< void, error_type > transform( F &&
f )
const &&
3096 ? (
detail::invoke( std::forward< F >(
f ) ), expected< void, error_type >() )
3097 : make_unexpected(
error() );
3103 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::
value
3106 nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type & > > transform_error( F &&
f ) &
3109 ? expected< void, detail::transform_invoke_result_t< F, error_type & > >()
3115 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::
value
3118 nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F &&
f )
const &
3121 ? expected< void, detail::transform_invoke_result_t< F, const error_type & > >()
3125 #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
3128 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::
value
3131 nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type && > > transform_error( F &&
f ) &&
3134 ? expected< void, detail::transform_invoke_result_t< F, error_type && > >()
3140 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::
value
3143 nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F &&
f )
const &&
3146 ? expected< void, detail::transform_invoke_result_t< F, const error_type && > >()
3150 #endif // nsel_P2505R >= 3
3186 template<
typename T1,
typename E1,
typename T2,
typename E2
3191 constexpr
bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3193 return bool(x) != bool(y) ? false : bool(x) ? *x == *y : x.error() == y.error();
3196 template<
typename T1,
typename E1,
typename T2,
typename E2
3201 constexpr
bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3203 return bool(x) != bool(y) ? false : bool(x) ||
static_cast<bool>( x.error() == y.error() );
3206 template<
typename T1,
typename E1,
typename T2,
typename E2 >
3207 constexpr
bool operator!=( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3212 #if nsel_P0323R <= 2
3214 template<
typename T,
typename E >
3215 constexpr
bool operator<( expected<T,E>
const & x, expected<T,E>
const & y )
3217 return (!y) ? false : (!x) ?
true : *x < *y;
3220 template<
typename T,
typename E >
3221 constexpr
bool operator>( expected<T,E>
const & x, expected<T,E>
const & y )
3226 template<
typename T,
typename E >
3227 constexpr
bool operator<=( expected<T,E>
const & x, expected<T,E>
const & y )
3232 template<
typename T,
typename E >
3233 constexpr
bool operator>=( expected<T,E>
const & x, expected<T,E>
const & y )
3242 template<
typename T1,
typename E1,
typename T2
3247 constexpr
bool operator==( expected<T1,E1>
const & x, T2
const & v )
3249 return bool(x) ? *x == v :
false;
3252 template<
typename T1,
typename E1,
typename T2
3257 constexpr
bool operator==(T2
const & v, expected<T1,E1>
const & x )
3259 return bool(x) ? v == *x :
false;
3262 template<
typename T1,
typename E1,
typename T2 >
3263 constexpr
bool operator!=( expected<T1,E1>
const & x, T2
const & v )
3265 return bool(x) ? *x != v :
true;
3268 template<
typename T1,
typename E1,
typename T2 >
3269 constexpr
bool operator!=( T2
const & v, expected<T1,E1>
const & x )
3271 return bool(x) ? v != *x :
true;
3274 #if nsel_P0323R <= 2
3276 template<
typename T,
typename E >
3277 constexpr
bool operator<( expected<T,E>
const & x, T
const & v )
3279 return bool(x) ? *x < v :
true;
3282 template<
typename T,
typename E >
3283 constexpr
bool operator<( T
const & v, expected<T,E>
const & x )
3285 return bool(x) ? v < *x :
false;
3288 template<
typename T,
typename E >
3289 constexpr
bool operator>( T
const & v, expected<T,E>
const & x )
3291 return bool(x) ? *x < v :
false;
3294 template<
typename T,
typename E >
3295 constexpr
bool operator>( expected<T,E>
const & x, T
const & v )
3297 return bool(x) ? v < *x :
false;
3300 template<
typename T,
typename E >
3301 constexpr
bool operator<=( T
const & v, expected<T,E>
const & x )
3303 return bool(x) ? ! ( *x < v ) :
false;
3306 template<
typename T,
typename E >
3307 constexpr
bool operator<=( expected<T,E>
const & x, T
const & v )
3309 return bool(x) ? ! ( v < *x ) :
true;
3312 template<
typename T,
typename E >
3313 constexpr
bool operator>=( expected<T,E>
const & x, T
const & v )
3315 return bool(x) ? ! ( *x < v ) :
false;
3318 template<
typename T,
typename E >
3319 constexpr
bool operator>=( T
const & v, expected<T,E>
const & x )
3321 return bool(x) ? ! ( v < *x ) :
true;
3324 #endif // nsel_P0323R
3328 template<
typename T1,
typename E1 ,
typename E2 >
3329 constexpr
bool operator==( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
3331 return (!x) ? x.get_unexpected() == u :
false;
3334 template<
typename T1,
typename E1 ,
typename E2 >
3335 constexpr
bool operator==( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
3340 template<
typename T1,
typename E1 ,
typename E2 >
3341 constexpr
bool operator!=( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
3343 return ! ( x == u );
3346 template<
typename T1,
typename E1 ,
typename E2 >
3347 constexpr
bool operator!=( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
3349 return ! ( x == u );
3352 #if nsel_P0323R <= 2
3354 template<
typename T,
typename E >
3355 constexpr
bool operator<( expected<T,E>
const & x, unexpected_type<E>
const & u )
3357 return (!x) ? ( x.get_unexpected() < u ) :
false;
3360 template<
typename T,
typename E >
3361 constexpr
bool operator<( unexpected_type<E>
const & u, expected<T,E>
const & x )
3363 return (!x) ? ( u < x.get_unexpected() ) :
true ;
3366 template<
typename T,
typename E >
3367 constexpr
bool operator>( expected<T,E>
const & x, unexpected_type<E>
const & u )
3372 template<
typename T,
typename E >
3373 constexpr
bool operator>( unexpected_type<E>
const & u, expected<T,E>
const & x )
3378 template<
typename T,
typename E >
3379 constexpr
bool operator<=( expected<T,E>
const & x, unexpected_type<E>
const & u )
3384 template<
typename T,
typename E >
3385 constexpr
bool operator<=( unexpected_type<E>
const & u, expected<T,E>
const & x)
3390 template<
typename T,
typename E >
3391 constexpr
bool operator>=( expected<T,E>
const & x, unexpected_type<E>
const & u )
3396 template<
typename T,
typename E >
3397 constexpr
bool operator>=( unexpected_type<E>
const & u, expected<T,E>
const & x )
3402 #endif // nsel_P0323R
3406 template<
typename T,
typename E
3413 void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
3418 #if nsel_P0323R <= 3
3420 template<
typename T >
3421 constexpr
auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
3423 return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
3428 auto inline make_expected() -> expected<void>
3433 template<
typename T >
3434 constexpr
auto make_expected_from_current_exception() -> expected<T>
3436 return expected<T>( make_unexpected_from_current_exception() );
3439 template<
typename T >
3440 auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
3442 return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
3445 template<
typename T,
typename E >
3446 constexpr
auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
3448 return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
3451 template<
typename F
3455 auto make_expected_from_call( F
f ) -> expected<
typename std::result_of<F()>::type >
3459 return make_expected(
f() );
3463 return make_unexpected_from_current_exception();
3467 template<
typename F
3471 auto make_expected_from_call( F
f ) -> expected<void>
3476 return make_expected();
3480 return make_unexpected_from_current_exception();
3484 #endif // nsel_P0323R
3488 using namespace expected_lite;
3499 template<
typename T,
typename E >
3507 return arg ? std::hash<T>{}(*arg) :
result_type{};
3512 template<
typename T,
typename E >
3520 return arg ? std::hash<T>{}(*arg) :
result_type{};
3529 template<
typename E >
3540 #if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141
3541 template<
typename E >
3542 using unexpected = unexpected_type<E>;
3547 #undef nsel_REQUIRES
3548 #undef nsel_REQUIRES_0
3549 #undef nsel_REQUIRES_T
3553 #endif // nsel_USES_STD_EXPECTED
3555 #endif // NONSTD_EXPECTED_LITE_HPP