13#ifndef NONSTD_EXPECTED_LITE_HPP
14#define NONSTD_EXPECTED_LITE_HPP
16#define expected_lite_MAJOR 0
17#define expected_lite_MINOR 9
18#define expected_lite_PATCH 0
20#define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH)
22#define expected_STRINGIFY( x ) expected_STRINGIFY_( x )
23#define expected_STRINGIFY_( x ) #x
27#define nsel_EXPECTED_DEFAULT 0
28#define nsel_EXPECTED_NONSTD 1
29#define nsel_EXPECTED_STD 2
34# if __has_include(<nonstd/expected.tweak.hpp>)
35# include <nonstd/expected.tweak.hpp>
37#define expected_HAVE_TWEAK_HEADER 1
39#define expected_HAVE_TWEAK_HEADER 0
45#if !defined( nsel_CONFIG_SELECT_EXPECTED )
46# define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD )
87#if !defined(nsel_CONFIG_WIN32_LEAN_AND_MEAN) && defined(_MSC_VER)
88# define nsel_CONFIG_WIN32_LEAN_AND_MEAN 1
90# define nsel_CONFIG_WIN32_LEAN_AND_MEAN 0
95#if !defined(nsel_CONFIG_NO_NODISCARD)
96# define nsel_CONFIG_NO_NODISCARD 0
98# define nsel_CONFIG_NO_NODISCARD 1
103#ifndef nsel_CONFIG_NO_EXCEPTIONS
104# if defined(_MSC_VER)
107# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
108# define nsel_CONFIG_NO_EXCEPTIONS 0
110# define nsel_CONFIG_NO_EXCEPTIONS 1
116#if !defined(nsel_CONFIG_NO_EXCEPTIONS_SEH) && defined(_MSC_VER)
117# define nsel_CONFIG_NO_EXCEPTIONS_SEH nsel_CONFIG_NO_EXCEPTIONS
119# define nsel_CONFIG_NO_EXCEPTIONS_SEH 0
125#ifndef nsel_CPLUSPLUS
126# if defined(_MSVC_LANG ) && !defined(__clang__)
127# define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
129# define nsel_CPLUSPLUS __cplusplus
133#define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L )
134#define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L )
135#define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L )
136#define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L )
137#define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L )
138#define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L )
142#if nsel_CPP23_OR_GREATER && defined(__has_include )
143# if __has_include( <expected> )
144# define nsel_HAVE_STD_EXPECTED 1
146# define nsel_HAVE_STD_EXPECTED 0
149# define nsel_HAVE_STD_EXPECTED 0
152#define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) )
158#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
159#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
163#if nsel_CPP17_OR_GREATER
170using std::in_place_type;
171using std::in_place_index;
172using std::in_place_t;
173using std::in_place_type_t;
174using std::in_place_index_t;
176#define nonstd_lite_in_place_t( T) std::in_place_t
177#define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
178#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
180#define nonstd_lite_in_place( T) std::in_place_t{}
181#define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
182#define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
196template< std::
size_t K >
209template< std::
size_t K >
221template< std::
size_t K >
229#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
230#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
231#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
233#define nonstd_lite_in_place( T) nonstd::in_place_type<T>
234#define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
235#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
246#if nsel_USES_STD_EXPECTED
253 using std::unexpected;
254 using std::bad_expected_access;
255 using std::unexpect_t;
260 template<
typename E >
261 using unexpected_type = unexpected<E>;
265 template<
typename E >
266 constexpr auto make_unexpected( E && value ) -> unexpected< typename std::decay<E>::type >
268 return unexpected< typename std::decay<E>::type >( std::forward<E>(value) );
273 typename E,
typename... Args,
274 typename = std::enable_if<
275 std::is_constructible<E, Args...>::value
279 make_unexpected( std::in_place_t inplace, Args &&... args ) -> unexpected_type< typename std::decay<E>::type >
281 return unexpected_type< typename std::decay<E>::type >( inplace, std::forward<Args>(args)...);
290#include <initializer_list>
293#include <system_error>
294#include <type_traits>
299#if nsel_CONFIG_WIN32_LEAN_AND_MEAN
300# ifndef WIN32_LEAN_AND_MEAN
301# define WIN32_LEAN_AND_MEAN
305#if nsel_CONFIG_NO_EXCEPTIONS
306# if nsel_CONFIG_NO_EXCEPTIONS_SEH
317#if nsel_CPP11_OR_GREATER
318# define nsel_constexpr constexpr
320# define nsel_constexpr
323#if nsel_CPP14_OR_GREATER
324# define nsel_constexpr14 constexpr
326# define nsel_constexpr14
329#if nsel_CPP17_OR_GREATER
330# define nsel_inline17 inline
332# define nsel_inline17
349#if defined(_MSC_VER) && !defined(__clang__)
350# define nsel_COMPILER_MSVC_VER (_MSC_VER )
351# define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
353# define nsel_COMPILER_MSVC_VER 0
354# define nsel_COMPILER_MSVC_VERSION 0
357#define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
359#if defined(__clang__)
360# define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
362# define nsel_COMPILER_CLANG_VERSION 0
365#if defined(__GNUC__) && !defined(__clang__)
366# define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
368# define nsel_COMPILER_GNUC_VERSION 0
376#define nsel_REQUIRES_0(...) \
377 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
379#define nsel_REQUIRES_T(...) \
380 , typename std::enable_if< (__VA_ARGS__), int >::type = 0
382#define nsel_REQUIRES_R(R, ...) \
383 typename std::enable_if< (__VA_ARGS__), R>::type
385#define nsel_REQUIRES_A(...) \
386 , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
391# pragma clang diagnostic push
392#elif defined __GNUC__
393# pragma GCC diagnostic push
396#if nsel_COMPILER_MSVC_VERSION >= 140
397# define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(push) ) __pragma( warning(disable: codes) )
399# define nsel_DISABLE_MSVC_WARNINGS(codes)
403# define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
404# define nsel_RESTORE_MSVC_WARNINGS()
405#elif defined __GNUC__
406# define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
407# define nsel_RESTORE_MSVC_WARNINGS()
408#elif nsel_COMPILER_MSVC_VERSION >= 140
409# define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) )
410# define nsel_RESTORE_MSVC_WARNINGS() nsel_RESTORE_WARNINGS()
412# define nsel_RESTORE_WARNINGS()
413# define nsel_RESTORE_MSVC_WARNINGS()
419nsel_DISABLE_MSVC_WARNINGS( 26409 )
424# define nsel_HAS_CPP0X _HAS_CPP0X
426# define nsel_HAS_CPP0X 0
431#define nsel_CPP11_000 (nsel_CPP11_OR_GREATER)
432#define nsel_CPP17_000 (nsel_CPP17_OR_GREATER)
436#define nsel_HAVE_ADDRESSOF nsel_CPP11_000
440#define nsel_HAVE_DEPRECATED nsel_CPP17_000
441#define nsel_HAVE_NODISCARD nsel_CPP17_000
445#if nsel_HAVE_DEPRECATED
446# define nsel_deprecated(msg) [[deprecated(msg)]]
448# define nsel_deprecated(msg)
451#if nsel_HAVE_NODISCARD && !nsel_CONFIG_NO_NODISCARD
452# define nsel_NODISCARD [[nodiscard]]
454# define nsel_NODISCARD
461namespace nonstd {
namespace expected_lite {
468#if nsel_HAVE_ADDRESSOF
469 using std::addressof;
472 T * addressof( T & arg )
noexcept
478 const T * addressof(
const T && ) =
delete;
486#if nsel_CPP17_OR_GREATER
488using std::conjunction;
489using std::is_swappable;
490using std::is_nothrow_swappable;
500 template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
501 static std::true_type test(
int );
504 static std::false_type test(...);
507struct is_nothrow_swappable
511 template<
typename T >
512 static constexpr bool satisfies()
514 return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
517 template<
typename T >
518 static auto test(
int ) -> std::integral_constant<bool, satisfies<T>()>{}
521 static auto test(...) -> std::false_type;
527template<
typename T >
528struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
530template<
typename T >
531struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
535template<
typename... >
struct conjunction : std::true_type{};
536template<
typename B1 >
struct conjunction<B1> : B1{};
538template<
typename B1,
typename... Bn >
539struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
549#if defined(__cpp_lib_remove_cvref)
551using std::remove_cvref;
555template<
typename T >
558 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
567template<
typename T,
typename E >
573template<
typename T >
574struct is_expected : std::false_type {};
576template<
typename T,
typename E >
577struct is_expected< expected< T, E > > : std::true_type {};
582template<
typename T,
typename E >
583class storage_t_noncopy_nonmove_impl
585 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
588 using value_type = T;
589 using error_type = E;
592 storage_t_noncopy_nonmove_impl() {}
593 ~storage_t_noncopy_nonmove_impl() {}
595 explicit storage_t_noncopy_nonmove_impl(
bool has_value )
596 : m_has_value( has_value )
599 void construct_value()
601 new( std11::addressof(m_value) ) value_type();
614 template<
class... Args >
615 void emplace_value( Args&&... args )
617 new( std11::addressof(m_value) ) value_type( std::forward<Args>(args)...);
620 template<
class U,
class... Args >
621 void emplace_value( std::initializer_list<U> il, Args&&... args )
623 new( std11::addressof(m_value) ) value_type( il, std::forward<Args>(args)... );
626 void destruct_value()
628 m_value.~value_type();
641 template<
class... Args >
642 void emplace_error( Args&&... args )
644 new( std11::addressof(m_error) ) error_type( std::forward<Args>(args)...);
647 template<
class U,
class... Args >
648 void emplace_error( std::initializer_list<U> il, Args&&... args )
650 new( std11::addressof(m_error) ) error_type( il, std::forward<Args>(args)... );
653 void destruct_error()
655 m_error.~error_type();
658 constexpr value_type
const & value() const &
663 value_type & value() &
668 constexpr value_type
const && value() const &&
670 return std::move( m_value );
673 nsel_constexpr14 value_type && value() &&
675 return std::move( m_value );
678 value_type
const * value_ptr()
const
680 return std11::addressof(m_value);
683 value_type * value_ptr()
685 return std11::addressof(m_value);
688 error_type
const &
error() const &
693 error_type &
error() &
698 constexpr error_type
const &&
error() const &&
700 return std::move( m_error );
703 nsel_constexpr14 error_type &&
error() &&
705 return std::move( m_error );
708 bool has_value()
const
713 void set_has_value(
bool v )
725 bool m_has_value =
false;
728template<
typename T,
typename E >
731 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
734 using value_type = T;
735 using error_type = E;
741 explicit storage_t_impl(
bool has_value )
742 : m_has_value( has_value )
745 void construct_value()
747 new( std11::addressof(m_value) ) value_type();
750 void construct_value( value_type
const & e )
752 new( std11::addressof(m_value) ) value_type( e );
755 void construct_value( value_type && e )
757 new( std11::addressof(m_value) ) value_type( std::move( e ) );
760 template<
class... Args >
761 void emplace_value( Args&&... args )
763 new( std11::addressof(m_value) ) value_type( std::forward<Args>(args)...);
766 template<
class U,
class... Args >
767 void emplace_value( std::initializer_list<U> il, Args&&... args )
769 new( std11::addressof(m_value) ) value_type( il, std::forward<Args>(args)... );
772 void destruct_value()
774 m_value.~value_type();
777 void construct_error( error_type
const & e )
779 new( std11::addressof(m_error) ) error_type( e );
782 void construct_error( error_type && e )
784 new( std11::addressof(m_error) ) error_type( std::move( e ) );
787 template<
class... Args >
788 void emplace_error( Args&&... args )
790 new( std11::addressof(m_error) ) error_type( std::forward<Args>(args)...);
793 template<
class U,
class... Args >
794 void emplace_error( std::initializer_list<U> il, Args&&... args )
796 new( std11::addressof(m_error) ) error_type( il, std::forward<Args>(args)... );
799 void destruct_error()
801 m_error.~error_type();
804 constexpr value_type
const & value() const &
809 value_type & value() &
814 constexpr value_type
const && value() const &&
816 return std::move( m_value );
819 nsel_constexpr14 value_type && value() &&
821 return std::move( m_value );
824 value_type
const * value_ptr()
const
826 return std11::addressof(m_value);
829 value_type * value_ptr()
831 return std11::addressof(m_value);
834 error_type
const &
error() const &
839 error_type &
error() &
844 constexpr error_type
const &&
error() const &&
846 return std::move( m_error );
849 nsel_constexpr14 error_type &&
error() &&
851 return std::move( m_error );
854 bool has_value()
const
859 void set_has_value(
bool v )
871 bool m_has_value =
false;
876template<
typename E >
877struct storage_t_impl< void, E >
879 template<
typename,
typename >
friend class nonstd::expected_lite::expected;
882 using value_type = void;
883 using error_type = E;
889 explicit storage_t_impl(
bool has_value )
890 : m_has_value( has_value )
893 void construct_error( error_type
const & e )
895 new( std11::addressof(m_error) ) error_type( e );
898 void construct_error( error_type && e )
900 new( std11::addressof(m_error) ) error_type( std::move( e ) );
903 template<
class... Args >
904 void emplace_error( Args&&... args )
906 new( std11::addressof(m_error) ) error_type( std::forward<Args>(args)...);
909 template<
class U,
class... Args >
910 void emplace_error( std::initializer_list<U> il, Args&&... args )
912 new( std11::addressof(m_error) ) error_type( il, std::forward<Args>(args)... );
915 void destruct_error()
917 m_error.~error_type();
920 error_type
const &
error() const &
925 error_type &
error() &
930 constexpr error_type
const &&
error() const &&
932 return std::move( m_error );
935 nsel_constexpr14 error_type &&
error() &&
937 return std::move( m_error );
940 bool has_value()
const
945 void set_has_value(
bool v )
957 bool m_has_value =
false;
960template<
typename T,
typename E,
bool isConstructable,
bool isMoveable >
966template<
typename T,
typename E >
967class storage_t<T, E, false, false> :
public storage_t_noncopy_nonmove_impl<T, E>
970 storage_t() =
default;
971 ~storage_t() =
default;
973 explicit storage_t(
bool has_value )
974 : storage_t_noncopy_nonmove_impl<T, E>( has_value )
977 storage_t( storage_t
const & other ) =
delete;
978 storage_t( storage_t && other ) =
delete;
982template<
typename T,
typename E >
983class storage_t<T, E, true, true> :
public storage_t_impl<T, E>
986 storage_t() =
default;
987 ~storage_t() =
default;
989 explicit storage_t(
bool has_value )
990 : storage_t_impl<T, E>( has_value )
993 storage_t( storage_t
const & other )
994 : storage_t_impl<T, E>( other.has_value() )
996 if ( this->has_value() ) this->construct_value( other.value() );
997 else this->construct_error( other.error() );
1000 storage_t(storage_t && other )
1001 : storage_t_impl<T, E>( other.has_value() )
1003 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
1004 else this->construct_error( std::move( other.error() ) );
1008template<
typename E >
1009class storage_t<void, E, true, true> :
public storage_t_impl<void, E>
1012 storage_t() =
default;
1013 ~storage_t() =
default;
1015 explicit storage_t(
bool has_value )
1016 : storage_t_impl<void, E>( has_value )
1019 storage_t( storage_t
const & other )
1020 : storage_t_impl<void, E>( other.has_value() )
1022 if ( this->has_value() ) ;
1023 else this->construct_error( other.error() );
1026 storage_t(storage_t && other )
1027 : storage_t_impl<void, E>( other.has_value() )
1029 if ( this->has_value() ) ;
1030 else this->construct_error( std::move( other.error() ) );
1034template<
typename T,
typename E >
1035class storage_t<T, E, true, false> :
public storage_t_impl<T, E>
1038 storage_t() =
default;
1039 ~storage_t() =
default;
1041 explicit storage_t(
bool has_value )
1042 : storage_t_impl<T, E>( has_value )
1045 storage_t( storage_t
const & other )
1046 : storage_t_impl<T, E>(other.has_value())
1048 if ( this->has_value() ) this->construct_value( other.value() );
1049 else this->construct_error( other.error() );
1052 storage_t( storage_t && other ) =
delete;
1055template<
typename E >
1056class storage_t<void, E, true, false> :
public storage_t_impl<void, E>
1059 storage_t() =
default;
1060 ~storage_t() =
default;
1062 explicit storage_t(
bool has_value )
1063 : storage_t_impl<void, E>( has_value )
1066 storage_t( storage_t
const & other )
1067 : storage_t_impl<void, E>(other.has_value())
1069 if ( this->has_value() ) ;
1070 else this->construct_error( other.error() );
1073 storage_t( storage_t && other ) =
delete;
1076template<
typename T,
typename E >
1077class storage_t<T, E, false, true> :
public storage_t_impl<T, E>
1080 storage_t() =
default;
1081 ~storage_t() =
default;
1083 explicit storage_t(
bool has_value )
1084 : storage_t_impl<T, E>( has_value )
1087 storage_t( storage_t
const & other ) =
delete;
1089 storage_t( storage_t && other )
1090 : storage_t_impl<T, E>( other.has_value() )
1092 if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
1093 else this->construct_error( std::move( other.error() ) );
1097template<
typename E >
1098class storage_t<void, E, false, true> :
public storage_t_impl<void, E>
1101 storage_t() =
default;
1102 ~storage_t() =
default;
1104 explicit storage_t(
bool has_value )
1105 : storage_t_impl<void, E>( has_value )
1108 storage_t( storage_t
const & other ) =
delete;
1110 storage_t( storage_t && other )
1111 : storage_t_impl<void, E>( other.has_value() )
1113 if ( this->has_value() ) ;
1114 else this->construct_error( std::move( other.error() ) );
1121struct is_reference_wrapper : std::false_type {};
1122template<
typename T >
1123struct is_reference_wrapper<
std::reference_wrapper< T > > : std::true_type {};
1125template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1127 std::is_function<FnT>::value
1128 && ( std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1129 || std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value )
1132nsel_constexpr
auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1133 noexcept(
noexcept( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... ) ) )
1134 ->
decltype( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )...) )
1136 return (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... );
1139template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1141 std::is_function<FnT>::value
1142 && is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1145nsel_constexpr
auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1146 noexcept(
noexcept( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) ) )
1147 ->
decltype( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) )
1149 return (obj.get().*memfnptr)( std::forward< Args >( args ) ... );
1152template<
typename FnT,
typename ClassT,
typename ObjectT,
typename... Args
1154 std::is_function<FnT>::value
1155 && !std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1156 && !std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1157 && !is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1160nsel_constexpr
auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
1161 noexcept(
noexcept( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) ) )
1162 ->
decltype( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) )
1164 return ((*std::forward<ObjectT>(obj)).*memfnptr)( std::forward< Args >( args ) ... );
1167template<
typename MemberT,
typename ClassT,
typename ObjectT
1169 std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1170 || std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1173nsel_constexpr
auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1174 noexcept(
noexcept( std::forward< ObjectT >( obj ).*memobjptr ) )
1175 ->
decltype( std::forward< ObjectT >( obj ).*memobjptr )
1177 return std::forward< ObjectT >( obj ).*memobjptr;
1180template<
typename MemberT,
typename ClassT,
typename ObjectT
1182 is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1185nsel_constexpr
auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1186 noexcept(
noexcept( obj.get().*memobjptr ) )
1187 ->
decltype( obj.get().*memobjptr )
1189 return obj.get().*memobjptr;
1192template<
typename MemberT,
typename ClassT,
typename ObjectT
1194 !std::is_same< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1195 && !std::is_base_of< ClassT,
typename std20::remove_cvref< ObjectT >::type >::value
1196 && !is_reference_wrapper<
typename std20::remove_cvref< ObjectT >::type >::value
1199nsel_constexpr
auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
1200 noexcept(
noexcept( (*std::forward< ObjectT >( obj )).*memobjptr ) )
1201 ->
decltype( (*std::forward< ObjectT >( obj )).*memobjptr )
1203 return (*std::forward< ObjectT >( obj )).*memobjptr;
1206template<
typename F,
typename... Args
1208 std::is_member_function_pointer<
typename std20::remove_cvref< F >::type >::value
1211nsel_constexpr
auto invoke( F && f, Args && ... args )
1212 noexcept(
noexcept( invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) ) )
1213 ->
decltype( invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) )
1215 return invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... );
1218template<
typename F,
typename... Args
1220 std::is_member_object_pointer<
typename std20::remove_cvref< F >::type >::value
1223nsel_constexpr
auto invoke( F && f, Args && ... args )
1224 noexcept(
noexcept( invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) ) )
1225 ->
decltype( invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) )
1227 return invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... );
1230template<
typename F,
typename... Args
1232 !std::is_member_function_pointer<
typename std20::remove_cvref< F >::type >::value
1233 && !std::is_member_object_pointer<
typename std20::remove_cvref< F >::type >::value
1236nsel_constexpr
auto invoke( F && f, Args && ... args )
1237 noexcept(
noexcept( std::forward< F >( f )( std::forward< Args >( args ) ... ) ) )
1238 ->
decltype( std::forward< F >( f )( std::forward< Args >( args ) ... ) )
1240 return std::forward< F >( f )( std::forward< Args >( args ) ... );
1243template<
typename F,
typename ... Args >
1244using invoke_result_nocvref_t =
typename std20::remove_cvref< decltype( ::nonstd::expected_lite::detail::invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
1247template<
typename F,
typename ... Args >
1248using transform_invoke_result_t =
typename std::remove_cv< decltype( ::nonstd::expected_lite::detail::invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
1250template<
typename F,
typename ... Args >
1251using transform_invoke_result_t = invoke_result_nocvref_t
1254template<
typename T >
1255struct valid_expected_value_type : std::integral_constant< bool, std::is_destructible< T >::value && !std::is_reference< T >::value && !std::is_array< T >::value > {};
1263template<
typename E = std::exception_ptr >
1264class unexpected_type
1266template< typename E >
1267class unexpected_type
1271 using error_type = E;
1277 constexpr unexpected_type( unexpected_type
const & ) =
default;
1278 constexpr unexpected_type( unexpected_type && ) =
default;
1280 template<
typename... Args
1282 std::is_constructible<E, Args&&...>::value
1285 constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), Args &&... args )
1286 : m_error(
std::forward<Args>( args )...)
1289 template<
typename U,
typename... Args
1291 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
1294 constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), std::initializer_list<U> il, Args &&... args )
1295 : m_error( il,
std::forward<Args>( args )...)
1298 template<
typename E2
1300 std::is_constructible<E,E2>::value
1301 && !std::is_same<
typename std20::remove_cvref<E2>::type, nonstd_lite_in_place_t(E2) >::value
1302 && !std::is_same<
typename std20::remove_cvref<E2>::type, unexpected_type >::value
1305 constexpr explicit unexpected_type( E2 && error )
1306 : m_error(
std::forward<E2>(
error ) )
1309 template<
typename E2
1311 std::is_constructible< E, E2>::value
1312 && !std::is_constructible<E, unexpected_type<E2> & >::value
1313 && !std::is_constructible<E, unexpected_type<E2> >::value
1314 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
1315 && !std::is_constructible<E, unexpected_type<E2>
const >::value
1316 && !std::is_convertible< unexpected_type<E2> &, E>::value
1317 && !std::is_convertible< unexpected_type<E2> , E>::value
1318 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1319 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1320 && !std::is_convertible< E2 const &, E>::value
1323 constexpr explicit unexpected_type( unexpected_type<E2>
const & error )
1327 template<
typename E2
1329 std::is_constructible< E, E2>::value
1330 && !std::is_constructible<E, unexpected_type<E2> & >::value
1331 && !std::is_constructible<E, unexpected_type<E2> >::value
1332 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
1333 && !std::is_constructible<E, unexpected_type<E2>
const >::value
1334 && !std::is_convertible< unexpected_type<E2> &, E>::value
1335 && !std::is_convertible< unexpected_type<E2> , E>::value
1336 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1337 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1338 && std::is_convertible< E2 const &, E>::value
1341 constexpr unexpected_type( unexpected_type<E2>
const & error )
1345 template<
typename E2
1347 std::is_constructible< E, E2>::value
1348 && !std::is_constructible<E, unexpected_type<E2> & >::value
1349 && !std::is_constructible<E, unexpected_type<E2> >::value
1350 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
1351 && !std::is_constructible<E, unexpected_type<E2>
const >::value
1352 && !std::is_convertible< unexpected_type<E2> &, E>::value
1353 && !std::is_convertible< unexpected_type<E2> , E>::value
1354 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1355 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1356 && !std::is_convertible< E2 const &, E>::value
1359 constexpr explicit unexpected_type( unexpected_type<E2> && error )
1363 template<
typename E2
1365 std::is_constructible< E, E2>::value
1366 && !std::is_constructible<E, unexpected_type<E2> & >::value
1367 && !std::is_constructible<E, unexpected_type<E2> >::value
1368 && !std::is_constructible<E, unexpected_type<E2>
const & >::value
1369 && !std::is_constructible<E, unexpected_type<E2>
const >::value
1370 && !std::is_convertible< unexpected_type<E2> &, E>::value
1371 && !std::is_convertible< unexpected_type<E2> , E>::value
1372 && !std::is_convertible< unexpected_type<E2>
const &, E>::value
1373 && !std::is_convertible< unexpected_type<E2>
const , E>::value
1374 && std::is_convertible< E2 const &, E>::value
1377 constexpr unexpected_type( unexpected_type<E2> && error )
1383 nsel_constexpr14 unexpected_type& operator=( unexpected_type
const & ) =
default;
1384 nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) =
default;
1386 template<
typename E2 = E >
1387 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2>
const & other )
1389 unexpected_type{ other.error() }.swap( *
this );
1393 template<
typename E2 = E >
1394 nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
1396 unexpected_type{ std::move( other.error() ) }.swap( *
this );
1402 nsel_constexpr14 E &
error() &
noexcept
1407 constexpr E
const &
error() const & noexcept
1412#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1414 nsel_constexpr14 E &&
error() &&
noexcept
1416 return std::move( m_error );
1419 constexpr E
const &&
error() const && noexcept
1421 return std::move( m_error );
1428 nsel_deprecated(
"replace value() with error()")
1430 nsel_constexpr14 E & value() & noexcept
1435 nsel_deprecated(
"replace value() with error()")
1437 constexpr E const & value() const & noexcept
1442#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1444 nsel_deprecated(
"replace value() with error()")
1446 nsel_constexpr14 E && value() && noexcept
1448 return std::move( m_error );
1451 nsel_deprecated(
"replace value() with error()")
1453 constexpr E const && value() const && noexcept
1455 return std::move( m_error );
1462 template<
typename U=E >
1463 nsel_REQUIRES_R(
void,
1464 std17::is_swappable<U>::value
1466 swap( unexpected_type & other )
noexcept (
1467 std17::is_nothrow_swappable<U>::value
1471 swap( m_error, other.m_error );
1480#if nsel_CPP17_OR_GREATER
1484template<
typename E >
1485unexpected_type( E ) -> unexpected_type< E >;
1491#if !nsel_CONFIG_NO_EXCEPTIONS
1497class unexpected_type<
std::exception_ptr >
1500 using error_type = std::exception_ptr;
1502 unexpected_type() =
delete;
1504 ~unexpected_type(){}
1506 explicit unexpected_type( std::exception_ptr
const & error )
1510 explicit unexpected_type(std::exception_ptr && error )
1514 template<
typename E >
1515 explicit unexpected_type( E error )
1516 : m_error(
std::make_exception_ptr(
error ) )
1519 std::exception_ptr
const & value()
const
1524 std::exception_ptr & value()
1530 std::exception_ptr m_error;
1538template<
typename E1,
typename E2 >
1539constexpr bool operator==( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1541 return x.error() == y.error();
1544template<
typename E1,
typename E2 >
1545constexpr bool operator!=( unexpected_type<E1>
const & x, unexpected_type<E2>
const & y )
1547 return ! ( x == y );
1552template<
typename E >
1553constexpr bool operator<( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1555 return x.error() < y.error();
1558template<
typename E >
1559constexpr bool operator>( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1564template<
typename E >
1565constexpr bool operator<=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1570template<
typename E >
1571constexpr bool operator>=( unexpected_type<E>
const & x, unexpected_type<E>
const & y )
1582 std17::is_swappable<E>::value
1585void swap( unexpected_type<E> & x, unexpected_type<E> & y)
noexcept (
noexcept ( x.swap(y) ) )
1594inline constexpr bool operator<( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1599inline constexpr bool operator>( unexpected_type<std::exception_ptr>
const & , unexpected_type<std::exception_ptr>
const & )
1604inline constexpr bool operator<=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1609inline constexpr bool operator>=( unexpected_type<std::exception_ptr>
const & x, unexpected_type<std::exception_ptr>
const & y )
1620template<
typename E >
1621struct is_unexpected : std::false_type {};
1623template<
typename E >
1624struct is_unexpected< unexpected_type<E> > : std::true_type {};
1632template<
typename E >
1633nsel_constexpr14
auto
1634make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
1636 return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
1641 typename E,
typename... Args,
1642 typename = std::enable_if<
1643 std::is_constructible<E, Args...>::value
1646nsel_constexpr14
auto
1647make_unexpected( nonstd_lite_in_place_t(E), Args &&... args ) -> unexpected_type< typename std::decay<E>::type >
1649 return std::move( unexpected_type<
typename std::decay<E>::type >( nonstd_lite_in_place(E), std::forward<Args>(args)...) );
1655make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
1657 return unexpected_type< std::exception_ptr >( std::current_exception() );
1664template<
typename E >
1665class nsel_NODISCARD bad_expected_access;
1670class nsel_NODISCARD bad_expected_access< void > :
public std::exception
1673 explicit bad_expected_access()
1680#if !nsel_CONFIG_NO_EXCEPTIONS
1682template<
typename E >
1683class nsel_NODISCARD bad_expected_access :
public bad_expected_access< void >
1686 using error_type = E;
1688 explicit bad_expected_access( error_type error )
1692 virtual char const * what() const noexcept
override
1694 return "bad_expected_access";
1697 nsel_constexpr14 error_type &
error() &
1702 constexpr error_type
const &
error() const &
1707#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
1709 nsel_constexpr14 error_type &&
error() &&
1711 return std::move( m_error );
1714 constexpr error_type
const &&
error() const &&
1716 return std::move( m_error );
1730using in_place_unexpected_t = unexpect_t;
1732nsel_inline17
constexpr unexpect_t unexpect{};
1733nsel_inline17
constexpr unexpect_t in_place_unexpected{};
1737#if nsel_CONFIG_NO_EXCEPTIONS
1740 inline bool text(
char const * ) {
return true; }
1743template<
typename Error >
1746 static void rethrow( Error
const & )
1748#if nsel_CONFIG_NO_EXCEPTIONS_SEH
1749 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1751 assert(
false && detail::text(
"throw bad_expected_access<Error>{ e };") );
1757struct error_traits<
std::exception_ptr >
1759 static void rethrow( std::exception_ptr
const & )
1761#if nsel_CONFIG_NO_EXCEPTIONS_SEH
1762 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1764 assert(
false && detail::text(
"throw bad_expected_access<std::exception_ptr>{ e };") );
1770struct error_traits<
std::error_code >
1772 static void rethrow( std::error_code
const & )
1774#if nsel_CONFIG_NO_EXCEPTIONS_SEH
1775 RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
1777 assert(
false && detail::text(
"throw std::system_error( e );") );
1784template<
typename Error >
1787 static void rethrow( Error
const & e )
1789 throw bad_expected_access<Error>{ e };
1794struct error_traits<
std::exception_ptr >
1796 static void rethrow( std::exception_ptr
const & e )
1798 std::rethrow_exception( e );
1803struct error_traits<
std::error_code >
1805 static void rethrow( std::error_code
const & e )
1807 throw std::system_error( e );
1818template<
typename T >
1819struct valid_unexpected_type : std::integral_constant< bool,
1820 std::is_same< T, typename std20::remove_cvref< T >::type >::value
1821 && std::is_object< T >::value
1822 && !std::is_array< T >::value
1825template<
typename T >
1826struct valid_unexpected_type< unexpected_type< T > > : std::false_type {};
1835using expected_lite::unexpected_type;
1837namespace expected_lite {
1842template<
typename T,
typename E = std::exception_ptr >
1843class nsel_NODISCARD expected
1845template< typename T, typename E >
1846class nsel_NODISCARD expected
1850 template<
typename,
typename >
friend class expected;
1853 using value_type = T;
1854 using error_type = E;
1855 using unexpected_type = nonstd::unexpected_type<E>;
1857 template<
typename U >
1860 using type = expected<U, error_type>;
1866 std::is_default_constructible<T>::value
1868 nsel_constexpr14 expected()
1871 contained.construct_value();
1874 nsel_constexpr14 expected( expected
const & ) =
default;
1875 nsel_constexpr14 expected( expected && ) =
default;
1877 template<
typename U,
typename G
1879 std::is_constructible< T, U const &>::value
1880 && std::is_constructible<E, G const &>::value
1881 && !std::is_constructible<T, expected<U, G> & >::value
1882 && !std::is_constructible<T, expected<U, G> && >::value
1883 && !std::is_constructible<T, expected<U, G>
const & >::value
1884 && !std::is_constructible<T, expected<U, G>
const && >::value
1885 && !std::is_convertible< expected<U, G> & , T>::value
1886 && !std::is_convertible< expected<U, G> &&, T>::value
1887 && !std::is_convertible< expected<U, G>
const & , T>::value
1888 && !std::is_convertible< expected<U, G>
const &&, T>::value
1889 && (!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value )
1892 nsel_constexpr14
explicit expected( expected<U, G>
const & other )
1893 : contained( other.has_value() )
1895 if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
1896 else contained.construct_error( E{ other.contained.error() } );
1899 template<
typename U,
typename G
1901 std::is_constructible< T, U const &>::value
1902 && std::is_constructible<E, G const &>::value
1903 && !std::is_constructible<T, expected<U, G> & >::value
1904 && !std::is_constructible<T, expected<U, G> && >::value
1905 && !std::is_constructible<T, expected<U, G>
const & >::value
1906 && !std::is_constructible<T, expected<U, G>
const && >::value
1907 && !std::is_convertible< expected<U, G> & , T>::value
1908 && !std::is_convertible< expected<U, G> &&, T>::value
1909 && !std::is_convertible< expected<U, G>
const &, T>::value
1910 && !std::is_convertible< expected<U, G>
const &&, T>::value
1911 && !(!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value )
1914 nsel_constexpr14 expected( expected<U, G>
const & other )
1915 : contained( other.has_value() )
1917 if ( has_value() ) contained.construct_value( other.contained.value() );
1918 else contained.construct_error( other.contained.error() );
1921 template<
typename U,
typename G
1923 std::is_constructible< T, U>::value
1924 && std::is_constructible<E, G>::value
1925 && !std::is_constructible<T, expected<U, G> & >::value
1926 && !std::is_constructible<T, expected<U, G> && >::value
1927 && !std::is_constructible<T, expected<U, G>
const & >::value
1928 && !std::is_constructible<T, expected<U, G>
const && >::value
1929 && !std::is_convertible< expected<U, G> & , T>::value
1930 && !std::is_convertible< expected<U, G> &&, T>::value
1931 && !std::is_convertible< expected<U, G>
const & , T>::value
1932 && !std::is_convertible< expected<U, G>
const &&, T>::value
1933 && (!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value )
1936 nsel_constexpr14
explicit expected( expected<U, G> && other )
1937 : contained( other.has_value() )
1939 if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
1940 else contained.construct_error( E{ std::move( other.contained.error() ) } );
1943 template<
typename U,
typename G
1945 std::is_constructible< T, U>::value
1946 && std::is_constructible<E, G>::value
1947 && !std::is_constructible<T, expected<U, G> & >::value
1948 && !std::is_constructible<T, expected<U, G> && >::value
1949 && !std::is_constructible<T, expected<U, G>
const & >::value
1950 && !std::is_constructible<T, expected<U, G>
const && >::value
1951 && !std::is_convertible< expected<U, G> & , T>::value
1952 && !std::is_convertible< expected<U, G> &&, T>::value
1953 && !std::is_convertible< expected<U, G>
const & , T>::value
1954 && !std::is_convertible< expected<U, G>
const &&, T>::value
1955 && !(!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value )
1958 nsel_constexpr14 expected( expected<U, G> && other )
1959 : contained( other.has_value() )
1961 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
1962 else contained.construct_error( std::move( other.contained.error() ) );
1965 template<
typename U = T
1967 std::is_copy_constructible<U>::value
1970 nsel_constexpr14 expected( value_type
const & value )
1973 contained.construct_value( value );
1976 template<
typename U = T
1978 std::is_constructible<T,U&&>::value
1979 && !std::is_same<
typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1980 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
1981 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
1982 && !std::is_convertible<U&&,T>::value
1985 nsel_constexpr14
explicit expected( U && value )
noexcept
1987 std::is_nothrow_move_constructible<U>::value &&
1988 std::is_nothrow_move_constructible<E>::value
1992 contained.construct_value( T{ std::forward<U>( value ) } );
1995 template<
typename U = T
1997 std::is_constructible<T,U&&>::value
1998 && !std::is_same<
typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1999 && !std::is_same< expected<T,E> ,
typename std20::remove_cvref<U>::type>::value
2000 && !std::is_same<nonstd::unexpected_type<E>,
typename std20::remove_cvref<U>::type>::value
2001 && std::is_convertible<U&&,T>::value
2004 nsel_constexpr14 expected( U && value )
noexcept
2006 std::is_nothrow_move_constructible<U>::value &&
2007 std::is_nothrow_move_constructible<E>::value
2011 contained.construct_value( std::forward<U>( value ) );
2016 template<
typename G = E
2018 std::is_constructible<E, G const & >::value
2019 && !std::is_convertible< G const &, E>::value
2022 nsel_constexpr14
explicit expected( nonstd::unexpected_type<G>
const & error )
2023 : contained( false )
2025 contained.construct_error( E{
error.error() } );
2028 template<
typename G = E
2030 std::is_constructible<E, G const & >::value
2031 && std::is_convertible< G const &, E>::value
2034 nsel_constexpr14 expected( nonstd::unexpected_type<G>
const & error )
2035 : contained( false )
2037 contained.construct_error(
error.error() );
2040 template<
typename G = E
2042 std::is_constructible<E, G&& >::value
2043 && !std::is_convertible< G&&, E>::value
2046 nsel_constexpr14
explicit expected( nonstd::unexpected_type<G> && error )
2047 : contained( false )
2049 contained.construct_error( E{ std::move(
error.error() ) } );
2052 template<
typename G = E
2054 std::is_constructible<E, G&& >::value
2055 && std::is_convertible< G&&, E>::value
2058 nsel_constexpr14 expected( nonstd::unexpected_type<G> && error )
2059 : contained( false )
2061 contained.construct_error( std::move(
error.error() ) );
2066 template<
typename... Args
2068 std::is_constructible<T, Args&&...>::value
2071 nsel_constexpr14
explicit expected( nonstd_lite_in_place_t(T), Args&&... args )
2074 contained.emplace_value( std::forward<Args>( args )... );
2077 template<
typename U,
typename... Args
2079 std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
2082 nsel_constexpr14
explicit expected( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
2085 contained.emplace_value( il, std::forward<Args>( args )... );
2090 template<
typename... Args
2092 std::is_constructible<E, Args&&...>::value
2095 nsel_constexpr14
explicit expected( unexpect_t, Args&&... args )
2096 : contained( false )
2098 contained.emplace_error( std::forward<Args>( args )... );
2101 template<
typename U,
typename... Args
2103 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
2106 nsel_constexpr14
explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
2107 : contained( false )
2109 contained.emplace_error( il, std::forward<Args>( args )... );
2120 if ( has_value() ) contained.destruct_value();
2121 else contained.destruct_error();
2126 expected & operator=( expected
const & other )
2128 expected( other ).swap( *
this );
2132 expected & operator=( expected && other )
noexcept
2134 std::is_nothrow_move_constructible< T>::value
2135 && std::is_nothrow_move_assignable< T>::value
2136 && std::is_nothrow_move_constructible<E>::value
2137 && std::is_nothrow_move_assignable< E>::value )
2139 expected( std::move( other ) ).swap( *
this );
2143 template<
typename U
2145 !std::is_same<expected<T,E>,
typename std20::remove_cvref<U>::type>::value
2146 && std17::conjunction<std::is_scalar<T>, std::is_same<T, std::decay<U>> >::value
2147 && std::is_constructible<T ,U>::value
2148 && std::is_assignable< T&,U>::value
2149 && std::is_nothrow_move_constructible<E>::value )
2151 expected & operator=( U && value )
2153 expected( std::forward<U>( value ) ).swap( *
this );
2157 template<
typename G = E
2159 std::is_constructible<E, G const&>::value &&
2160 std::is_copy_constructible<G>::value
2161 && std::is_copy_assignable<G>::value
2164 expected & operator=( nonstd::unexpected_type<G>
const & error )
2166 expected( unexpect,
error.error() ).swap( *
this );
2170 template<
typename G = E
2172 std::is_constructible<E, G&&>::value &&
2173 std::is_move_constructible<G>::value
2174 && std::is_move_assignable<G>::value
2177 expected & operator=( nonstd::unexpected_type<G> && error )
2179 expected( unexpect, std::move(
error.error() ) ).swap( *
this );
2183 template<
typename... Args
2185 std::is_nothrow_constructible<T, Args&&...>::value
2188 value_type & emplace( Args &&... args )
2190 expected( nonstd_lite_in_place(T), std::forward<Args>(args)... ).swap( *
this );
2194 template<
typename U,
typename... Args
2196 std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value
2199 value_type & emplace( std::initializer_list<U> il, Args &&... args )
2201 expected( nonstd_lite_in_place(T), il, std::forward<Args>(args)... ).swap( *
this );
2207 template<
typename U=T,
typename G=E >
2208 nsel_REQUIRES_R(
void,
2209 std17::is_swappable< U>::value
2210 && std17::is_swappable<G>::value
2211 && ( std::is_move_constructible<U>::value || std::is_move_constructible<G>::value )
2213 swap( expected & other )
noexcept
2215 std::is_nothrow_move_constructible<T>::value && std17::is_nothrow_swappable<T&>::value &&
2216 std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
2221 if (
bool(*
this) &&
bool(other) ) { swap( contained.value(), other.contained.value() ); }
2222 else if ( !
bool(*
this) && !
bool(other) ) { swap( contained.error(), other.contained.error() ); }
2223 else if (
bool(*
this) && !
bool(other) ) { error_type t( std::move( other.error() ) );
2224 other.contained.destruct_error();
2225 other.contained.construct_value( std::move( contained.value() ) );
2226 contained.destruct_value();
2227 contained.construct_error( std::move( t ) );
2228 bool has_value = contained.has_value();
2229 bool other_has_value = other.has_value();
2230 other.contained.set_has_value(has_value);
2231 contained.set_has_value(other_has_value);
2233 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2238 constexpr value_type
const * operator ->()
const
2240 return assert( has_value() ), contained.value_ptr();
2243 value_type * operator ->()
2245 return assert( has_value() ), contained.value_ptr();
2248 constexpr value_type
const & operator *() const &
2250 return assert( has_value() ), contained.value();
2253 value_type & operator *() &
2255 return assert( has_value() ), contained.value();
2258#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2260 constexpr value_type
const && operator *() const &&
2262 return std::move( ( assert( has_value() ), contained.value() ) );
2265 nsel_constexpr14 value_type && operator *() &&
2267 return std::move( ( assert( has_value() ), contained.value() ) );
2272 constexpr explicit operator bool() const noexcept
2277 constexpr bool has_value() const noexcept
2279 return contained.has_value();
2282 nsel_DISABLE_MSVC_WARNINGS( 4702 )
2284 constexpr value_type const & value() const &
2287 ? ( contained.value() )
2288 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
2291 value_type & value() &
2294 ? ( contained.value() )
2295 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
2298#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2300 constexpr value_type
const && value() const &&
2302 return std::move( has_value()
2303 ? ( contained.value() )
2304 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
2307 nsel_constexpr14 value_type && value() &&
2309 return std::move( has_value()
2310 ? ( contained.value() )
2311 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
2315 nsel_RESTORE_MSVC_WARNINGS()
2317 constexpr error_type const & error() const &
2319 return assert( ! has_value() ), contained.error();
2322 error_type &
error() &
2324 return assert( ! has_value() ), contained.error();
2327#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2329 constexpr error_type
const &&
error() const &&
2331 return std::move( ( assert( ! has_value() ), contained.error() ) );
2334 error_type &&
error() &&
2336 return std::move( ( assert( ! has_value() ), contained.error() ) );
2341 constexpr unexpected_type get_unexpected()
const
2343 return make_unexpected( contained.error() );
2346 template<
typename Ex >
2347 bool has_exception()
const
2349 using ContainedEx =
typename std::remove_reference<
decltype( get_unexpected().error() ) >::type;
2350 return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
2353 template<
typename U
2355 std::is_copy_constructible< T>::value
2356 && std::is_convertible<U&&, T>::value
2359 value_type value_or( U && v )
const &
2363 :
static_cast<T
>( std::forward<U>( v ) );
2366 template<
typename U
2368 std::is_move_constructible< T>::value
2369 && std::is_convertible<U&&, T>::value
2372 value_type value_or( U && v ) &&
2375 ? std::move( contained.value() )
2376 : static_cast<T>(
std::forward<U>( v ) );
2380 template<
typename G = E
2382 std::is_copy_constructible< E >::value
2383 && std::is_convertible< G, E >::value
2386 nsel_constexpr error_type error_or( G && e )
const &
2389 ?
static_cast< E
>( std::forward< G >( e ) )
2390 : contained.
error();
2393 template<
typename G = E
2395 std::is_move_constructible< E >::value
2396 && std::is_convertible< G, E >::value
2399 nsel_constexpr14 error_type error_or( G && e ) &&
2402 ?
static_cast< E
>( std::forward< G >( e ) )
2409 template<
typename F
2411 detail::is_expected < detail::invoke_result_nocvref_t< F, value_type & > > ::value
2412 && std::is_same<
typename detail::invoke_result_nocvref_t< F, value_type & >::error_type, error_type >::value
2413 && std::is_constructible< error_type, error_type & >::value
2416 nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type & > and_then( F && f ) &
2419 ? detail::invoke_result_nocvref_t< F, value_type & >( detail::invoke( std::forward< F >( f ), value() ) )
2420 : detail::invoke_result_nocvref_t< F, value_type & >( unexpect,
error() );
2425 detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type & > >::value
2426 && std::is_same<
typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
2427 && std::is_constructible< error_type, const error_type & >::value
2430 nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type & > and_then( F && f )
const &
2433 ? detail::invoke_result_nocvref_t< F, const value_type & >( detail::invoke( std::forward< F >( f ), value() ) )
2434 : detail::invoke_result_nocvref_t< F, const value_type & >( unexpect,
error() );
2437#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2440 detail::is_expected< detail::invoke_result_nocvref_t< F, value_type && > >::value
2441 && std::is_same<
typename detail::invoke_result_nocvref_t< F, value_type && >::error_type, error_type >::value
2442 && std::is_constructible< error_type, error_type && >::value
2445 nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type && > and_then( F && f ) &&
2448 ? detail::invoke_result_nocvref_t< F, value_type && >( detail::invoke( std::forward< F >( f ), std::move( value() ) ) )
2449 : detail::invoke_result_nocvref_t< F, value_type && >( unexpect,
std::move(
error() ) );
2454 detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type && > >::value
2455 && std::is_same<
typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
2456 && std::is_constructible< error_type, const error_type && >::value
2459 nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type && > and_then( F && f )
const &&
2462 ? detail::invoke_result_nocvref_t< F, const value_type && >( detail::invoke( std::forward< F >( f ), std::move( value() ) ) )
2463 : detail::invoke_result_nocvref_t< F, const value_type && >( unexpect,
std::move(
error() ) );
2469 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::value
2470 && std::is_same<
typename detail::invoke_result_nocvref_t< F, error_type & >::value_type, value_type >::value
2471 && std::is_constructible< value_type, value_type & >::value
2474 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F && f ) &
2477 ? detail::invoke_result_nocvref_t< F, error_type & >( value() )
2478 : detail::invoke_result_nocvref_t< F, error_type & >( detail::invoke(
std::forward< F >( f ),
error() ) );
2483 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::value
2484 && std::is_same<
typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type, value_type >::value
2485 && std::is_constructible< value_type, const value_type & >::value
2488 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F && f )
const &
2491 ? detail::invoke_result_nocvref_t< F, const error_type & >( value() )
2492 : detail::invoke_result_nocvref_t< F, const error_type & >( detail::invoke(
std::forward< F >( f ),
error() ) );
2495#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2498 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::value
2499 && std::is_same<
typename detail::invoke_result_nocvref_t< F, error_type && >::value_type, value_type >::value
2500 && std::is_constructible< value_type, value_type && >::value
2503 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F && f ) &&
2506 ? detail::invoke_result_nocvref_t< F, error_type && >( std::move( value() ) )
2507 : detail::invoke_result_nocvref_t< F, error_type && >( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
2512 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::value
2513 && std::is_same<
typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type, value_type >::value
2514 && std::is_constructible< value_type, const value_type && >::value
2517 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F && f )
const &&
2520 ? detail::invoke_result_nocvref_t< F, const error_type && >( std::move( value() ) )
2521 : detail::invoke_result_nocvref_t< F, const error_type && >( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
2527 std::is_constructible< error_type, error_type & >::value
2528 && !std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
2529 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type & > >::value
2532 nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type & >, error_type > transform( F && f ) &
2535 ? expected< detail::transform_invoke_result_t< F, value_type & >, error_type >( detail::invoke( std::forward< F >( f ), **
this ) )
2536 : make_unexpected(
error() );
2541 std::is_constructible< error_type, error_type & >::value
2542 && std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
2545 nsel_constexpr14 expected< void, error_type > transform( F && f ) &
2548 ? ( detail::invoke( std::forward< F >( f ), **
this ), expected< void, error_type >() )
2549 : make_unexpected(
error() );
2554 std::is_constructible< error_type, const error_type & >::value
2555 && !std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
2556 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type & > >::value
2559 nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type & >, error_type > transform( F && f )
const &
2562 ? expected< detail::transform_invoke_result_t< F, const value_type & >, error_type >( detail::invoke( std::forward< F >( f ), **
this ) )
2563 : make_unexpected(
error() );
2568 std::is_constructible< error_type, const error_type & >::value
2569 && std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
2572 nsel_constexpr expected< void, error_type > transform( F && f )
const &
2575 ? ( detail::invoke( std::forward< F >( f ), **
this ), expected< void, error_type >() )
2576 : make_unexpected(
error() );
2579#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2582 std::is_constructible< error_type, error_type && >::value
2583 && !std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
2584 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type && > >::value
2587 nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type && >, error_type > transform( F && f ) &&
2590 ? expected< detail::transform_invoke_result_t< F, value_type && >, error_type >( detail::invoke( std::forward< F >( f ), std::move( **
this ) ) )
2591 : make_unexpected(
std::move(
error() ) );
2596 std::is_constructible< error_type, error_type && >::value
2597 && std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
2600 nsel_constexpr14 expected< void, error_type > transform( F && f ) &&
2603 ? ( detail::invoke( std::forward< F >( f ), **
this ), expected< void, error_type >() )
2604 : make_unexpected(
std::move(
error() ) );
2609 std::is_constructible< error_type, const error_type && >::value
2610 && !std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
2611 && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type && > >::value
2614 nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type && >, error_type > transform( F && f )
const &&
2617 ? expected< detail::transform_invoke_result_t< F, const value_type && >, error_type >( detail::invoke( std::forward< F >( f ), std::move( **
this ) ) )
2618 : make_unexpected(
std::move(
error() ) );
2623 std::is_constructible< error_type, const error_type && >::value
2624 && std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
2627 nsel_constexpr expected< void, error_type > transform( F && f )
const &&
2630 ? ( detail::invoke( std::forward< F >( f ), **
this ), expected< void, error_type >() )
2631 : make_unexpected(
std::move(
error() ) );
2637 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::value
2638 && std::is_constructible< value_type, value_type & >::value
2641 nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type & > > transform_error( F && f ) &
2644 ? expected< value_type, detail::transform_invoke_result_t< F, error_type & > >(
in_place, **this )
2645 : make_unexpected( detail::invoke(
std::forward< F >( f ),
error() ) );
2650 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::value
2651 && std::is_constructible< value_type, const value_type & >::value
2654 nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F && f )
const &
2657 ? expected< value_type, detail::transform_invoke_result_t< F, const error_type & > >(
in_place, **this )
2658 : make_unexpected( detail::invoke(
std::forward< F >( f ),
error() ) );
2661#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2664 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::value
2665 && std::is_constructible< value_type, value_type && >::value
2668 nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type && > > transform_error( F && f ) &&
2671 ? expected< value_type, detail::transform_invoke_result_t< F, error_type && > >(
in_place, std::move( **
this ) )
2672 : make_unexpected( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
2677 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::value
2678 && std::is_constructible< value_type, const value_type && >::value
2681 nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F && f )
const &&
2684 ? expected< value_type, detail::transform_invoke_result_t< F, const error_type && > >(
in_place, std::move( **
this ) )
2685 : make_unexpected( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
2725 , std::is_copy_constructible<T>::value && std::is_copy_constructible<E>::value
2726 , std::is_move_constructible<T>::value && std::is_move_constructible<E>::value
2733template<
typename E >
2734class nsel_NODISCARD expected< void, E >
2737 template<
typename,
typename >
friend class expected;
2740 using value_type = void;
2741 using error_type = E;
2742 using unexpected_type = nonstd::unexpected_type<E>;
2746 constexpr expected() noexcept
2750 nsel_constexpr14 expected( expected
const & other ) =
default;
2751 nsel_constexpr14 expected( expected && other ) =
default;
2753 constexpr explicit expected( nonstd_lite_in_place_t(
void) )
2757 template<
typename G = E
2759 !std::is_convertible<G const &, E>::value
2762 nsel_constexpr14
explicit expected( nonstd::unexpected_type<G>
const & error )
2763 : contained( false )
2765 contained.construct_error( E{
error.error() } );
2768 template<
typename G = E
2770 std::is_convertible<G const &, E>::value
2773 nsel_constexpr14 expected( nonstd::unexpected_type<G>
const & error )
2774 : contained( false )
2776 contained.construct_error(
error.error() );
2779 template<
typename G = E
2781 !std::is_convertible<G&&, E>::value
2784 nsel_constexpr14
explicit expected( nonstd::unexpected_type<G> && error )
2785 : contained( false )
2787 contained.construct_error( E{ std::move(
error.error() ) } );
2790 template<
typename G = E
2792 std::is_convertible<G&&, E>::value
2795 nsel_constexpr14 expected( nonstd::unexpected_type<G> && error )
2796 : contained( false )
2798 contained.construct_error( std::move(
error.error() ) );
2801 template<
typename... Args
2803 std::is_constructible<E, Args&&...>::value
2806 nsel_constexpr14
explicit expected( unexpect_t, Args&&... args )
2807 : contained( false )
2809 contained.emplace_error( std::forward<Args>( args )... );
2812 template<
typename U,
typename... Args
2814 std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
2817 nsel_constexpr14
explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
2818 : contained( false )
2820 contained.emplace_error( il, std::forward<Args>( args )... );
2827 if ( ! has_value() )
2829 contained.destruct_error();
2835 expected & operator=( expected
const & other )
2837 expected( other ).swap( *
this );
2841 expected & operator=( expected && other )
noexcept
2843 std::is_nothrow_move_assignable<E>::value &&
2844 std::is_nothrow_move_constructible<E>::value )
2846 expected( std::move( other ) ).swap( *
this );
2852 expected().swap( *
this );
2857 template<
typename G = E >
2858 nsel_REQUIRES_R(
void,
2859 std17::is_swappable<G>::value
2860 && std::is_move_constructible<G>::value
2862 swap( expected & other )
noexcept
2864 std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
2869 if ( !
bool(*
this) && !
bool(other) ) { swap( contained.error(), other.contained.error() ); }
2870 else if (
bool(*
this) && !
bool(other) ) { contained.construct_error( std::move( other.error() ) );
2871 bool has_value = contained.has_value();
2872 bool other_has_value = other.has_value();
2873 other.contained.set_has_value(has_value);
2874 contained.set_has_value(other_has_value);
2876 else if ( !
bool(*
this) &&
bool(other) ) { other.swap( *
this ); }
2881 constexpr explicit operator bool() const noexcept
2886 constexpr bool has_value() const noexcept
2888 return contained.has_value();
2893 if ( ! has_value() )
2895 error_traits<error_type>::rethrow( contained.error() );
2899 constexpr error_type
const &
error() const &
2901 return assert( ! has_value() ), contained.error();
2904 error_type &
error() &
2906 return assert( ! has_value() ), contained.error();
2909#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2911 constexpr error_type
const &&
error() const &&
2913 return std::move( ( assert( ! has_value() ), contained.error() ) );
2916 error_type &&
error() &&
2918 return std::move( ( assert( ! has_value() ), contained.error() ) );
2923 constexpr unexpected_type get_unexpected()
const
2925 return make_unexpected( contained.error() );
2928 template<
typename Ex >
2929 bool has_exception()
const
2931 using ContainedEx =
typename std::remove_reference<
decltype( get_unexpected().error() ) >::type;
2932 return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
2936 template<
typename G = E
2938 std::is_copy_constructible< E >::value
2939 && std::is_convertible< G, E >::value
2942 nsel_constexpr error_type error_or( G && e )
const &
2945 ?
static_cast< E
>( std::forward< G >( e ) )
2946 : contained.
error();
2949 template<
typename G = E
2951 std::is_move_constructible< E >::value
2952 && std::is_convertible< G, E >::value
2955 nsel_constexpr14 error_type error_or( G && e ) &&
2958 ?
static_cast< E
>( std::forward< G >( e ) )
2967 detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
2968 && std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
2969 && std::is_constructible< error_type, error_type & >::value
2972 nsel_constexpr14 detail::invoke_result_nocvref_t< F > and_then( F && f ) &
2975 ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
2976 : detail::invoke_result_nocvref_t< F >( unexpect,
error() );
2981 detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
2982 && std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
2983 && std::is_constructible< error_type, const error_type & >::value
2986 nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F && f )
const &
2989 ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
2990 : detail::invoke_result_nocvref_t< F >( unexpect,
error() );
2993#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
2996 detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
2997 && std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
2998 && std::is_constructible< error_type, error_type && >::value
3001 nsel_constexpr14 detail::invoke_result_nocvref_t< F > and_then( F && f ) &&
3004 ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
3005 : detail::invoke_result_nocvref_t< F >( unexpect,
std::move(
error() ) );
3010 detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
3011 && std::is_same<
typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
3012 && std::is_constructible< error_type, const error_type && >::value
3015 nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F && f )
const &&
3018 ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
3019 : detail::invoke_result_nocvref_t< F >( unexpect,
std::move(
error() ) );
3025 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::value
3026 && std::is_void<
typename detail::invoke_result_nocvref_t< F, error_type & >::value_type >::value
3029 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F && f ) &
3032 ? detail::invoke_result_nocvref_t< F, error_type & >()
3033 : detail::invoke_result_nocvref_t< F, error_type & >( detail::invoke(
std::forward< F >( f ),
error() ) );
3038 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::value
3039 && std::is_void<
typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type >::value
3042 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F && f )
const &
3045 ? detail::invoke_result_nocvref_t< F, const error_type & >()
3046 : detail::invoke_result_nocvref_t< F, const error_type & >( detail::invoke(
std::forward< F >( f ),
error() ) );
3049#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
3052 detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::value
3053 && std::is_void<
typename detail::invoke_result_nocvref_t< F, error_type && >::value_type >::value
3056 nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F && f ) &&
3059 ? detail::invoke_result_nocvref_t< F, error_type && >()
3060 : detail::invoke_result_nocvref_t< F, error_type && >( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
3065 detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::value
3066 && std::is_void<
typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type >::value
3069 nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F && f )
const &&
3072 ? detail::invoke_result_nocvref_t< F, const error_type && >()
3073 : detail::invoke_result_nocvref_t< F, const error_type && >( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
3079 std::is_constructible< error_type, error_type & >::value
3080 && !std::is_void< detail::transform_invoke_result_t< F > >::value
3083 nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) &
3086 ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
3087 : make_unexpected(
error() );
3092 std::is_constructible< error_type, error_type & >::value
3093 && std::is_void< detail::transform_invoke_result_t< F > >::value
3096 nsel_constexpr14 expected< void, error_type > transform( F && f ) &
3099 ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
3100 : make_unexpected(
error() );
3105 std::is_constructible< error_type, const error_type & >::value
3106 && !std::is_void< detail::transform_invoke_result_t< F > >::value
3109 nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f )
const &
3112 ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
3113 : make_unexpected(
error() );
3118 std::is_constructible< error_type, const error_type & >::value
3119 && std::is_void< detail::transform_invoke_result_t< F > >::value
3122 nsel_constexpr expected< void, error_type > transform( F && f )
const &
3125 ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
3126 : make_unexpected(
error() );
3129#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
3132 std::is_constructible< error_type, error_type && >::value
3133 && !std::is_void< detail::transform_invoke_result_t< F > >::value
3136 nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) &&
3139 ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
3140 : make_unexpected(
error() );
3145 std::is_constructible< error_type, error_type && >::value
3146 && std::is_void< detail::transform_invoke_result_t< F > >::value
3149 nsel_constexpr14 expected< void, error_type > transform( F && f ) &&
3152 ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
3153 : make_unexpected(
error() );
3158 std::is_constructible< error_type, const error_type && >::value
3159 && !std::is_void< detail::transform_invoke_result_t< F > >::value
3162 nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f )
const &&
3165 ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
3166 : make_unexpected(
error() );
3171 std::is_constructible< error_type, const error_type && >::value
3172 && std::is_void< detail::transform_invoke_result_t< F > >::value
3175 nsel_constexpr expected< void, error_type > transform( F && f )
const &&
3178 ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
3179 : make_unexpected(
error() );
3185 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::value
3188 nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type & > > transform_error( F && f ) &
3191 ? expected< void, detail::transform_invoke_result_t< F, error_type & > >()
3192 : make_unexpected( detail::invoke(
std::forward< F >( f ),
error() ) );
3197 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::value
3200 nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F && f )
const &
3203 ? expected< void, detail::transform_invoke_result_t< F, const error_type & > >()
3204 : make_unexpected( detail::invoke(
std::forward< F >( f ),
error() ) );
3207#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
3210 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::value
3213 nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type && > > transform_error( F && f ) &&
3216 ? expected< void, detail::transform_invoke_result_t< F, error_type && > >()
3217 : make_unexpected( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
3222 detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::value
3225 nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F && f )
const &&
3228 ? expected< void, detail::transform_invoke_result_t< F, const error_type && > >()
3229 : make_unexpected( detail::invoke(
std::forward< F >( f ),
std::move(
error() ) ) );
3260 , std::is_copy_constructible<E>::value
3261 , std::is_move_constructible<E>::value
3268template<
typename T1,
typename E1,
typename T2,
typename E2
3270 !std::is_void<T1>::value && !std::is_void<T2>::value
3273constexpr bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3275 return bool(x) != bool(y) ? false : bool(x) ? *x == *y : x.error() == y.error();
3278template<
typename T1,
typename E1,
typename T2,
typename E2
3280 std::is_void<T1>::value && std::is_void<T2>::value
3283constexpr bool operator==( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3285 return bool(x) != bool(y) ? false : bool(x) ||
static_cast<bool>( x.error() == y.error() );
3288template<
typename T1,
typename E1,
typename T2,
typename E2 >
3289constexpr bool operator!=( expected<T1,E1>
const & x, expected<T2,E2>
const & y )
3296template<
typename T,
typename E >
3297constexpr bool operator<( expected<T,E>
const & x, expected<T,E>
const & y )
3299 return (!y) ? false : (!x) ?
true : *x < *y;
3302template<
typename T,
typename E >
3303constexpr bool operator>( expected<T,E>
const & x, expected<T,E>
const & y )
3308template<
typename T,
typename E >
3309constexpr bool operator<=( expected<T,E>
const & x, expected<T,E>
const & y )
3314template<
typename T,
typename E >
3315constexpr bool operator>=( expected<T,E>
const & x, expected<T,E>
const & y )
3324template<
typename T1,
typename E1,
typename T2
3326 !std::is_void<T1>::value
3329constexpr bool operator==( expected<T1,E1>
const & x, T2
const & v )
3331 return bool(x) ? *x == v :
false;
3334template<
typename T1,
typename E1,
typename T2
3336 !std::is_void<T1>::value
3339constexpr bool operator==(T2
const & v, expected<T1,E1>
const & x )
3341 return bool(x) ? v == *x :
false;
3344template<
typename T1,
typename E1,
typename T2 >
3345constexpr bool operator!=( expected<T1,E1>
const & x, T2
const & v )
3347 return bool(x) ? *x != v :
true;
3350template<
typename T1,
typename E1,
typename T2 >
3351constexpr bool operator!=( T2
const & v, expected<T1,E1>
const & x )
3353 return bool(x) ? v != *x :
true;
3358template<
typename T,
typename E >
3359constexpr bool operator<( expected<T,E>
const & x, T
const & v )
3361 return bool(x) ? *x < v :
true;
3364template<
typename T,
typename E >
3365constexpr bool operator<( T
const & v, expected<T,E>
const & x )
3367 return bool(x) ? v < *x :
false;
3370template<
typename T,
typename E >
3371constexpr bool operator>( T
const & v, expected<T,E>
const & x )
3373 return bool(x) ? *x < v :
false;
3376template<
typename T,
typename E >
3377constexpr bool operator>( expected<T,E>
const & x, T
const & v )
3379 return bool(x) ? v < *x :
false;
3382template<
typename T,
typename E >
3383constexpr bool operator<=( T
const & v, expected<T,E>
const & x )
3385 return bool(x) ? ! ( *x < v ) : false;
3388template<
typename T,
typename E >
3389constexpr bool operator<=( expected<T,E>
const & x, T
const & v )
3391 return bool(x) ? ! ( v < *x ) : true;
3394template<
typename T,
typename E >
3395constexpr bool operator>=( expected<T,E>
const & x, T
const & v )
3397 return bool(x) ? ! ( *x < v ) : false;
3400template<
typename T,
typename E >
3401constexpr bool operator>=( T
const & v, expected<T,E>
const & x )
3403 return bool(x) ? ! ( v < *x ) : true;
3410template<
typename T1,
typename E1 ,
typename E2 >
3411constexpr bool operator==( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
3413 return (!x) ? x.get_unexpected() == u :
false;
3416template<
typename T1,
typename E1 ,
typename E2 >
3417constexpr bool operator==( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
3422template<
typename T1,
typename E1 ,
typename E2 >
3423constexpr bool operator!=( expected<T1,E1>
const & x, unexpected_type<E2>
const & u )
3425 return ! ( x == u );
3428template<
typename T1,
typename E1 ,
typename E2 >
3429constexpr bool operator!=( unexpected_type<E2>
const & u, expected<T1,E1>
const & x )
3431 return ! ( x == u );
3436template<
typename T,
typename E >
3437constexpr bool operator<( expected<T,E>
const & x, unexpected_type<E>
const & u )
3439 return (!x) ? ( x.get_unexpected() < u ) :
false;
3442template<
typename T,
typename E >
3443constexpr bool operator<( unexpected_type<E>
const & u, expected<T,E>
const & x )
3445 return (!x) ? ( u < x.get_unexpected() ) : true ;
3448template<
typename T,
typename E >
3449constexpr bool operator>( expected<T,E>
const & x, unexpected_type<E>
const & u )
3454template<
typename T,
typename E >
3455constexpr bool operator>( unexpected_type<E>
const & u, expected<T,E>
const & x )
3460template<
typename T,
typename E >
3461constexpr bool operator<=( expected<T,E>
const & x, unexpected_type<E>
const & u )
3466template<
typename T,
typename E >
3467constexpr bool operator<=( unexpected_type<E>
const & u, expected<T,E>
const & x)
3472template<
typename T,
typename E >
3473constexpr bool operator>=( expected<T,E>
const & x, unexpected_type<E>
const & u )
3478template<
typename T,
typename E >
3479constexpr bool operator>=( unexpected_type<E>
const & u, expected<T,E>
const & x )
3488template<
typename T,
typename E
3490 ( std::is_void<T>::value || std::is_move_constructible<T>::value )
3491 && std::is_move_constructible<E>::value
3492 && std17::is_swappable<T>::value
3493 && std17::is_swappable<E>::value )
3495void swap( expected<T,E> & x, expected<T,E> & y )
noexcept (
noexcept ( x.swap(y) ) )
3502template<
typename T >
3503constexpr auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
3505 return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
3510auto inline make_expected() -> expected<void>
3512 return expected<void>( in_place );
3515template<
typename T >
3516constexpr auto make_expected_from_current_exception() -> expected<T>
3518 return expected<T>( make_unexpected_from_current_exception() );
3521template<
typename T >
3522auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
3524 return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
3527template<
typename T,
typename E >
3528constexpr auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
3530 return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
3534 nsel_REQUIRES_T( ! std::is_same<
typename std::result_of<F()>::type,
void>::value )
3537auto make_expected_from_call( F f ) -> expected<
typename std::result_of<F()>::type >
3541 return make_expected( f() );
3545 return make_unexpected_from_current_exception();
3550 nsel_REQUIRES_T( std::is_same<
typename std::result_of<F()>::type,
void>::value )
3553auto make_expected_from_call( F f ) -> expected<void>
3558 return make_expected();
3562 return make_unexpected_from_current_exception();
3570using namespace expected_lite;
3581template<
typename T,
typename E >
3589 return arg ? std::hash<T>{}(*arg) :
result_type{};
3594template<
typename T,
typename E >
3602 return arg ? std::hash<T>{}(*arg) :
result_type{};
3611template<
typename E >
3622#if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141
3623template<
typename E >
3624using unexpected = unexpected_type<E>;
3630#undef nsel_REQUIRES_0
3631#undef nsel_REQUIRES_T
3633nsel_RESTORE_WARNINGS()
void error(const char *msg)
Send error message to std::cerr.
Definition logging_utils.cpp:33
std::is_same< bool_pack< true, Bs... >, bool_pack< Bs..., true > > conjunction
Definition traits.hpp:19
Definition expected.hpp:190
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition expected.hpp:216
in_place_t in_place_index(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
Definition expected.hpp:222
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition expected.hpp:204
Definition expected.hpp:197
Definition expected.hpp:194
Definition expected.hpp:201
std::size_t result_type
Definition expected.hpp:3584
nonstd::expected< T, E > argument_type
Definition expected.hpp:3585
constexpr result_type operator()(argument_type const &arg) const
Definition expected.hpp:3587
nonstd::expected< T &, E > argument_type
Definition expected.hpp:3598
std::size_t result_type
Definition expected.hpp:3597
constexpr result_type operator()(argument_type const &arg) const
Definition expected.hpp:3600