00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef NONSTD_EXPECTED_LITE_HPP
00013 #define NONSTD_EXPECTED_LITE_HPP
00014
00015 #define expected_lite_MAJOR 0
00016 #define expected_lite_MINOR 2
00017 #define expected_lite_PATCH 0
00018
00019 #define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH)
00020
00021 #define expected_STRINGIFY( x ) expected_STRINGIFY_( x )
00022 #define expected_STRINGIFY_( x ) #x
00023
00024
00025
00026 #define nsel_EXPECTED_DEFAULT 0
00027 #define nsel_EXPECTED_NONSTD 1
00028 #define nsel_EXPECTED_STD 2
00029
00030 #if !defined( nsel_CONFIG_SELECT_EXPECTED )
00031 # define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD )
00032 #endif
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef nsel_P0323R
00052 # define nsel_P0323R 5
00053 #endif
00054
00055
00056
00057
00058 #ifndef nsel_CPLUSPLUS
00059 # if defined(_MSVC_LANG ) && !defined(__clang__)
00060 # define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
00061 # else
00062 # define nsel_CPLUSPLUS __cplusplus
00063 # endif
00064 #endif
00065
00066 #define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L )
00067 #define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L )
00068 #define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L )
00069 #define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L )
00070 #define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202000L )
00071
00072
00073
00074 #if nsel_CPP20_OR_GREATER && defined(__has_include )
00075 # if __has_include( <expected> )
00076 # define nsel_HAVE_STD_EXPECTED 1
00077 # else
00078 # define nsel_HAVE_STD_EXPECTED 0
00079 # endif
00080 #else
00081 # define nsel_HAVE_STD_EXPECTED 0
00082 #endif
00083
00084 #define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) )
00085
00086
00087
00088
00089
00090 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
00091 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
00092
00093
00094
00095 #if nsel_CPP17_OR_GREATER
00096
00097 #include <utility>
00098
00099 namespace nonstd {
00100
00101 using std::in_place;
00102 using std::in_place_type;
00103 using std::in_place_index;
00104 using std::in_place_t;
00105 using std::in_place_type_t;
00106 using std::in_place_index_t;
00107
00108 #define nonstd_lite_in_place_t( T) std::in_place_t
00109 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
00110 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
00111
00112 #define nonstd_lite_in_place( T) std::in_place_t{}
00113 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
00114 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
00115
00116 }
00117
00118 #else // nsel_CPP17_OR_GREATER
00119
00120 #include <cstddef>
00121
00122 namespace nonstd {
00123 namespace detail {
00124
00125 template< class T >
00126 struct in_place_type_tag {};
00127
00128 template< std::size_t K >
00129 struct in_place_index_tag {};
00130
00131 }
00132
00133 struct in_place_t {};
00134
00135 template< class T >
00136 inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
00137 {
00138 return in_place_t();
00139 }
00140
00141 template< std::size_t K >
00142 inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
00143 {
00144 return in_place_t();
00145 }
00146
00147 template< class T >
00148 inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
00149 {
00150 return in_place_t();
00151 }
00152
00153 template< std::size_t K >
00154 inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
00155 {
00156 return in_place_t();
00157 }
00158
00159
00160
00161 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
00162 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
00163 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
00164
00165 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
00166 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
00167 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
00168
00169 }
00170
00171 #endif // nsel_CPP17_OR_GREATER
00172 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
00173
00174
00175
00176
00177
00178 #if nsel_USES_STD_EXPECTED
00179
00180 #include <expected>
00181
00182 namespace nonstd {
00183
00184 using std::expected;
00185
00186 }
00187
00188 #else // nsel_USES_STD_EXPECTED
00189
00190 #include <cassert>
00191 #include <exception>
00192 #include <functional>
00193 #include <initializer_list>
00194 #include <new>
00195 #include <stdexcept>
00196 #include <system_error>
00197 #include <type_traits>
00198 #include <utility>
00199
00200 #if nsel_CPP11_OR_GREATER
00201 # define nsel_constexpr constexpr
00202 #else
00203 # define nsel_constexpr
00204 #endif
00205
00206 #if nsel_CPP14_OR_GREATER
00207 # define nsel_constexpr14 constexpr
00208 #else
00209 # define nsel_constexpr14
00210 #endif
00211
00212 #if nsel_CPP17_OR_GREATER
00213 # define nsel_inline17 inline
00214 #else
00215 # define nsel_inline17
00216 #endif
00217
00218
00219
00220 #define nsel_REQUIRES_A(...) \
00221 , typename std::enable_if<__VA_ARGS__, void*>::type = nullptr
00222
00223 #define nsel_REQUIRES_0(...) \
00224 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
00225
00226 #define nsel_REQUIRES_R(R, ...) \
00227 typename std::enable_if<__VA_ARGS__, R>::type
00228
00229 #define nsel_REQUIRES_T(...) \
00230 , typename = typename std::enable_if< (__VA_ARGS__), nonstd::expected_lite::detail::enabler >::type
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 #if defined(_MSC_VER) && !defined(__clang__)
00246 # define nsel_COMPILER_MSVC_VER (_MSC_VER )
00247 # define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
00248 #else
00249 # define nsel_COMPILER_MSVC_VER 0
00250 # define nsel_COMPILER_MSVC_VERSION 0
00251 #endif
00252
00253 #define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
00254
00255 #if defined(__clang__)
00256 # define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
00257 #else
00258 # define nsel_COMPILER_CLANG_VERSION 0
00259 #endif
00260
00261 #if defined(__GNUC__) && !defined(__clang__)
00262 # define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
00263 #else
00264 # define nsel_COMPILER_GNUC_VERSION 0
00265 #endif
00266
00267
00268
00269
00270
00271
00272 #ifdef _HAS_CPP0X
00273 # define nsel_HAS_CPP0X _HAS_CPP0X
00274 #else
00275 # define nsel_HAS_CPP0X 0
00276 #endif
00277
00278
00279
00280
00281
00282 #ifdef __clang__
00283 # pragma clang diagnostic push
00284 #elif defined __GNUC__
00285 # pragma GCC diagnostic push
00286 #endif // __clang__
00287
00288 #if nsel_COMPILER_MSVC_VERSION >= 140
00289 # pragma warning( push )
00290 # define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(disable: codes) )
00291 #else
00292 # define nsel_DISABLE_MSVC_WARNINGS(codes)
00293 #endif
00294
00295 #ifdef __clang__
00296 # define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
00297 #elif defined __GNUC__
00298 # define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
00299 #elif nsel_COMPILER_MSVC_VERSION >= 140
00300 # define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) )
00301 #else
00302 # define nsel_RESTORE_WARNINGS()
00303 #endif
00304
00305
00306
00307
00308 nsel_DISABLE_MSVC_WARNINGS( 26409 )
00309
00310
00311
00312
00313
00314 namespace nonstd { namespace expected_lite {
00315
00316 namespace std20 {
00317
00318
00319
00320 template< typename T >
00321 struct remove_cvref
00322 {
00323 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
00324 };
00325
00326 }
00327
00328
00329
00330 template< typename T, typename E >
00331 class expected;
00332
00333 namespace detail {
00334
00336
00337 enum class enabler{};
00338
00340
00341 template< typename T, typename E >
00342 union storage_t
00343 {
00344 friend class expected<T,E>;
00345
00346 private:
00347 using value_type = T;
00348 using error_type = E;
00349
00350
00351 storage_t() {}
00352 ~storage_t() {}
00353
00354 template<class ...Args>
00355 void construct_value(Args&& ...args)
00356 {
00357 new(&m_value) value_type(std::forward<Args>(args)...);
00358 }
00359
00360 void destruct_value()
00361 {
00362 m_value.~value_type();
00363 }
00364
00365 void construct_error( error_type const & e )
00366 {
00367 new( &m_error ) error_type( e );
00368 }
00369
00370 void construct_error( error_type && e )
00371 {
00372 new( &m_error ) error_type( std::move( e ) );
00373 }
00374
00375 void destruct_error()
00376 {
00377 m_error.~error_type();
00378 }
00379
00380 constexpr value_type const & value() const &
00381 {
00382 return m_value;
00383 }
00384
00385 value_type & value() &
00386 {
00387 return m_value;
00388 }
00389
00390 constexpr value_type const && value() const &&
00391 {
00392 return std::move( m_value );
00393 }
00394
00395 nsel_constexpr14 value_type && value() &&
00396 {
00397 return std::move( m_value );
00398 }
00399
00400 value_type const * value_ptr() const
00401 {
00402 return &m_value;
00403 }
00404
00405 value_type * value_ptr()
00406 {
00407 return &m_value;
00408 }
00409
00410 error_type const & error() const
00411 {
00412 return m_error;
00413 }
00414
00415 error_type & error()
00416 {
00417 return m_error;
00418 }
00419
00420 private:
00421 value_type m_value;
00422 error_type m_error;
00423 };
00424
00426
00427 template< typename E >
00428 union storage_t<void, E>
00429 {
00430 friend class expected<void,E>;
00431
00432 private:
00433 using value_type = void;
00434 using error_type = E;
00435
00436
00437 storage_t() {}
00438 ~storage_t() {}
00439
00440 void construct_error( error_type const & e )
00441 {
00442 new( &m_error ) error_type( e );
00443 }
00444
00445 void construct_error( error_type && e )
00446 {
00447 new( &m_error ) error_type( std::move( e ) );
00448 }
00449
00450 void destruct_error()
00451 {
00452 m_error.~error_type();
00453 }
00454
00455 error_type const & error() const
00456 {
00457 return m_error;
00458 }
00459
00460 error_type & error()
00461 {
00462 return m_error;
00463 }
00464
00465 private:
00466 error_type m_error;
00467 };
00468
00469 }
00470
00472
00473 #if nsel_P0323R <= 2
00474 template< typename E = std::exception_ptr >
00475 class unexpected_type
00476 #else
00477 template< typename E >
00478 class unexpected_type
00479 #endif
00480 {
00481 public:
00482 using error_type = E;
00483
00484 unexpected_type() = delete;
00485 constexpr unexpected_type( unexpected_type const &) = default;
00486 constexpr unexpected_type( unexpected_type &&) = default;
00487 nsel_constexpr14 unexpected_type& operator=( unexpected_type const &) = default;
00488 nsel_constexpr14 unexpected_type& operator=( unexpected_type &&) = default;
00489
00490 template< typename E2
00491 nsel_REQUIRES_T(
00492 std::is_constructible<E,E2&&>::value
00493 )
00494 >
00495 constexpr explicit unexpected_type( E2 && error )
00496 : m_error( std::forward<E2>( error ) )
00497 {}
00498
00499 template< typename E2 >
00500 constexpr explicit unexpected_type( unexpected_type<E2> const & error
00501 nsel_REQUIRES_A(
00502 std::is_constructible<E,E2 const &>::value
00503 && !std::is_convertible<E2 const &, E>::value )
00504 )
00505 : m_error( error )
00506 {}
00507
00508 template< typename E2 >
00509 constexpr unexpected_type( unexpected_type<E2> const & error
00510 nsel_REQUIRES_A(
00511 std::is_constructible<E,E2 const &>::value
00512 && std::is_convertible<E2 const &, E>::value )
00513 )
00514 : m_error( error )
00515 {}
00516
00517 template< typename E2 >
00518 constexpr explicit unexpected_type( unexpected_type<E2> && error
00519 nsel_REQUIRES_A(
00520 std::is_constructible<E,E2&&>::value
00521 && !std::is_convertible<E2&&, E>::value )
00522 )
00523 : m_error( error )
00524 {}
00525
00526 template< typename E2 >
00527 constexpr unexpected_type( unexpected_type<E2> && error
00528 nsel_REQUIRES_A(
00529 std::is_constructible<E,E2&&>::value
00530 && std::is_convertible<E2&&, E>::value )
00531 )
00532 : m_error( error )
00533 {}
00534
00535 nsel_constexpr14 E & value() & noexcept
00536 {
00537 return m_error;
00538 }
00539
00540 constexpr E const & value() const & noexcept
00541 {
00542 return m_error;
00543 }
00544
00545 nsel_constexpr14 E && value() && noexcept
00546 {
00547 return std::move( m_error );
00548 }
00549
00550 constexpr E const && value() const && noexcept
00551 {
00552 return std::move( m_error );
00553 }
00554
00555
00556
00557
00558
00559
00560 void swap( unexpected_type & other ) noexcept (
00561 #if nsel_CPP17_OR_GREATER
00562 std::is_nothrow_move_constructible<E>::value
00563 && std::is_nothrow_swappable<E&>::value
00564 #else
00565 std::is_nothrow_move_constructible<E>::value
00566 && noexcept ( std::swap( std::declval<E&>(), std::declval<E&>() ) )
00567 #endif
00568 )
00569 {
00570 using std::swap;
00571 swap( m_error, other.m_error );
00572 }
00573
00574 private:
00575 error_type m_error;
00576 };
00577
00579
00580 #if nsel_P0323R <= 2
00581
00582 template<>
00583 class unexpected_type< std::exception_ptr >
00584 {
00585 public:
00586 using error_type = std::exception_ptr;
00587
00588 unexpected_type() = delete;
00589
00590 ~unexpected_type(){}
00591
00592 explicit unexpected_type( std::exception_ptr const & error )
00593 : m_error( error )
00594 {}
00595
00596 explicit unexpected_type(std::exception_ptr && error )
00597 : m_error( std::move( error ) )
00598 {}
00599
00600 template< typename E >
00601 explicit unexpected_type( E error )
00602 : m_error( std::make_exception_ptr( error ) )
00603 {}
00604
00605 std::exception_ptr const & value() const
00606 {
00607 return m_error;
00608 }
00609
00610 std::exception_ptr & value()
00611 {
00612 return m_error;
00613 }
00614
00615 private:
00616 std::exception_ptr m_error;
00617 };
00618
00619 #endif // nsel_P0323R
00620
00622
00623 template< typename E >
00624 constexpr bool operator==( unexpected_type<E> const & x, unexpected_type<E> const & y )
00625 {
00626 return x.value() == y.value();
00627 }
00628
00629 template< typename E >
00630 constexpr bool operator!=( unexpected_type<E> const & x, unexpected_type<E> const & y )
00631 {
00632 return ! ( x == y );
00633 }
00634
00635 #if nsel_P0323R <= 2
00636
00637 template< typename E >
00638 constexpr bool operator<( unexpected_type<E> const & x, unexpected_type<E> const & y )
00639 {
00640 return x.value() < y.value();
00641 }
00642
00643 template< typename E >
00644 constexpr bool operator>( unexpected_type<E> const & x, unexpected_type<E> const & y )
00645 {
00646 return ( y < x );
00647 }
00648
00649 template< typename E >
00650 constexpr bool operator<=( unexpected_type<E> const & x, unexpected_type<E> const & y )
00651 {
00652 return ! ( y < x );
00653 }
00654
00655 template< typename E >
00656 constexpr bool operator>=( unexpected_type<E> const & x, unexpected_type<E> const & y )
00657 {
00658 return ! ( x < y );
00659 }
00660
00662
00663 template< typename E >
00664 void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
00665 {
00666 x.swap( y );
00667 }
00668
00669
00670
00671 inline constexpr bool operator<( unexpected_type<std::exception_ptr> const & , unexpected_type<std::exception_ptr> const & )
00672 {
00673 return false;
00674 }
00675
00676 inline constexpr bool operator>( unexpected_type<std::exception_ptr> const & , unexpected_type<std::exception_ptr> const & )
00677 {
00678 return false;
00679 }
00680
00681 inline constexpr bool operator<=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
00682 {
00683 return ( x == y );
00684 }
00685
00686 inline constexpr bool operator>=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
00687 {
00688 return ( x == y );
00689 }
00690
00691 #endif // nsel_P0323R
00692
00693
00694
00695 #if nsel_P0323R <= 3
00696
00697 template< typename E>
00698 struct is_unexpected : std::false_type {};
00699
00700 template< typename E>
00701 struct is_unexpected< unexpected_type<E> > : std::true_type {};
00702
00703 #endif // nsel_P0323R
00704
00705
00706
00707
00708
00709 template< typename E>
00710 nsel_constexpr14 auto
00711 make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
00712 {
00713 return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
00714 }
00715
00716 #if nsel_P0323R <= 3
00717
00718 auto inline
00719 make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
00720 {
00721 return unexpected_type< std::exception_ptr >( std::current_exception() );
00722 }
00723
00724 #endif // nsel_P0323R
00725
00727
00728 struct unexpect_t{};
00729 using in_place_unexpected_t = unexpect_t;
00730
00731 nsel_inline17 constexpr unexpect_t unexpect{};
00732 nsel_inline17 constexpr unexpect_t in_place_unexpected{};
00733
00735
00736 template< typename E >
00737 class bad_expected_access;
00738
00739 template <>
00740 class bad_expected_access< void > : public std::exception
00741 {
00742 public:
00743 explicit bad_expected_access()
00744 : std::exception()
00745 {}
00746 };
00747
00748 template< typename E >
00749 class bad_expected_access : public bad_expected_access< void >
00750 {
00751 public:
00752 using error_type = E;
00753
00754 explicit bad_expected_access( error_type error )
00755 : m_error( error )
00756 {}
00757
00758 virtual char const * what() const noexcept override
00759 {
00760 return "bad_expected_access";
00761 }
00762
00763 nsel_constexpr14 error_type & error() &
00764 {
00765 return m_error;
00766 }
00767
00768 constexpr error_type const & error() const &
00769 {
00770 return m_error;
00771 }
00772
00773 nsel_constexpr14 error_type && error() &&
00774 {
00775 return std::move( m_error );
00776 }
00777
00778 constexpr error_type const && error() const &&
00779 {
00780 return std::move( m_error );
00781 }
00782
00783 private:
00784 error_type m_error;
00785 };
00786
00788
00789 template< typename Error >
00790 struct error_traits
00791 {
00792 static void rethrow( Error const & e )
00793 {
00794 throw bad_expected_access<Error>{ e };
00795 }
00796 };
00797
00798 template<>
00799 struct error_traits< std::exception_ptr >
00800 {
00801 static void rethrow( std::exception_ptr const & e )
00802 {
00803 std::rethrow_exception( e );
00804 }
00805 };
00806
00807 template<>
00808 struct error_traits< std::error_code >
00809 {
00810 static void rethrow( std::error_code const & e )
00811 {
00812 throw std::system_error( e );
00813 }
00814 };
00815
00816 }
00817
00818
00819
00820 using expected_lite::unexpected_type;
00821
00822 namespace expected_lite {
00823
00825
00826 #if nsel_P0323R <= 2
00827 template< typename T, typename E = std::exception_ptr >
00828 class expected
00829 #else
00830 template< typename T, typename E >
00831 class expected
00832 #endif
00833 {
00834 public:
00835 using value_type = T;
00836 using error_type = E;
00837 using unexpected_type = nonstd::unexpected_type<E>;
00838
00839 template< typename U >
00840 struct rebind
00841 {
00842 using type = expected<U, error_type>;
00843 };
00844
00845
00846
00847 nsel_REQUIRES_0(
00848 std::is_default_constructible<T>::value
00849 )
00850 nsel_constexpr14 expected() noexcept
00851 (
00852 std::is_nothrow_default_constructible<T>::value
00853 )
00854 : has_value_( true )
00855 {
00856 contained.construct_value( value_type() );
00857 }
00858
00859 nsel_constexpr14 expected( expected const & other
00860
00861
00862
00863
00864 )
00865 : has_value_( other.has_value_ )
00866 {
00867 if ( has_value() ) contained.construct_value( other.contained.value() );
00868 else contained.construct_error( other.contained.error() );
00869 }
00870
00871 nsel_constexpr14 expected( expected && other
00872
00873
00874
00875
00876 ) noexcept (
00877 std::is_nothrow_move_constructible<T>::value
00878 && std::is_nothrow_move_constructible<E>::value
00879 )
00880 : has_value_( other.has_value_ )
00881 {
00882 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
00883 else contained.construct_error( std::move( other.contained.error() ) );
00884 }
00885
00886 template< typename U, typename G >
00887 nsel_constexpr14 explicit expected( expected<U, G> const & other
00888 nsel_REQUIRES_A(
00889 std::is_constructible<T, const U&>::value
00890 && std::is_constructible<E, const G&>::value
00891 && !std::is_constructible<T, expected<U, G>&>::value
00892 && !std::is_constructible<T, expected<U, G>&&>::value
00893 && !std::is_constructible<T, const expected<U, G>&>::value
00894 && !std::is_constructible<T, const expected<U, G>&&>::value
00895 && !std::is_convertible<expected<U, G>&, T>::value
00896 && !std::is_convertible<expected<U, G>&&, T>::value
00897 && !std::is_convertible<const expected<U, G>&, T>::value
00898 && !std::is_convertible<const expected<U, G>&&, T>::value
00899 && (!std::is_convertible<U const&, T>::value || !std::is_convertible<const G&, E>::value ) )
00900 )
00901 : has_value_( other.has_value_ )
00902 {
00903 if ( has_value() ) contained.construct_value( other.contained.value() );
00904 else contained.construct_error( other.contained.error() );
00905 }
00906
00907 template< typename U, typename G >
00908 nsel_constexpr14 expected( expected<U, G> const & other
00909 nsel_REQUIRES_A(
00910 std::is_constructible<T, const U&>::value
00911 && std::is_constructible<E, const G&>::value
00912 && !std::is_constructible<T, expected<U, G>&>::value
00913 && !std::is_constructible<T, expected<U, G>&&>::value
00914 && !std::is_constructible<T, const expected<U, G>&>::value
00915 && !std::is_constructible<T, const expected<U, G>&&>::value
00916 && !std::is_convertible<expected<U, G>&, T>::value
00917 && !std::is_convertible<expected<U, G>&&, T>::value
00918 && !std::is_convertible<const expected<U, G>&, T>::value
00919 && !std::is_convertible<const expected<U, G>&&, T>::value
00920 && !(!std::is_convertible<U const&, T>::value || !std::is_convertible<const G&, E>::value ) )
00921 )
00922 : has_value_( other.has_value_ )
00923 {
00924 if ( has_value() ) contained.construct_value( other.contained.value() );
00925 else contained.construct_error( other.contained.error() );
00926 }
00927
00928 template< typename U, typename G >
00929 nsel_constexpr14 explicit expected( expected<U, G> && other
00930 nsel_REQUIRES_A(
00931 std::is_constructible<T, U>::value
00932 && std::is_constructible<E, G>::value
00933 && !std::is_constructible<T, expected<U, G>&>::value
00934 && !std::is_constructible<T, expected<U, G>&&>::value
00935 && !std::is_constructible<T, const expected<U, G>&>::value
00936 && !std::is_constructible<T, const expected<U, G>&&>::value
00937 && !std::is_convertible<expected<U, G>&, T>::value
00938 && !std::is_convertible<expected<U, G>&&, T>::value
00939 && !std::is_convertible<const expected<U, G>&, T>::value
00940 && !std::is_convertible<const expected<U, G>&&, T>::value
00941 && (!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) )
00942 )
00943 : has_value_( other.has_value_ )
00944 {
00945 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
00946 else contained.construct_error( std::move( other.contained.error() ) );
00947 }
00948
00949 template< typename U, typename G >
00950 nsel_constexpr14 expected( expected<U, G> && other
00951 nsel_REQUIRES_A(
00952 std::is_constructible<T, U>::value
00953 && std::is_constructible<E, G>::value
00954 && !std::is_constructible<T, expected<U, G>&>::value
00955 && !std::is_constructible<T, expected<U, G>&&>::value
00956 && !std::is_constructible<T, const expected<U, G>&>::value
00957 && !std::is_constructible<T, const expected<U, G>&&>::value
00958 && !std::is_convertible<expected<U, G>&, T>::value
00959 && !std::is_convertible<expected<U, G>&&, T>::value
00960 && !std::is_convertible<const expected<U, G>&, T>::value
00961 && !std::is_convertible<const expected<U, G>&&, T>::value
00962 && !(!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) )
00963 )
00964 : has_value_( other.has_value_ )
00965 {
00966 if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
00967 else contained.construct_error( std::move( other.contained.error() ) );
00968 }
00969
00970 nsel_constexpr14 expected( value_type const & value
00971
00972
00973 )
00974 : has_value_( true )
00975 {
00976 contained.construct_value( value );
00977 }
00978
00979 template< typename U = T >
00980 nsel_constexpr14 explicit expected( U && value
00981 nsel_REQUIRES_A(
00982 std::is_constructible<T,U&&>::value
00983 && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
00984 && !std::is_same<expected<T,E>, typename std20::remove_cvref<U>::type>::value
00985 && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
00986 && !std::is_convertible<U&&,T>::value
00987 )
00988 ) noexcept
00989 (
00990 std::is_nothrow_move_constructible<U>::value &&
00991 std::is_nothrow_move_constructible<E>::value
00992 )
00993 : has_value_( true )
00994 {
00995 contained.construct_value( std::forward<U>( value ) );
00996 }
00997
00998 template< typename U = T >
00999 nsel_constexpr14 expected( U && value
01000 nsel_REQUIRES_A(
01001 std::is_constructible<T,U&&>::value
01002 && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
01003 && !std::is_same<expected<T,E>, typename std20::remove_cvref<U>::type>::value
01004 && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
01005 && std::is_convertible<U&&,T>::value
01006 )
01007 ) noexcept
01008 (
01009 std::is_nothrow_move_constructible<U>::value &&
01010 std::is_nothrow_move_constructible<E>::value
01011 )
01012 : has_value_( true )
01013 {
01014 contained.construct_value( std::forward<U>( value ) );
01015 }
01016
01017 template< typename... Args
01018 nsel_REQUIRES_T(
01019 std::is_constructible<T, Args&&...>::value
01020 )
01021 >
01022 nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), Args&&... args )
01023 : has_value_( true )
01024 {
01025 contained.construct_value( std::forward<Args>( args )... );
01026 }
01027
01028 template< typename U, typename... Args
01029 nsel_REQUIRES_T(
01030 std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
01031 )
01032 >
01033 nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
01034 : has_value_( true )
01035 {
01036 contained.construct_value( il, std::forward<Args>( args )... );
01037 }
01038
01039 template< typename G = E >
01040 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error
01041 nsel_REQUIRES_A(
01042 !std::is_convertible<const G&, E>::value )
01043 )
01044 : has_value_( false )
01045 {
01046 contained.construct_error( error.value() );
01047 }
01048
01049 template< typename G = E >
01050 nsel_constexpr14 expected( nonstd::unexpected_type<G> const & error
01051 nsel_REQUIRES_A(
01052 std::is_convertible<const G&, E>::value )
01053 )
01054 : has_value_( false )
01055 {
01056 contained.construct_error( error.value() );
01057 }
01058
01059 template< typename G = E >
01060 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error
01061 nsel_REQUIRES_A(
01062 !std::is_convertible<G&&, E>::value )
01063 )
01064 : has_value_( false )
01065 {
01066 contained.construct_error( std::move( error.value() ) );
01067 }
01068
01069 template< typename G = E >
01070 nsel_constexpr14 expected( nonstd::unexpected_type<G> && error
01071 nsel_REQUIRES_A(
01072 std::is_convertible<G&&, E>::value )
01073 )
01074 : has_value_( false )
01075 {
01076 contained.construct_error( std::move( error.value() ) );
01077 }
01078
01079 template< typename... Args
01080 nsel_REQUIRES_T(
01081 std::is_constructible<E, Args&&...>::value
01082 )
01083 >
01084 nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
01085 : has_value_( false )
01086 {
01087 contained.construct_error( std::forward<Args>( args )... );
01088 }
01089
01090 template< typename U, typename... Args
01091 nsel_REQUIRES_T(
01092 std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
01093 )
01094 >
01095 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
01096 : has_value_( false )
01097 {
01098 contained.construct_error( il, std::forward<Args>( args )... );
01099 }
01100
01101
01102
01103 ~expected()
01104 {
01105 if ( has_value() ) contained.destruct_value();
01106 else contained.destruct_error();
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 expected operator=( expected const & other )
01118 {
01119 expected( other ).swap( *this );
01120 return *this;
01121 }
01122
01123
01124
01125
01126
01127
01128
01129 expected & operator=( expected && other ) noexcept
01130 (
01131 std::is_nothrow_move_assignable<T>::value &&
01132 std::is_nothrow_move_constructible<T>::value&&
01133 std::is_nothrow_move_assignable<E>::value &&
01134 std::is_nothrow_move_constructible<E>::value )
01135 {
01136 expected( std::move( other ) ).swap( *this );
01137 return *this;
01138 }
01139
01140 template< typename U
01141 nsel_REQUIRES_T(
01142 std::is_constructible<T,U>::value &&
01143 std::is_assignable<T&, U>::value
01144 )
01145 >
01146 expected & operator=( U && value )
01147 {
01148 expected( std::forward<U>( value ) ).swap( *this );
01149 return *this;
01150 }
01151
01152
01153
01154
01155
01156 expected & operator=( unexpected_type const & uvalue )
01157 {
01158 expected( std::move( uvalue ) ).swap( *this );
01159 return *this;
01160 }
01161
01162
01163
01164
01165
01166 expected & operator=( unexpected_type && uvalue )
01167 {
01168 expected( std::move( uvalue ) ).swap( *this );
01169 return *this;
01170 }
01171
01172 template< typename... Args
01173 nsel_REQUIRES_T(
01174 std::is_constructible<T, Args&&...>::value
01175 )
01176 >
01177 void emplace( Args &&... args )
01178 {
01179 expected( nonstd_lite_in_place(T), std::forward<Args>(args)... ).swap( *this );
01180 }
01181
01182 template< typename U, typename... Args
01183 nsel_REQUIRES_T(
01184 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
01185 )
01186 >
01187 void emplace( std::initializer_list<U> il, Args &&... args )
01188 {
01189 expected( nonstd_lite_in_place(T), il, std::forward<Args>(args)... ).swap( *this );
01190 }
01191
01192
01193
01194
01195
01196
01197
01198 void swap( expected & other ) noexcept
01199 (
01200 #if nsel_CPP17_OR_GREATER
01201 std::is_nothrow_move_constructible<T>::value && std::is_nothrow_swappable<T&>::value &&
01202 std::is_nothrow_move_constructible<E>::value && std::is_nothrow_swappable<E&>::value
01203 #else
01204 std::is_nothrow_move_constructible<T>::value && noexcept ( std::swap( std::declval<T&>(), std::declval<T&>() ) ) &&
01205 std::is_nothrow_move_constructible<E>::value && noexcept ( std::swap( std::declval<E&>(), std::declval<E&>() ) )
01206 #endif
01207 )
01208 {
01209 using std::swap;
01210
01211 if ( bool(*this) && bool(other) ) { swap( contained.value(), other.contained.value() ); }
01212 else if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
01213 else if ( bool(*this) && ! bool(other) ) { error_type t( std::move( other.error() ) );
01214 other.contained.destruct_error();
01215 other.contained.construct_value( std::move( contained.value() ) );
01216 contained.destruct_value();
01217 contained.construct_error( std::move( t ) );
01218 swap( has_value_, other.has_value_ ); }
01219 else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
01220 }
01221
01222
01223
01224 constexpr value_type const * operator ->() const
01225 {
01226 return assert( has_value() ), contained.value_ptr();
01227 }
01228
01229 value_type * operator ->()
01230 {
01231 return assert( has_value() ), contained.value_ptr();
01232 }
01233
01234 constexpr value_type const & operator *() const &
01235 {
01236 return assert( has_value() ), contained.value();
01237 }
01238
01239 value_type & operator *() &
01240 {
01241 return assert( has_value() ), contained.value();
01242 }
01243
01244 constexpr value_type const && operator *() const &&
01245 {
01246 return assert( has_value() ), std::move( contained.value() );
01247 }
01248
01249 nsel_constexpr14 value_type && operator *() &&
01250 {
01251 return assert( has_value() ), std::move( contained.value() );
01252 }
01253
01254 constexpr explicit operator bool() const noexcept
01255 {
01256 return has_value();
01257 }
01258
01259 constexpr bool has_value() const noexcept
01260 {
01261 return has_value_;
01262 }
01263
01264 constexpr value_type const & value() const &
01265 {
01266 return has_value()
01267 ? ( contained.value() )
01268 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
01269 }
01270
01271 value_type & value() &
01272 {
01273 return has_value()
01274 ? ( contained.value() )
01275 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
01276 }
01277
01278 constexpr value_type const && value() const &&
01279 {
01280 return std::move( has_value()
01281 ? ( contained.value() )
01282 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
01283 }
01284
01285 nsel_constexpr14 value_type && value() &&
01286 {
01287 return std::move( has_value()
01288 ? ( contained.value() )
01289 : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
01290 }
01291
01292 constexpr error_type const & error() const &
01293 {
01294 return assert( ! has_value() ), contained.error();
01295 }
01296
01297 error_type & error() &
01298 {
01299 return assert( ! has_value() ), contained.error();
01300 }
01301
01302 constexpr error_type const && error() const &&
01303 {
01304 return assert( ! has_value() ), std::move( contained.error() );
01305 }
01306
01307 error_type && error() &&
01308 {
01309 return assert( ! has_value() ), std::move( contained.error() );
01310 }
01311
01312 constexpr unexpected_type get_unexpected() const
01313 {
01314 return make_unexpected( contained.error() );
01315 }
01316
01317 template< typename Ex >
01318 bool has_exception() const
01319 {
01320 using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
01321 return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
01322 }
01323
01324 template< typename U
01325 nsel_REQUIRES_T(
01326 std::is_copy_constructible<T>::value &&
01327 std::is_convertible<U&&, T>::value
01328 )
01329 >
01330 value_type value_or( U && v ) const &
01331 {
01332 return has_value()
01333 ? contained.value()
01334 : static_cast<T>( std::forward<U>( v ) );
01335 }
01336
01337 template< typename U
01338 nsel_REQUIRES_T(
01339 std::is_move_constructible<T>::value &&
01340 std::is_convertible<U&&, T>::value
01341 )
01342 >
01343 value_type value_or( U && v ) &&
01344 {
01345 return has_value()
01346 ? std::move( contained.value() )
01347 : static_cast<T>( std::forward<U>( v ) );
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 private:
01382 bool has_value_;
01383 detail::storage_t<T,E> contained;
01384 };
01385
01387
01388 template< typename E >
01389 class expected<void, E>
01390 {
01391 public:
01392 using value_type = void;
01393 using error_type = E;
01394 using unexpected_type = nonstd::unexpected_type<E>;
01395
01396
01397
01398 constexpr expected() noexcept
01399 : has_value_( true )
01400 {
01401 }
01402
01403 nsel_constexpr14 expected( expected const & other )
01404 : has_value_( other.has_value_ )
01405 {
01406 if ( ! has_value() ) contained.construct_error( other.contained.error() );
01407 }
01408
01409 nsel_REQUIRES_0(
01410 std::is_move_constructible<E>::value
01411 )
01412 nsel_constexpr14 expected( expected && other ) noexcept
01413 (
01414 true
01415 )
01416 : has_value_( other.has_value_ )
01417 {
01418 if ( ! has_value() ) contained.construct_error( std::move( other.contained.error() ) );
01419 }
01420
01421 constexpr explicit expected( nonstd_lite_in_place_t(void) )
01422 : has_value_( true )
01423 {
01424 }
01425
01426 template< typename G = E >
01427 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error
01428 nsel_REQUIRES_A(
01429 !std::is_convertible<const G&, E>::value
01430 )
01431 )
01432 : has_value_( false )
01433 {
01434 contained.construct_error( error.value() );
01435 }
01436
01437 template< typename G = E >
01438 nsel_constexpr14 expected( nonstd::unexpected_type<G> const & error
01439 nsel_REQUIRES_A(
01440 std::is_convertible<const G&, E>::value
01441 )
01442 )
01443 : has_value_( false )
01444 {
01445 contained.construct_error( error.value() );
01446 }
01447
01448 template< typename G = E >
01449 nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error
01450 nsel_REQUIRES_A(
01451 !std::is_convertible<G&&, E>::value
01452 )
01453 )
01454 : has_value_( false )
01455 {
01456 contained.construct_error( std::move( error.value() ) );
01457 }
01458
01459 template< typename G = E >
01460 nsel_constexpr14 expected( nonstd::unexpected_type<G> && error
01461 nsel_REQUIRES_A(
01462 std::is_convertible<G&&, E>::value
01463 )
01464 )
01465 : has_value_( false )
01466 {
01467 contained.construct_error( std::move( error.value() ) );
01468 }
01469
01470 template< typename... Args
01471 nsel_REQUIRES_T(
01472 std::is_constructible<E, Args&&...>::value
01473 )
01474 >
01475 nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
01476 : has_value_( false )
01477 {
01478 contained.construct_error( std::forward<Args>( args )... );
01479 }
01480
01481 template< typename U, typename... Args
01482 nsel_REQUIRES_T(
01483 std::is_constructible<U, std::initializer_list<U>, Args&&...>::value
01484 )
01485 >
01486 nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
01487 : has_value_( false )
01488 {
01489 contained.construct_error( il, std::forward<Args>( args )... );
01490 }
01491
01492
01493
01494
01495 ~expected()
01496 {
01497 if ( ! has_value() ) contained.destruct_error();
01498 }
01499
01500
01501
01502
01503
01504
01505
01506 expected & operator=( expected const & other )
01507 {
01508 expected( other ).swap( *this );
01509 return *this;
01510 }
01511
01512
01513
01514
01515
01516 expected & operator=( expected && other ) noexcept
01517 (
01518 std::is_nothrow_move_assignable<E>::value &&
01519 std::is_nothrow_move_constructible<E>::value )
01520 {
01521 expected( std::move( other ) ).swap( *this );
01522 return *this;
01523 }
01524
01525 void emplace()
01526 {}
01527
01528
01529
01530
01531
01532
01533 void swap( expected & other ) noexcept
01534 (
01535 #if nsel_CPP17_OR_GREATER
01536 std::is_nothrow_move_constructible<E>::value && std::is_nothrow_swappable<E&>::value
01537 #else
01538 std::is_nothrow_move_constructible<E>::value && noexcept ( std::swap( std::declval<E&>(), std::declval<E&>() ) )
01539 #endif
01540 )
01541 {
01542 using std::swap;
01543
01544 if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
01545 else if ( bool(*this) && ! bool(other) ) { contained.construct_error( std::move( other.error() ) );
01546 swap( has_value_, other.has_value_ ); }
01547 else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
01548 }
01549
01550
01551
01552 constexpr explicit operator bool() const noexcept
01553 {
01554 return has_value();
01555 }
01556
01557 constexpr bool has_value() const noexcept
01558 {
01559 return has_value_;
01560 }
01561
01562 void value() const
01563 {}
01564
01565 constexpr error_type const & error() const &
01566 {
01567 return assert( ! has_value() ), contained.error();
01568 }
01569
01570 error_type & error() &
01571 {
01572 return assert( ! has_value() ), contained.error();
01573 }
01574
01575 constexpr error_type const && error() const &&
01576 {
01577 return assert( ! has_value() ), std::move( contained.error() );
01578 }
01579
01580 error_type && error() &&
01581 {
01582 return assert( ! has_value() ), std::move( contained.error() );
01583 }
01584
01585 constexpr unexpected_type get_unexpected() const
01586 {
01587 return make_unexpected( contained.error() );
01588 }
01589
01590 template< typename Ex >
01591 bool has_exception() const
01592 {
01593 return ! has_value() && std::is_base_of< Ex, decltype( get_unexpected().value() ) >::value;
01594 }
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617 private:
01618 bool has_value_;
01619 detail::storage_t<void,E> contained;
01620 };
01621
01622
01623
01624 template< typename T, typename E >
01625 constexpr bool operator==( expected<T,E> const & x, expected<T,E> const & y )
01626 {
01627 return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
01628 }
01629
01630 template< typename T, typename E >
01631 constexpr bool operator!=( expected<T,E> const & x, expected<T,E> const & y )
01632 {
01633 return !(x == y);
01634 }
01635
01636 template< typename T, typename E >
01637 constexpr bool operator<( expected<T,E> const & x, expected<T,E> const & y )
01638 {
01639 return (!y) ? false : (!x) ? true : *x < *y;
01640 }
01641
01642 template< typename T, typename E >
01643 constexpr bool operator>( expected<T,E> const & x, expected<T,E> const & y )
01644 {
01645 return (y < x);
01646 }
01647
01648 template< typename T, typename E >
01649 constexpr bool operator<=( expected<T,E> const & x, expected<T,E> const & y )
01650 {
01651 return !(y < x);
01652 }
01653
01654 template< typename T, typename E >
01655 constexpr bool operator>=( expected<T,E> const & x, expected<T,E> const & y )
01656 {
01657 return !(x < y);
01658 }
01659
01660
01661
01662 template< typename T, typename E >
01663 constexpr bool operator==( expected<T,E> const & x, unexpected_type<E> const & u )
01664 {
01665 return (!x) ? x.get_unexpected() == u : false;
01666 }
01667
01668 template< typename T, typename E >
01669 constexpr bool operator==( unexpected_type<E> const & u, expected<T,E> const & x )
01670 {
01671 return ( x == u );
01672 }
01673
01674 template< typename T, typename E >
01675 constexpr bool operator!=( expected<T,E> const & x, unexpected_type<E> const & u )
01676 {
01677 return ! ( x == u );
01678 }
01679
01680 template< typename T, typename E >
01681 constexpr bool operator!=( unexpected_type<E> const & u, expected<T,E> const & x )
01682 {
01683 return ! ( x == u );
01684 }
01685
01686 template< typename T, typename E >
01687 constexpr bool operator<( expected<T,E> const & x, unexpected_type<E> const & u )
01688 {
01689 return (!x) ? ( x.get_unexpected() < u ) : false;
01690 }
01691
01692 #if nsel_P0323R <= 2
01693
01694 template< typename T, typename E >
01695 constexpr bool operator<( unexpected_type<E> const & u, expected<T,E> const & x )
01696 {
01697 return (!x) ? ( u < x.get_unexpected() ) : true ;
01698 }
01699
01700 template< typename T, typename E >
01701 constexpr bool operator>( expected<T,E> const & x, unexpected_type<E> const & u )
01702 {
01703 return ( u < x );
01704 }
01705
01706 template< typename T, typename E >
01707 constexpr bool operator>( unexpected_type<E> const & u, expected<T,E> const & x )
01708 {
01709 return ( x < u );
01710 }
01711
01712 template< typename T, typename E >
01713 constexpr bool operator<=( expected<T,E> const & x, unexpected_type<E> const & u )
01714 {
01715 return ! ( u < x );
01716 }
01717
01718 template< typename T, typename E >
01719 constexpr bool operator<=( unexpected_type<E> const & u, expected<T,E> const & x)
01720 {
01721 return ! ( x < u );
01722 }
01723
01724 template< typename T, typename E >
01725 constexpr bool operator>=( expected<T,E> const & x, unexpected_type<E> const & u )
01726 {
01727 return ! ( u > x );
01728 }
01729
01730 template< typename T, typename E >
01731 constexpr bool operator>=( unexpected_type<E> const & u, expected<T,E> const & x )
01732 {
01733 return ! ( x > u );
01734 }
01735
01736 #endif // nsel_P0323R
01737
01738
01739
01740 template< typename T, typename E >
01741 constexpr bool operator==( expected<T,E> const & x, T const & v )
01742 {
01743 return bool(x) ? *x == v : false;
01744 }
01745
01746 template< typename T, typename E >
01747 constexpr bool operator==(T const & v, expected<T,E> const & x )
01748 {
01749 return bool(x) ? v == *x : false;
01750 }
01751
01752 template< typename T, typename E >
01753 constexpr bool operator!=( expected<T,E> const & x, T const & v )
01754 {
01755 return bool(x) ? *x != v : true;
01756 }
01757
01758 template< typename T, typename E >
01759 constexpr bool operator!=( T const & v, expected<T,E> const & x )
01760 {
01761 return bool(x) ? v != *x : true;
01762 }
01763
01764 template< typename T, typename E >
01765 constexpr bool operator<( expected<T,E> const & x, T const & v )
01766 {
01767 return bool(x) ? *x < v : true;
01768 }
01769
01770 template< typename T, typename E >
01771 constexpr bool operator<( T const & v, expected<T,E> const & x )
01772 {
01773 return bool(x) ? v < *x : false;
01774 }
01775
01776 template< typename T, typename E >
01777 constexpr bool operator>( T const & v, expected<T,E> const & x )
01778 {
01779 return bool(x) ? *x < v : false;
01780 }
01781
01782 template< typename T, typename E >
01783 constexpr bool operator>( expected<T,E> const & x, T const & v )
01784 {
01785 return bool(x) ? v < *x : false;
01786 }
01787
01788 template< typename T, typename E >
01789 constexpr bool operator<=( T const & v, expected<T,E> const & x )
01790 {
01791 return bool(x) ? ! ( *x < v ) : false;
01792 }
01793
01794 template< typename T, typename E >
01795 constexpr bool operator<=( expected<T,E> const & x, T const & v )
01796 {
01797 return bool(x) ? ! ( v < *x ) : true;
01798 }
01799
01800 template< typename T, typename E >
01801 constexpr bool operator>=( expected<T,E> const & x, T const & v )
01802 {
01803 return bool(x) ? ! ( *x < v ) : false;
01804 }
01805
01806 template< typename T, typename E >
01807 constexpr bool operator>=( T const & v, expected<T,E> const & x )
01808 {
01809 return bool(x) ? ! ( v < *x ) : true;
01810 }
01811
01813
01814 template< typename T, typename E >
01815 void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
01816 {
01817 x.swap( y );
01818 }
01819
01820 #if nsel_P0323R <= 3
01821
01822 template< typename T >
01823 constexpr auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
01824 {
01825 return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
01826 }
01827
01828
01829
01830 auto inline make_expected() -> expected<void>
01831 {
01832 return expected<void>( in_place );
01833 }
01834
01835 template< typename T >
01836 constexpr auto make_expected_from_current_exception() -> expected<T>
01837 {
01838 return expected<T>( make_unexpected_from_current_exception() );
01839 }
01840
01841 template< typename T >
01842 auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
01843 {
01844 return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
01845 }
01846
01847 template< typename T, typename E >
01848 constexpr auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
01849 {
01850 return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
01851 }
01852
01853 template< typename F >
01854
01855 auto make_expected_from_call( F f,
01856 nsel_REQUIRES_A( ! std::is_same<typename std::result_of<F()>::type, void>::value )
01857 ) -> expected< typename std::result_of<F()>::type >
01858 {
01859 try
01860 {
01861 return make_expected( f() );
01862 }
01863 catch (...)
01864 {
01865 return make_unexpected_from_current_exception();
01866 }
01867 }
01868
01869 template< typename F >
01870
01871 auto make_expected_from_call( F f,
01872 nsel_REQUIRES_A( std::is_same<typename std::result_of<F()>::type, void>::value )
01873 ) -> expected<void>
01874 {
01875 try
01876 {
01877 f();
01878 return make_expected();
01879 }
01880 catch (...)
01881 {
01882 return make_unexpected_from_current_exception();
01883 }
01884 }
01885
01886 #endif // nsel_P0323R
01887
01888 }
01889
01890 using namespace expected_lite;
01891
01892
01893
01894
01895 }
01896
01897 namespace std {
01898
01899
01900
01901 template< typename T, typename E >
01902 struct hash< nonstd::expected<T,E> >
01903 {
01904 using result_type = typename hash<T>::result_type;
01905 using argument_type = nonstd::expected<T,E>;
01906
01907 constexpr result_type operator()(argument_type const & arg) const
01908 {
01909 return arg ? std::hash<T>{}(*arg) : result_type{};
01910 }
01911 };
01912
01913
01914 template< typename T, typename E >
01915 struct hash< nonstd::expected<T&,E> >
01916 {
01917 using result_type = typename hash<T>::result_type;
01918 using argument_type = nonstd::expected<T&,E>;
01919
01920 constexpr result_type operator()(argument_type const & arg) const
01921 {
01922 return arg ? std::hash<T>{}(*arg) : result_type{};
01923 }
01924 };
01925
01926
01927
01928
01929
01930
01931 template< typename E >
01932 struct hash< nonstd::expected<void,E> >
01933 {
01934 };
01935
01936 }
01937
01938 namespace nonstd {
01939
01940
01941
01942 #if nsel_CPP17_OR_GREATER && nsel_COMPILER_MSVC_VERSION > 141
01943 template< typename E >
01944 using unexpected = unexpected_type<E>;
01945 #endif
01946
01947 }
01948
01949 #undef nsel_REQUIRES
01950 #undef nsel_REQUIRES_0
01951 #undef nsel_REQUIRES_T
01952
01953 nsel_RESTORE_WARNINGS()
01954
01955 #endif // nsel_USES_STD_EXPECTED
01956
01957 #endif // NONSTD_EXPECTED_LITE_HPP