diff options
author | yronglin <yronglin777@gmail.com> | 2023-05-18 00:55:03 +0800 |
---|---|---|
committer | yronglin <yronglin777@gmail.com> | 2023-05-18 00:55:47 +0800 |
commit | 5ae9098e5c1564bdfe0ae0fdbc02e581138eeac7 (patch) | |
tree | 8616b1f098496df4fbca1069ff1fb1c140c811bd | |
parent | afbd36f153afc6cfe7a07baa42076e50b2d63d96 (diff) | |
download | llvm-5ae9098e5c1564bdfe0ae0fdbc02e581138eeac7.tar.gz |
Revert "[libc++] Implement P2505R5(Monadic operations for std::expected)."
This reverts commit ebc111b08bddca55d5f7e560a20bdb2c913d80cb.
Sorry, I forgot to append Phabricator reversion when land D140911, I try to revert this change and reland.
Reviewed By: #libc, ldionne, EricWF
Differential Revision: https://reviews.llvm.org/D150793
29 files changed, 35 insertions, 3113 deletions
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 48c2d0ddfae1..0f5ee6c24485 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -320,7 +320,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_typeinfo`` ``202106L`` ------------------------------------------------- ----------------- - ``__cpp_lib_expected`` ``202211L`` + ``__cpp_lib_expected`` ``202202L`` ------------------------------------------------- ----------------- ``__cpp_lib_format_ranges`` ``202207L`` ------------------------------------------------- ----------------- diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst index d2db69e67b98..6e6cdc25ce63 100644 --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -41,7 +41,6 @@ Implemented Papers - P1328R1 - ``constexpr type_info::operator==()`` - P1413R3 - Formatting ``thread::id`` (the ``stacktrace`` is not done yet) - P2675R1 - ``format``'s width estimation is too approximate and not forward compatible -- P2505R5 - Monadic operations for ``std::expected`` Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index d658c18a6489..95cc327b0d01 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -274,7 +274,7 @@ "`3853 <https://wg21.link/LWG3853>`__","``basic_const_iterator<volatile int*>::operator->`` is ill-formed","February 2023","","","" "`3857 <https://wg21.link/LWG3857>`__","``basic_string_view`` should allow explicit conversion when only traits vary","February 2023","|Complete|","17.0","" "`3860 <https://wg21.link/LWG3860>`__","``range_common_reference_t`` is missing","February 2023","|Complete|","17.0","|ranges|" -"`3866 <https://wg21.link/LWG3866>`__","Bad Mandates for ``expected::transform_error`` overloads","February 2023","|Complete|","17.0","" +"`3866 <https://wg21.link/LWG3866>`__","Bad Mandates for ``expected::transform_error`` overloads","February 2023","","","" "`3867 <https://wg21.link/LWG3867>`__","Should ``std::basic_osyncstream``'s move assignment operator be ``noexcept``?","February 2023","","","" "`3441 <https://wg21.link/LWG3441>`__","Misleading note about calls to customization points","February 2023","","","" "`3622 <https://wg21.link/LWG3622>`__","Misspecified transitivity of equivalence in ยง[unord.req.general]","February 2023","","","" @@ -301,7 +301,7 @@ "`3872 <https://wg21.link/LWG3872>`__","``basic_const_iterator`` should have custom ``iter_move``","February 2023","","","" "`3875 <https://wg21.link/LWG3875>`__","``std::ranges::repeat_view<T, IntegerClass>::iterator`` may be ill-formed","February 2023","","","|ranges|" "`3876 <https://wg21.link/LWG3876>`__","Default constructor of ``std::layout_XX::mapping`` misses precondition","February 2023","","","" -"`3877 <https://wg21.link/LWG3877>`__","Incorrect constraints on ``const``-qualified monadic overloads for ``std::expected``","February 2023","|Complete|","17.0","" +"`3877 <https://wg21.link/LWG3877>`__","Incorrect constraints on ``const``-qualified monadic overloads for ``std::expected``","February 2023","","","" "`3878 <https://wg21.link/LWG3878>`__","import ``std;`` should guarantee initialization of standard iostreams objects","February 2023","","","" "`3879 <https://wg21.link/LWG3879>`__","``erase_if`` for ``flat_{,multi}set`` is incorrectly specified","February 2023","","","" "`3880 <https://wg21.link/LWG3880>`__","Clarify ``operator+=`` complexity for ``{chunk,stride}_view::iterator``","February 2023","","","|ranges|" diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv index a49dc627a7fa..550fb34d4b34 100644 --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -100,7 +100,7 @@ "`P1478R8 <https://wg21.link/P1478R8>`__","LWG", "``Byte-wise`` ``atomic`` ``memcpy``", "November 2022","","","|concurrency TS|" "`P2167R3 <https://wg21.link/P2167R3>`__","LWG", "Improved Proposed Wording for LWG 2114", "November 2022","","","" "`P2396R1 <https://wg21.link/P2396R1>`__","LWG", "Concurrency TS 2 fixes ", "November 2022","","","|concurrency TS|" -"`P2505R5 <https://wg21.link/P2505R5>`__","LWG", "Monadic Functions for ``std::expected``", "November 2022","|Complete|","17.0","" +"`P2505R5 <https://wg21.link/P2505R5>`__","LWG", "Monadic Functions for ``std::expected``", "November 2022","","","" "`P2539R4 <https://wg21.link/P2539R4>`__","LWG", "Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?", "November 2022","","","|format|" "`P2602R2 <https://wg21.link/P2602R2>`__","LWG", "Poison Pills are Too Toxic", "November 2022","","","|ranges|" "`P2708R1 <https://wg21.link/P2708R1>`__","LWG", "No Further Fundamentals TSes", "November 2022","|Nothing to do|","","" diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index 668e23f21c71..3ff8fbc7b211 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -14,12 +14,10 @@ #include <__expected/bad_expected_access.h> #include <__expected/unexpect.h> #include <__expected/unexpected.h> -#include <__functional/invoke.h> #include <__memory/addressof.h> #include <__memory/construct_at.h> #include <__type_traits/conjunction.h> #include <__type_traits/disjunction.h> -#include <__type_traits/integral_constant.h> #include <__type_traits/is_assignable.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_convertible.h> @@ -62,17 +60,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp, class _Err> -class expected; - -template <class _Tp> -struct __is_std_expected : false_type {}; - -template <class _Tp, class _Err> -struct __is_std_expected<expected<_Tp, _Err>> : true_type {}; - -struct __expected_construct_in_place_from_invoke_tag {}; -struct __expected_construct_unexpected_from_invoke_tag {}; +namespace __expected { template <class _Err, class _Arg> _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { @@ -84,6 +72,8 @@ _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { # endif } +} // namespace __expected + template <class _Tp, class _Err> class expected { static_assert( @@ -176,15 +166,6 @@ private: _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >; - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( - std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {} - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( - std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} public: template <class _Up, class _OtherErr> @@ -557,28 +538,28 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); } return __union_.__val_; } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); } return __union_.__val_; } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); } return std::move(__union_.__val_); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); } return std::move(__union_.__val_); } @@ -617,245 +598,6 @@ public: return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); } - template <class _Up = _Err> - _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { - static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); - static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); - if (has_value()) - return std::forward<_Up>(__error); - return error(); - } - - template <class _Up = _Err> - _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { - static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible"); - static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); - if (has_value()) - return std::forward<_Up>(__error); - return std::move(error()); - } - - // [expected.void.monadic], monadic - template <class _Func> - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { - using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Up::error_type, _Err>, - "The result of f(value()) must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f), value()); - } - return _Up(unexpect, error()); - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { - using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Up::error_type, _Err>, - "The result of f(value()) must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f), value()); - } - return _Up(unexpect, error()); - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { - using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>; - static_assert( - __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Up::error_type, _Err>, - "The result of f(std::move(value())) must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f), std::move(value())); - } - return _Up(unexpect, std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { - using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>; - static_assert( - __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Up::error_type, _Err>, - "The result of f(std::move(value())) must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f), std::move(value())); - } - return _Up(unexpect, std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Tp, _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { - using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(error()) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(in_place, value()); - } - return std::invoke(std::forward<_Func>(__f), error()); - } - - template <class _Func> - requires is_constructible_v<_Tp, const _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { - using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(error()) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(in_place, value()); - } - return std::invoke(std::forward<_Func>(__f), error()); - } - - template <class _Func> - requires is_constructible_v<_Tp, _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { - using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; - static_assert( - __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(std::move(error())) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(in_place, std::move(value())); - } - return std::invoke(std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Tp, const _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { - using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; - static_assert( - __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(std::move(error())) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(in_place, std::move(value())); - } - return std::invoke(std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { - using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, error()); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); - } else { - std::invoke(std::forward<_Func>(__f), value()); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { - using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, error()); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); - } else { - std::invoke(std::forward<_Func>(__f), value()); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { - using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, std::move(error())); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>( - __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); - } else { - std::invoke(std::forward<_Func>(__f), std::move(value())); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { - using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, std::move(error())); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>( - __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); - } else { - std::invoke(std::forward<_Func>(__f), std::move(value())); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Tp, _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { - using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(error()) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(in_place, value()); - } - return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); - } - - template <class _Func> - requires is_constructible_v<_Tp, const _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { - using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(error()) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(in_place, value()); - } - return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); - } - - template <class _Func> - requires is_constructible_v<_Tp, _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { - using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(std::move(error())) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(in_place, std::move(value())); - } - return expected<_Tp, _Gp>( - __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Tp, const _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { - using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(std::move(error())) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(in_place, std::move(value())); - } - return expected<_Tp, _Gp>( - __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); - } - // [expected.object.eq], equality operators template <class _T2, class _E2> requires(!is_void_v<_T2>) @@ -883,66 +625,24 @@ public: private: struct __empty_t {}; - - template <class _ValueType, class _ErrorType> - union __union_t { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {} - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) - = default; - - // the expected's destructor handles this - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} - - _ValueType __val_; - _ErrorType __unex_; - }; - - // use named union because [[no_unique_address]] cannot be applied to an unnamed union, - // also guaranteed elision into a potentially-overlapping subobject is unsettled (and - // it's not clear that it's implementable, given that the function is allowed to clobber - // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. - template <class _ValueType, class _ErrorType> - requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>) - union __union_t<_ValueType, _ErrorType> { + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) = default; // the expected's destructor handles this _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>) + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) {} _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; - _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_; - _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; - }; + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; - _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_; bool __has_val_; }; @@ -1062,19 +762,6 @@ public: std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); } -private: - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f) - : __has_val_(true) { - std::invoke(std::forward<_Func>(__f)); - } - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( - __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} - -public: // [expected.void.dtor], destructor _LIBCPP_HIDE_FROM_ABI constexpr ~expected() @@ -1212,13 +899,13 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); } } _LIBCPP_HIDE_FROM_ABI constexpr void value() && { if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); } } @@ -1242,235 +929,6 @@ public: return std::move(__union_.__unex_); } - template <class _Up = _Err> - _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { - static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); - static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); - if (has_value()) { - return std::forward<_Up>(__error); - } - return error(); - } - - template <class _Up = _Err> - _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { - static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible"); - static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); - if (has_value()) { - return std::forward<_Up>(__error); - } - return std::move(error()); - } - - // [expected.void.monadic], monadic - template <class _Func> - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { - using _Up = remove_cvref_t<invoke_result_t<_Func>>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f)); - } - return _Up(unexpect, error()); - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { - using _Up = remove_cvref_t<invoke_result_t<_Func>>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f)); - } - return _Up(unexpect, error()); - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { - using _Up = remove_cvref_t<invoke_result_t<_Func>>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f)); - } - return _Up(unexpect, std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { - using _Up = remove_cvref_t<invoke_result_t<_Func>>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); - if (has_value()) { - return std::invoke(std::forward<_Func>(__f)); - } - return _Up(unexpect, std::move(error())); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { - using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(error()) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(); - } - return std::invoke(std::forward<_Func>(__f), error()); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { - using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(error()) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(); - } - return std::invoke(std::forward<_Func>(__f), error()); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { - using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(std::move(error())) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(); - } - return std::invoke(std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { - using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); - static_assert(is_same_v<typename _Gp::value_type, _Tp>, - "The result of f(std::move(error())) must have the same value_type as this expected"); - if (has_value()) { - return _Gp(); - } - return std::invoke(std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { - using _Up = remove_cv_t<invoke_result_t<_Func>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, error()); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); - } else { - std::invoke(std::forward<_Func>(__f)); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { - using _Up = remove_cv_t<invoke_result_t<_Func>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, error()); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); - } else { - std::invoke(std::forward<_Func>(__f)); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { - using _Up = remove_cv_t<invoke_result_t<_Func>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, std::move(error())); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); - } else { - std::invoke(std::forward<_Func>(__f)); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { - using _Up = remove_cv_t<invoke_result_t<_Func>>; - if (!has_value()) { - return expected<_Up, _Err>(unexpect, std::move(error())); - } - if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); - } else { - std::invoke(std::forward<_Func>(__f)); - return expected<_Up, _Err>(); - } - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { - using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(error()) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(); - } - return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { - using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(error()) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(); - } - return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { - using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(std::move(error())) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(); - } - return expected<_Tp, _Gp>( - __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); - } - - template <class _Func> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { - using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; - static_assert(__valid_std_unexpected<_Gp>::value, - "The result of f(std::move(error())) must be a valid template argument for unexpected"); - if (has_value()) { - return expected<_Tp, _Gp>(); - } - return expected<_Tp, _Gp>( - __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); - } - // [expected.void.eq], equality operators template <class _T2, class _E2> requires is_void_v<_T2> @@ -1489,55 +947,23 @@ public: private: struct __empty_t {}; - - template <class _ErrorType> - union __union_t { + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ErrorType>) - = default; - - // the expected's destructor handles this - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} - - __empty_t __empty_; - _ErrorType __unex_; - }; - - // use named union because [[no_unique_address]] cannot be applied to an unnamed union, - // also guaranteed elision into a potentially-overlapping subobject is unsettled (and - // it's not clear that it's implementable, given that the function is allowed to clobber - // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. - template <class _ErrorType> - requires is_trivially_move_constructible_v<_ErrorType> - union __union_t<_ErrorType> { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - - template <class _Func, class... _Args> - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ErrorType>) + requires(is_trivially_destructible_v<_Err>) = default; // the expected's destructor handles this _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(!is_trivially_destructible_v<_ErrorType>) + requires(!is_trivially_destructible_v<_Err>) {} _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; - _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; - }; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; - _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_; bool __has_val_; }; diff --git a/libcxx/include/version b/libcxx/include/version index 4cb74e29cbf2..b87abdfce522 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -82,7 +82,7 @@ __cpp_lib_erase_if 202002L <deque> <forward __cpp_lib_exchange_function 201304L <utility> __cpp_lib_execution 201902L <execution> 201603L // C++17 -__cpp_lib_expected 202211L <expected> +__cpp_lib_expected 202202L <expected> __cpp_lib_filesystem 201703L <filesystem> __cpp_lib_format 202106L <format> __cpp_lib_format_ranges 202207L <format> @@ -399,7 +399,7 @@ __cpp_lib_void_t 201411L <type_traits> # undef __cpp_lib_constexpr_memory # define __cpp_lib_constexpr_memory 202202L # define __cpp_lib_constexpr_typeinfo 202106L -# define __cpp_lib_expected 202211L +# define __cpp_lib_expected 202202L # if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) # define __cpp_lib_format_ranges 202207L # endif diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp deleted file mode 100644 index 692ac60d0738..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class F> constexpr auto and_then(F&& f) &; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) const &; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) &&; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) const &&; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -#include <expected> -#include <utility> - -struct NotSameAsInt {}; - -int lval_return_not_std_expected(int&) { return 0; } -int clval_return_not_std_expected(const int&) { return 0; } -int rval_return_not_std_expected(int&&) { return 0; } -int crval_return_not_std_expected(const int&&) { return 0; } - -std::expected<int, NotSameAsInt> lval_error_type_not_same_as_int(int&) { return {}; } -std::expected<int, NotSameAsInt> clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected<int, NotSameAsInt> rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected<int, NotSameAsInt> crval_error_type_not_same_as_int(const int&&) { return {}; } - -// clang-format off -void test() { - // Test & overload - { - // U is not a specialization of std::expected - { - std::expected<int, int> f1(1); - f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(value()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - std::expected<int, int> f1(1); - f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(value()) must have the same error_type as this expected}} - } - } - - // Test const& overload - { - // U is not a specialization of std::expected - { - const std::expected<int, int> f1(1); - f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(value()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - const std::expected<int, int> f1(1); - f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(value()) must have the same error_type as this expected}} - - } - } - - // Test && overload - { - // U is not a specialization of std::expected - { - std::expected<int, int> f1(1); - std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - std::expected<int, int> f1(1); - std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}} - } - } - - // Test const&& overload - { - // U is not a specialization of std::expected - { - const std::expected<int, int> f1(1); - std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - const std::expected<int, int> f1(1); - std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}} - } - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/error_or.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/error_or.mandates.verify.cpp deleted file mode 100644 index f0ab5c495517..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/error_or.mandates.verify.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class G = E> constexpr E error_or(G&&) const &; -// Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true. - -// template<class G = E> constexpr E error_or(G&&) &&; -// Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true. - -#include <expected> -#include <utility> - -struct NonCopyable { - NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -struct NotConvertibleFromInt {}; - -// clang-format off -void test() { - // const & overload - // !is_copy_constructible_v<G>, - { - const std::expected<int, NonCopyable> f1(std::unexpect, 0); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonCopyable>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be copy constructible}} - // expected-error-re@*:* {{call to deleted constructor of{{.*}}}} - } - - // const & overload - // !is_convertible_v<U, T> - { - const std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{}); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}} - // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}} - - } - - // && overload - // !is_move_constructible_v<T>, - { - std::expected<int, NonMovable> f1(std::unexpect, 0); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonMovable>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be move constructible}} - // expected-error-re@*:* {{call to deleted constructor of{{.*}}}} - } - - // && overload - // !is_convertible_v<U, T> - { - std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{}); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}} - //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}} - // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}} - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp index c8c217054ae6..3fd047df7134 100644 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp @@ -16,20 +16,4 @@ struct Empty {}; -struct A { - int x_; - int y_; -}; - -struct B : public A { - int z_; - virtual ~B() = default; -}; - static_assert(sizeof(std::expected<Empty, Empty>) == sizeof(bool)); -static_assert(sizeof(std::expected<Empty, A>) == 2 * sizeof(int) + alignof(std::expected<Empty, A>)); -static_assert(sizeof(std::expected<Empty, B>) == sizeof(B) + alignof(std::expected<Empty, B>)); -static_assert(sizeof(std::expected<A, Empty>) == 2 * sizeof(int) + alignof(std::expected<A, Empty>)); -static_assert(sizeof(std::expected<A, A>) == 2 * sizeof(int) + alignof(std::expected<A, A>)); -static_assert(sizeof(std::expected<B, Empty>) == sizeof(B) + alignof(std::expected<B, Empty>)); -static_assert(sizeof(std::expected<B, B>) == sizeof(B) + alignof(std::expected<B, B>)); diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/or_else.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/or_else.mandates.verify.cpp deleted file mode 100644 index 1264cc06b48c..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/or_else.mandates.verify.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class F> constexpr auto or_else(F&& f) &; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) const &; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) &&; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) const &&; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -#include <expected> -#include <utility> - -struct NotSameAsInt {}; - -int lval_return_not_std_expected(int&) { return 0; } -int clval_return_not_std_expected(const int&) { return 0; } -int rval_return_not_std_expected(int&&) { return 0; } -int crval_return_not_std_expected(const int&&) { return 0; } - -std::expected<NotSameAsInt, int> lval_error_type_not_same_as_int(int&) { return {}; } -std::expected<NotSameAsInt, int> clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected<NotSameAsInt, int> rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected<NotSameAsInt, int> crval_error_type_not_same_as_int(const int&&) { return {}; } - -// clang-format off -void test() { - // Test & overload - { - // G is not a specialization of std::expected - { - std::expected<int, int> f1(std::unexpected<int>(1)); - f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<G:value_type, T> - { - std::expected<int, int> f1(std::unexpected<int>(1)); - f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must have the same value_type as this expected}} - } - } - - // Test const& overload - { - // G is not a specialization of std::expected - { - const std::expected<int, int> f1(std::unexpected<int>(1)); - f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<G:value_type, T> - { - const std::expected<int, int> f1(std::unexpected<int>(1)); - f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must have the same value_type as this expected}} - } - } - - // Test && overload - { - // G is not a specialization of std::expected - { - std::expected<int, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<G:value_type, T> - { - std::expected<int, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}} - } - } - - // Test const&& overload - { - // G is not a specialization of std::expected - { - const std::expected<int, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<G:value_type, T> - { - const std::expected<int, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}} - } - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp deleted file mode 100644 index 32b82fdaa255..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates - -// template<class F> constexpr auto transform_error(F&& f) &; -// template<class F> constexpr auto transform_error(F&& f) const &; -// -// Let G be remove_cv_t<invoke_result_t<F, decltype(error())>> -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward<F>(f), error())); is well-formed. - -// template<class F> constexpr auto transform_error(F&& f) &&; -// template<class F> constexpr auto transform_error(F&& f) const &&; -// -// Let G be remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>. -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed. - -#include <expected> -#include <utility> - -static int val; - -template <class T> -std::unexpected<int> return_unexpected(T) { - return std::unexpected<int>(1); -} - -template <class T> -int& return_no_object(T) { - return val; -} - -// clang-format off -void test() { - - // Test & overload - { - std::expected<int, int> e; - e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}} - - e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}} - } - - // Test const& overload - { - const std::expected<int, int> e; - e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } - - // Test && overload - { - std::expected<int, int> e; - std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } - - // Test const&& overload - { - const std::expected<int, int> e; - std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/and_then.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/and_then.mandates.verify.cpp deleted file mode 100644 index 615d5347fcc0..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.void/and_then.mandates.verify.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class F> constexpr auto and_then(F&& f) &; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) const &; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) &&; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -// template<class F> constexpr auto and_then(F&& f) const &&; -// Mandates: -// Let U be std::remove_cvref_t<std::invoke_result<F>> -// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true - -#include <expected> -#include <utility> - -struct NotSameAsInt {}; - -int lval_return_not_std_expected(void) { return 0; } -int clval_return_not_std_expected(void) { return 0; } -int rval_return_not_std_expected(void) { return 0; } -int crval_return_not_std_expected(void) { return 0; } - -std::expected<int, NotSameAsInt> lval_error_type_not_same_as_int(void) { return {}; } -std::expected<int, NotSameAsInt> clval_error_type_not_same_as_int(void) { return {}; } -std::expected<int, NotSameAsInt> rval_error_type_not_same_as_int(void) { return {}; } -std::expected<int, NotSameAsInt> crval_error_type_not_same_as_int(void) { return {}; } - -// clang-format off -void test() { - // Test & overload - { - // U is not a specialization of std::expected - { - std::expected<void, int> f1; - f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - std::expected<void, int> f1; - f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must have the same error_type as this expected}} - } - } - - // Test const& overload - { - // U is not a specialization of std::expected - { - const std::expected<void, int> f1; - f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - const std::expected<void, int> f1; - f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must have the same error_type as this expected}} - } - } - - // Test && overload - { - // U is not a specialization of std::expected - { - std::expected<void, int> f1; - std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - std::expected<void, int> f1; - std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must have the same error_type as this expected}} - } - } - - // Test const&& overload - { - // U is not a specialization of std::expected - { - const std::expected<void, int> f1; - std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}} - } - - // !std::is_same_v<U:error_type, E> - { - const std::expected<void, int> f1; - std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f() must have the same error_type as this expected}} - } - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp deleted file mode 100644 index a36665b25c87..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class G = E> constexpr E error_or(G&&) const &; -// Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true. - -// template<class G = E> constexpr E error_or(G&&) &&; -// Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true. - -#include <expected> -#include <utility> - -struct NonCopyable { - NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -struct NotConvertibleFromInt {}; - -// clang-format off -void test() { - // const & overload - // !is_copy_constructible_v<G>, - { - const std::expected<void, NonCopyable> f1(std::unexpect, 0); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonCopyable>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be copy constructible}} - // expected-error-re@*:* {{call to deleted constructor of{{.*}}}} - } - - // const & overload - // !is_convertible_v<U, T> - { - const std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{}); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}} - // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}} - } - - // && overload - // !is_move_constructible_v<T>, - { - std::expected<void, NonMovable> f1(std::unexpect, 0); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonMovable>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be move constructible}} - // expected-error-re@*:* {{call to deleted constructor of{{.*}}}} - } - - // && overload - // !is_convertible_v<U, T> - { - std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{}); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}} - // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}} - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp index dc59a6228386..1ad2aa125c29 100644 --- a/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp @@ -16,16 +16,4 @@ struct Empty {}; -struct A { - int x_; - int y_; -}; - -struct B : public A { - int z_; - virtual ~B() = default; -}; - static_assert(sizeof(std::expected<void, Empty>) == sizeof(bool)); -static_assert(sizeof(std::expected<void, A>) == 2 * sizeof(int) + alignof(std::expected<void, A>)); -static_assert(sizeof(std::expected<void, B>) == sizeof(B) + alignof(std::expected<void, B>)); diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/or_else.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/or_else.mandates.verify.cpp deleted file mode 100644 index 9ebf6f586de2..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.void/or_else.mandates.verify.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates -// template<class F> constexpr auto or_else(F&& f) &; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) const &; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) &&; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -// template<class F> constexpr auto or_else(F&& f) const &&; -// Mandates: -// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>> -// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true - -#include <expected> -#include <utility> - -struct NotSameAsInt {}; - -int lval_return_not_std_expected(int&) { return 0; } -int clval_return_not_std_expected(const int&) { return 0; } -int rval_return_not_std_expected(int&&) { return 0; } -int crval_return_not_std_expected(const int&&) { return 0; } - -std::expected<NotSameAsInt, int> lval_error_type_not_same_as_int(int&) { return {}; } -std::expected<NotSameAsInt, int> clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected<NotSameAsInt, int> rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected<NotSameAsInt, int> crval_error_type_not_same_as_int(const int&&) { return {}; } - -// clang-format off -void test() { - // Test & overload - { - // G is not a specialization of std::expected - { - std::expected<void, int> f1(std::unexpected<int>(1)); - f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - } - - // !std::is_same_v<G:value_type, T> - { - std::expected<void, int> f1(std::unexpected<int>(1)); - f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must have the same value_type as this expected}} - } - } - - // Test const& overload - { - // G is not a specialization of std::expected - { - const std::expected<void, int> f1(std::unexpected<int>(1)); - f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - } - - // !std::is_same_v<G:value_type, T> - { - const std::expected<void, int> f1(std::unexpected<int>(1)); - f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(error()) must have the same value_type as this expected}} - } - } - - // Test && overload - { - // G is not a specialization of std::expected - { - std::expected<void, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - } - - // !std::is_same_v<G:value_type, T> - { - std::expected<void, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}} - } - } - - // Test const&& overload - { - // G is not a specialization of std::expected - { - const std::expected<void, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}} - // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}} - } - - // !std::is_same_v<G:value_type, T> - { - const std::expected<void, int> f1(std::unexpected<int>(1)); - std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}} - } - } -} -// clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp deleted file mode 100644 index cdae36733a33..000000000000 --- a/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Test the mandates - -// template<class F> constexpr auto transform_error(F&& f) &; -// template<class F> constexpr auto transform_error(F&& f) const &; -// -// Let G be remove_cv_t<invoke_result_t<F, decltype(error())>> -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward<F>(f), error())); is well-formed. - -// template<class F> constexpr auto transform_error(F&& f) &&; -// template<class F> constexpr auto transform_error(F&& f) const &&; -// -// Let G be remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>. -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed. - -#include <expected> -#include <utility> - -static int val; - -template <class T> -std::unexpected<int> return_unexpected(T) { - return std::unexpected<int>(1); -} - -template <class T> -int& return_no_object(T) { - return val; -} - -// clang-format off -void test() { - - // Test & overload - { - std::expected<void, int> e; - e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}} - - e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}} - } - - // Test const& overload - { - const std::expected<void, int> e; - e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } - - // Test && overload - { - std::expected<void, int> e; - std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } - - // Test const&& overload - { - const std::expected<void, int> e; - std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} - } -} -// clang-format on diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp index 289609838a13..4872981be89e 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp @@ -16,7 +16,7 @@ // Test the feature test macros defined by <expected> /* Constant Value - __cpp_lib_expected 202211L [C++2b] + __cpp_lib_expected 202202L [C++2b] */ #include <expected> @@ -51,8 +51,8 @@ # ifndef __cpp_lib_expected # error "__cpp_lib_expected should be defined in c++2b" # endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++2b" +# if __cpp_lib_expected != 202202L +# error "__cpp_lib_expected should have the value 202202L in c++2b" # endif #endif // TEST_STD_VER > 20 diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 74073cfcf1c1..e1bdde4551a7 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -76,7 +76,7 @@ __cpp_lib_exchange_function 201304L [C++14] __cpp_lib_execution 201603L [C++17] 201902L [C++20] - __cpp_lib_expected 202211L [C++2b] + __cpp_lib_expected 202202L [C++2b] __cpp_lib_filesystem 201703L [C++17] __cpp_lib_format 202106L [C++20] __cpp_lib_format_ranges 202207L [C++2b] @@ -4161,8 +4161,8 @@ # ifndef __cpp_lib_expected # error "__cpp_lib_expected should be defined in c++2b" # endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++2b" +# if __cpp_lib_expected != 202202L +# error "__cpp_lib_expected should have the value 202202L in c++2b" # endif # if !defined(_LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM) diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/and_then.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/and_then.pass.cpp deleted file mode 100644 index 1630931d4a85..000000000000 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/and_then.pass.cpp +++ /dev/null @@ -1,288 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// <expected> - -// template<class F> constexpr auto and_then(F&& f) &; -// template<class F> constexpr auto and_then(F&& f) const &; -// template<class F> constexpr auto and_then(F&& f) &&; -// template<class F> constexpr auto and_then(F&& f) const &&; - -#include <cassert> -#include <concepts> -#include <expected> -#include <memory> -#include <type_traits> -#include <utility> - -struct LVal { - constexpr std::expected<int, int> operator()(int&) { return 1; } - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct CLVal { - std::expected<int, int> operator()(int&) = delete; - constexpr std::expected<int, int> operator()(const int&) { return 1; } - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct RVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - constexpr std::expected<int, int> operator()(int&&) { return 1; } - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct CRVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - constexpr std::expected<int, int> operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr std::expected<int, int> operator()(int) & { return 1; } - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct CRefQual { - std::expected<int, int> operator()(int) & = delete; - constexpr std::expected<int, int> operator()(int) const& { return 1; } - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct RVRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - constexpr std::expected<int, int> operator()(int) && { return 1; } - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct RVCRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - constexpr std::expected<int, int> operator()(int) const&& { return 1; } -}; - -struct UnexpectedLVal { - constexpr std::expected<int, int> operator()(int&) { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct UnexpectedCLVal { - std::expected<int, int> operator()(int&) = delete; - constexpr std::expected<int, int> operator()(const int&) { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct UnexpectedRVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - constexpr std::expected<int, int> operator()(int&&) { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct UnexpectedCRVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - constexpr std::expected<int, int> operator()(const int&&) { return std::expected<int, int>(std::unexpected<int>(5)); } -}; - -struct UnexpectedRefQual { - constexpr std::expected<int, int> operator()(int) & { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct UnexpectedCRefQual { - std::expected<int, int> operator()(int) & = delete; - constexpr std::expected<int, int> operator()(int) const& { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct UnexpectedRVRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - constexpr std::expected<int, int> operator()(int) && { return std::expected<int, int>(std::unexpected<int>(5)); } - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct UnexpectedRVCRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - constexpr std::expected<int, int> operator()(int) const&& { return std::expected<int, int>(std::unexpected<int>(5)); } -}; - -struct NonCopyable { - constexpr NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - constexpr NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -struct NonConst { - std::expected<int, int> non_const() { return 1; } -}; - -template <class E, class F> -concept has_and_then = requires(E&& e, F&& f) { - {std::forward<E>(e).and_then(std::forward<F>(f))}; -}; - -static_assert( has_and_then<std::expected<int, int>&, std::expected<int, int>(int&)>); -static_assert(!has_and_then<std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(int&)>); -static_assert( has_and_then<const std::expected<int, int>&, std::expected<int, int>(const int&)>); -static_assert(!has_and_then<const std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(const int&)>); -static_assert( has_and_then<std::expected<int, int>&&, std::expected<int, int>(int)>); -static_assert(!has_and_then<std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(int)>); -static_assert( has_and_then<const std::expected<int, int>&&, std::expected<int, int>(const int)>); -static_assert(!has_and_then<const std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(const int)>); - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&, int()>); -static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without &qualifier on F'soperator() - { - std::expected<int, int> e{0}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(LVal{}); - assert(val == 1); - assert(e.and_then(UnexpectedLVal{}).error() == 5); - } - - // With & qualifier on F's operator() - { - std::expected<int, int> e{0}; - RefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l); - assert(val == 1); - UnexpectedRefQual nl{}; - assert(e.and_then(nl).error() == 5); - } - } - - // Test const& overload - { - // Without & qualifier on F's operator() - { - const std::expected<int, int> e{0}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(CLVal{}); - assert(val == 1); - assert(e.and_then(UnexpectedCLVal{}).error() == 5); - } - - // With & qualifier on F's operator() - { - const std::expected<int, int> e{0}; - const CRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l); - assert(val == 1); - const UnexpectedCRefQual nl{}; - assert(e.and_then(nl).error() == 5); - } - } - - // Test && overload - { - // Without & qualifier on F's operator() - { - std::expected<int, int> e{0}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVal{}); - assert(val == 1); - assert(std::move(e).and_then(UnexpectedRVal{}).error() == 5); - } - - // With & qualifier on F's operator() - { - std::expected<int, int> e{0}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVRefQual{}); - assert(val == 1); - assert(e.and_then(UnexpectedRVRefQual{}).error() == 5); - } - } - - // Test const&& overload - { - // Without & qualifier on F's operator() - { - const std::expected<int, int> e{0}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(CRVal{}); - assert(val == 1); - assert(std::move(e).and_then(UnexpectedCRVal{}).error() == 5); - } - - // With & qualifier on F's operator() - { - const std::expected<int, int> e{0}; - const RVCRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(std::move(l)); - assert(val == 1); - const UnexpectedRVCRefQual nl{}; - assert(std::move(e).and_then(std::move(nl)).error() == 5); - } - } -} -// clang-format on - -// check that the lambda body is not instantiated during overload resolution -constexpr void test_sfinae() { - std::expected<NonConst, int> e(std::unexpected<int>(2)); - auto l = [](auto&& x) { return x.non_const(); }; - e.and_then(l); - std::move(e).and_then(l); -} - -constexpr bool test() { - test_sfinae(); - test_val_types(); - - std::expected<int, int> e(std::unexpected<int>(1)); - const auto& ce = e; - - const auto never_called = [](int) { - assert(false); - return std::expected<int, int>(); - }; - - e.and_then(never_called); - std::move(e).and_then(never_called); - ce.and_then(never_called); - std::move(ce).and_then(never_called); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/or_else.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/or_else.pass.cpp deleted file mode 100644 index bf5b481a158a..000000000000 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/or_else.pass.cpp +++ /dev/null @@ -1,202 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// <expected> - -// template<class F> constexpr auto or_else(F&& f) &; -// template<class F> constexpr auto or_else(F&& f) const &; -// template<class F> constexpr auto or_else(F&& f) &&; -// template<class F> constexpr auto or_else(F&& f) const &&; - -#include <cassert> -#include <concepts> -#include <expected> -#include <memory> -#include <type_traits> -#include <utility> - -struct LVal { - constexpr std::expected<int, int> operator()(int&) { return 1; } - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct CLVal { - std::expected<int, int> operator()(int&) = delete; - constexpr std::expected<int, int> operator()(const int&) { return 1; } - std::expected<int, int> operator()(int&&) = delete; - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct RVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - constexpr std::expected<int, int> operator()(int&&) { return 1; } - std::expected<int, int> operator()(const int&&) = delete; -}; - -struct CRVal { - std::expected<int, int> operator()(int&) = delete; - std::expected<int, int> operator()(const int&) = delete; - std::expected<int, int> operator()(int&&) = delete; - constexpr std::expected<int, int> operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr std::expected<int, int> operator()(int) & { return 1; } - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct CRefQual { - std::expected<int, int> operator()(int) & = delete; - constexpr std::expected<int, int> operator()(int) const& { return 1; } - std::expected<int, int> operator()(int) && = delete; - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct RVRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - constexpr std::expected<int, int> operator()(int) && { return 1; } - std::expected<int, int> operator()(int) const&& = delete; -}; - -struct RVCRefQual { - std::expected<int, int> operator()(int) & = delete; - std::expected<int, int> operator()(int) const& = delete; - std::expected<int, int> operator()(int) && = delete; - constexpr std::expected<int, int> operator()(int) const&& { return 1; } -}; - -template <class E, class F> -concept has_or_else = - requires(E&& e, F&& f) { - { std::forward<E>(e).or_else(std::forward<F>(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_or_else<const std::expected<std::unique_ptr<int>, int>&, int()>); -static_assert(!has_or_else<const std::expected<std::unique_ptr<int>, int>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without & qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(LVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator - { - std::expected<int, int> e(std::unexpected<int>(0)); - RefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(l); - assert(val == 1); - } - } - - // Test const& overload - { - // Without const& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(CLVal{}); - assert(val == 1); - } - - // With const& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - const CRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(l); - assert(val == 1); - } - } - - // Test && overload - { - // Without && qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(RVal{}); - assert(val == 1); - } - - // With && qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(RVRefQual{}); - assert(val == 1); - } - } - - // Test const&& overload - { - // Without const&& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(CRVal{}); - assert(val == 1); - } - - // With const&& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - const RVCRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(std::move(l)); - assert(val == 1); - } - } -} -// clang-format on - -struct NonConst { - std::expected<int, int> non_const() { return std::expected<int, int>(std::unexpect, 1); } -}; - -// check that the lambda body is not instantiated during overload resolution -constexpr void test_sfinae() { - std::expected<int, NonConst> e{1}; - auto l = [](auto&& x) { return x.non_const(); }; - e.or_else(l); - std::move(e).or_else(l); -} - -constexpr bool test() { - test_sfinae(); - test_val_types(); - - std::expected<int, int> e(1); - const auto& ce = e; - - const auto never_called = [](int) { - assert(false); - return std::expected<int, int>(); - }; - - e.or_else(never_called); - std::move(e).or_else(never_called); - ce.or_else(never_called); - std::move(ce).or_else(never_called); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp deleted file mode 100644 index b72055fb2523..000000000000 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp +++ /dev/null @@ -1,251 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, -// please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333, but we have a workaround to -// avoid this issue. - -// <expected> - -// template<class F> constexpr auto transform(F&& f) &; -// template<class F> constexpr auto transform(F&& f) const &; -// template<class F> constexpr auto transform(F&& f) &&; -// template<class F> constexpr auto transform(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <memory> -#include <type_traits> -#include <utility> - -struct LVal { - constexpr int operator()(int&) { return 1; } - int operator()(const int&) = delete; - int operator()(int&&) = delete; - int operator()(const int&&) = delete; -}; - -struct CLVal { - int operator()(int&) = delete; - constexpr int operator()(const int&) { return 1; } - int operator()(int&&) = delete; - int operator()(const int&&) = delete; -}; - -struct RVal { - int operator()(int&) = delete; - int operator()(const int&) = delete; - constexpr int operator()(int&&) { return 1; } - int operator()(const int&&) = delete; -}; - -struct CRVal { - int operator()(int&) = delete; - int operator()(const int&) = delete; - int operator()(int&&) = delete; - constexpr int operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr int operator()(int) & { return 1; } - int operator()(int) const& = delete; - int operator()(int) && = delete; - int operator()(int) const&& = delete; -}; - -struct CRefQual { - int operator()(int) & = delete; - constexpr int operator()(int) const& { return 1; } - int operator()(int) && = delete; - int operator()(int) const&& = delete; -}; - -struct RVRefQual { - int operator()(int) & = delete; - int operator()(int) const& = delete; - constexpr int operator()(int) && { return 1; } - int operator()(int) const&& = delete; -}; - -struct RVCRefQual { - int operator()(int) & = delete; - int operator()(int) const& = delete; - int operator()(int) && = delete; - constexpr int operator()(int) const&& { return 1; } -}; - -struct NonCopy { - int value; - constexpr explicit NonCopy(int val) : value(val) {} - NonCopy(const NonCopy&) = delete; -}; - -struct NonConst { - int non_const() { return 1; } -}; - -template <class E, class F> -concept has_transform = - requires(E&& e, F&& f) { - { std::forward<E>(e).transform(std::forward<F>(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&, int()>); -static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without &qualifier on F'soperator() - { - std::expected<int, int> e(0); - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform(LVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - std::expected<int, int> e(0); - RefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform(l); - assert(val == 1); - } - } - - // Test const& overload - { - // Without & qualifier on F's operator() - { - const std::expected<int, int> e(0); - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform(CLVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - const std::expected<int, int> e(0); - const CRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform(l); - assert(val == 1); - } - } - - // Test && overload - { - // Without & qualifier on F's operator() - { - std::expected<int, int> e(0); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform(RVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - std::expected<int, int> e(0); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform(RVRefQual{}); - assert(val == 1); - } - } - - // Test const&& overload - { - // Without & qualifier on F's operator() - { - const std::expected<int, int> e(0); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform(CRVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - const std::expected<int, int> e(0); - const RVCRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform(std::move(l)); - assert(val == 1); - } - } -} -// clang-format on - -constexpr void test_take_val_return_void() { - std::expected<int, int> e(1); - int val = 0; - e.transform([&val]<typename T>(T&&) -> void { - static_assert(std::is_same_v<T, int&>); - assert(val == 0); - val = 1; - }); - assert(val == 1); - std::move(e).transform([&val]<typename T>(T&&) -> void { - static_assert(std::is_same_v<T, int>); - assert(val == 1); - val = 2; - }); - - const auto& ce = e; - assert(val == 2); - ce.transform([&val]<typename T>(T&&) -> void { - static_assert(std::is_same_v<T, const int&>); - assert(val == 2); - val = 3; - }); - assert(val == 3); - std::move(ce).transform([&val]<typename T>(T&&) -> void { - static_assert(std::is_same_v<T, const int>); - assert(val == 3); - val = 4; - }); - assert(val == 4); -} - -// check val member is direct-non-list-initialized with invoke(std::forward<F>(f), value()) -constexpr void test_direct_non_list_init() { - auto xform = [](int i) { return NonCopy(i); }; - std::expected<int, int> e(2); - std::expected<NonCopy, int> n = e.transform(xform); - assert(n.value().value == 2); -} - -// check that the lambda body is not instantiated during overload resolution -constexpr void test_sfinae() { - std::expected<NonConst, int> e(std::unexpected<int>(2)); - auto l = [](auto&& x) { return x.non_const(); }; - e.transform(l); - std::move(e).transform(l); - - std::expected<int, int> e1(std::unexpected<int>(1)); - const auto& ce1 = e1; - const auto never_called = [](int) { - assert(false); - return std::expected<int, int>(); - }; - - e1.transform(never_called); - std::move(e1).transform(never_called); - ce1.and_then(never_called); - std::move(ce1).transform(never_called); -} - -constexpr bool test() { - test_sfinae(); - test_val_types(); - test_direct_non_list_init(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp deleted file mode 100644 index edcc56abc2f7..000000000000 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp +++ /dev/null @@ -1,221 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, -// please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333, but we have a workaround to -// avoid this issue. - -// <expected> - -// template<class F> constexpr auto transform_error(F&& f) &; -// template<class F> constexpr auto transform_error(F&& f) const &; -// template<class F> constexpr auto transform_error(F&& f) &&; -// template<class F> constexpr auto transform_error(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <memory> -#include <type_traits> -#include <utility> - -struct LVal { - constexpr int operator()(int&) { return 1; } - int operator()(const int&) = delete; - int operator()(int&&) = delete; - int operator()(const int&&) = delete; -}; - -struct CLVal { - int operator()(int&) = delete; - constexpr int operator()(const int&) { return 1; } - int operator()(int&&) = delete; - int operator()(const int&&) = delete; -}; - -struct RVal { - int operator()(int&) = delete; - int operator()(const int&) = delete; - constexpr int operator()(int&&) { return 1; } - int operator()(const int&&) = delete; -}; - -struct CRVal { - int operator()(int&) = delete; - int operator()(const int&) = delete; - int operator()(int&&) = delete; - constexpr int operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr int operator()(int) & { return 1; } - int operator()(int) const& = delete; - int operator()(int) && = delete; - int operator()(int) const&& = delete; -}; - -struct CRefQual { - int operator()(int) & = delete; - constexpr int operator()(int) const& { return 1; } - int operator()(int) && = delete; - int operator()(int) const&& = delete; -}; - -struct RVRefQual { - int operator()(int) & = delete; - int operator()(int) const& = delete; - constexpr int operator()(int) && { return 1; } - int operator()(int) const&& = delete; -}; - -struct RVCRefQual { - int operator()(int) & = delete; - int operator()(int) const& = delete; - int operator()(int) && = delete; - constexpr int operator()(int) const&& { return 1; } -}; - -struct NonCopy { - int value; - constexpr explicit NonCopy(int val) : value(val) {} - NonCopy(const NonCopy&) = delete; -}; - -struct NonConst { - int non_const() { return 1; } -}; - -template <class E, class F> -concept has_transform_error = - requires(E&& e, F&& f) { - { std::forward<E>(e).transform_error(std::forward<F>(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_transform_error<const std::expected<std::unique_ptr<int>, int>&, int()>); -static_assert(!has_transform_error<const std::expected<std::unique_ptr<int>, int>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without & qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform_error(LVal{}); - assert(val.error() == 1); - } - - // With & qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - RefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform_error(l); - assert(val.error() == 1); - } - } - - // Test const& overload - { - // Without const& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform_error(CLVal{}); - assert(val.error() == 1); - } - - // With const& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - const CRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = e.transform_error(l); - assert(val.error() == 1); - } - } - - // Test && overload - { - // Without && qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform_error(RVal{}); - assert(val.error() == 1); - } - - // With && qualifier on F's operator() - { - std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform_error(RVRefQual{}); - assert(val.error() == 1); - } - } - - // Test const&& overload - { - // Without const&& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform_error(CRVal{}); - assert(val.error() == 1); - } - - // With const&& qualifier on F's operator() - { - const std::expected<int, int> e(std::unexpected<int>(0)); - const RVCRefQual l{}; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).transform_error(std::move(l)); - assert(val.error() == 1); - } - } -} -// clang-format on - -// check unex member is direct-non-list-initialized with invoke(std::forward<F>(f), error()) -constexpr void test_direct_non_list_init() { - auto xform = [](int i) { return NonCopy(i); }; - std::expected<int, int> e(std::unexpected<int>(2)); - std::expected<int, NonCopy> n = e.transform_error(xform); - assert(n.error().value == 2); -} - -// check that the lambda body is not instantiated during overload resolution -constexpr void test_sfinae() { - std::expected<int, NonConst> e(2); - auto l = [](auto&& x) { return x.non_const(); }; - e.transform_error(l); - std::move(e).transform_error(l); - - std::expected<int, int> e1; - const auto& ce1 = e1; - - const auto never_called = [](int) { - assert(false); - return 0; - }; - - e1.transform_error(never_called); - std::move(e1).transform_error(never_called); - ce1.transform_error(never_called); - std::move(ce1).transform_error(never_called); -} - -constexpr bool test() { - test_sfinae(); - test_val_types(); - test_direct_non_list_init(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.expected/observers/error_or.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/error_or.pass.cpp deleted file mode 100644 index f698f44ba8f3..000000000000 --- a/libcxx/test/std/utilities/expected/expected.expected/observers/error_or.pass.cpp +++ /dev/null @@ -1,96 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// template<class G = E> constexpr E error_or(G&& e) const &; -// template<class G = E> constexpr E error_or(G&& e) &&; - -#include <cassert> -#include <concepts> -#include <expected> -#include <type_traits> -#include <utility> - -struct ConstructFromInt { - int value; - constexpr ConstructFromInt(int v) : value(v) {} -}; - -constexpr bool test_default_template_arg() { - // const &, has_value() - { - const std::expected<int, ConstructFromInt> e(5); - std::same_as<ConstructFromInt> decltype(auto) x = e.error_or(10); - assert(x.value == 10); - } - - // const &, !has_value() - { - const std::expected<int, ConstructFromInt> e(std::unexpect, 5); - std::same_as<ConstructFromInt> decltype(auto) x = e.error_or(10); - assert(x.value == 5); - } - - // &&, has_value() - { - const std::expected<int, ConstructFromInt> e(5); - std::same_as<ConstructFromInt> decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 10); - } - - // &&, !has_value() - { - const std::expected<int, ConstructFromInt> e(std::unexpect, 5); - std::same_as<ConstructFromInt> decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 5); - } - - return true; -} - -constexpr bool test() { - // const &, has_value() - { - const std::expected<int, int> e(5); - std::same_as<int> decltype(auto) x = e.error_or(10); - assert(x == 10); - } - - // const &, !has_value() - { - const std::expected<int, int> e(std::unexpect, 5); - std::same_as<int> decltype(auto) x = e.error_or(10); - assert(x == 5); - } - - // &&, has_value() - { - std::expected<int, int> e(5); - std::same_as<int> decltype(auto) x = std::move(e).error_or(10); - assert(x == 10); - } - - // &&, !has_value() - { - std::expected<int, int> e(std::unexpect, 5); - std::same_as<int> decltype(auto) x = std::move(e).error_or(10); - assert(x == 5); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - test_default_template_arg(); - static_assert(test_default_template_arg()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp deleted file mode 100644 index f60002c67ebc..000000000000 --- a/libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp +++ /dev/null @@ -1,149 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// <expected> - -// template<class F> constexpr auto and_then(F&& f) &; -// template<class F> constexpr auto and_then(F&& f) const &; -// template<class F> constexpr auto and_then(F&& f) &&; -// template<class F> constexpr auto and_then(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <memory> -#include <type_traits> -#include <utility> - -struct NonCopyable { - constexpr NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - constexpr NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -template <class E, class F> -concept has_and_then = - requires(E&& e, F&& f) { - { std::forward<E>(e).and_then(std::forward<F>(f)) }; - }; - -std::expected<void, int> return_int() { return {}; } -std::expected<void, NonCopyable> return_noncopyable() { return {}; } -std::expected<void, NonMovable> return_nonmovable() { return {}; } - -static_assert(has_and_then<std::expected<void, int>&, decltype(return_int)>); -static_assert(!has_and_then<std::expected<void, NonCopyable>&, decltype(return_noncopyable)>); -static_assert(has_and_then<const std::expected<void, int>&, decltype(return_int)>); -static_assert(!has_and_then<const std::expected<void, NonCopyable>&, decltype(return_noncopyable)>); -static_assert(has_and_then<std::expected<void, int>&&, decltype(return_int)>); -static_assert(!has_and_then<std::expected<void, NonMovable>&&, decltype(return_nonmovable)>); -static_assert(has_and_then<const std::expected<void, int>&&, decltype(return_int)>); -static_assert(!has_and_then<const std::expected<void, NonMovable>&&, decltype(return_nonmovable)>); - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&, int()>); -static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&&, int()>); - -constexpr void test_val_types() { - // Test & overload - { - auto l = [] -> std::expected<int, int> { return 2; }; - std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = v.and_then(l); - assert(val == 2); - } - - // Test const& overload - { - auto l = [] -> std::expected<int, int> { return 2; }; - const std::expected<void, int> v; - assert(v.and_then(l).value() == 2); - static_assert(std::is_same_v< decltype(v.and_then(l)), std::expected<int, int>>); - } - - // Test && overload - { - auto l = [] -> std::expected<int, int> { return 2; }; - std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(l); - assert(val == 2); - } - - // Test const&& overload - { - auto l = [] -> std::expected<int, int> { return 2; }; - const std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(l); - assert(val == 2); - } -} - -constexpr void test_fail() { - // Test & overload - { - auto f = [] -> std::expected<int, int> { - assert(false); - return 0; - }; - std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<int, int>> decltype(auto) val = v.and_then(f); - assert(val.error() == 2); - } - - // Test const& overload - { - auto f = [] -> std::expected<int, int> { - assert(false); - return 0; - }; - const std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<int, int>> decltype(auto) val = v.and_then(f); - assert(val.error() == 2); - } - - // Test && overload - { - auto f = [] -> std::expected<int, int> { - assert(false); - return 0; - }; - std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(f); - assert(val.error() == 2); - } - - // Test const&& overload - { - auto f = [] -> std::expected<int, int> { - assert(false); - return 0; - }; - const std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).and_then(f); - assert(val.error() == 2); - } -} - -constexpr bool test() { - test_fail(); - test_val_types(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/or_else.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/or_else.pass.cpp deleted file mode 100644 index 13e341c6d20c..000000000000 --- a/libcxx/test/std/utilities/expected/expected.void/monadic/or_else.pass.cpp +++ /dev/null @@ -1,104 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// <expected> - -// template<class F> constexpr auto or_else(F&& f) &; -// template<class F> constexpr auto or_else(F&& f) const &; -// template<class F> constexpr auto or_else(F&& f) &&; -// template<class F> constexpr auto or_else(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <type_traits> -#include <utility> - -constexpr void test_val_types() { - // Test & overload - { - auto l = [](auto) -> std::expected<void, long> { return {}; }; - std::expected<void, int> v(std::unexpected<int>(1)); - std::same_as<std::expected<void, long>> decltype(auto) val = v.or_else(l); - assert(val.has_value()); - } - - // Test const& overload - { - auto l = [](auto) -> std::expected<void, long> { return {}; }; - const std::expected<void, int> v(std::unexpected<int>(1)); - std::same_as<std::expected<void, long>> decltype(auto) val = v.or_else(l); - assert(val.has_value()); - } - - // Test && overload - { - auto l = [](auto) -> std::expected<void, long> { return {}; }; - std::expected<void, int> v(std::unexpected<int>(1)); - std::same_as<std::expected<void, long>> decltype(auto) val = std::move(v).or_else(l); - assert(val.has_value()); - } - - // Test const&& overload - { - auto l = [](auto) -> std::expected<void, long> { return {}; }; - const std::expected<void, int> v(std::unexpected<int>(1)); - std::same_as<std::expected<void, long>> decltype(auto) val = std::move(v).or_else(l); - assert(val.has_value()); - } -} - -constexpr void test_fail() { - auto never_called = [](auto) -> std::expected<void, long> { - assert(false); - return std::expected<void, long>(std::unexpected<long>(5)); - }; - - // Test & overload - { - std::expected<void, int> v; - std::same_as<std::expected<void, long>> decltype(auto) val = v.or_else(never_called); - assert(val.has_value()); - } - - // Test const& overload - { - const std::expected<void, int> v; - std::same_as<std::expected<void, long>> decltype(auto) val = v.or_else(never_called); - assert(val.has_value()); - } - - // Test && overload - { - std::expected<void, int> v; - std::same_as<std::expected<void, long>> decltype(auto) val = std::move(v).or_else(never_called); - assert(val.has_value()); - } - - // Test const&& overload - { - const std::expected<void, int> v; - std::same_as<std::expected<void, long>> decltype(auto) val = std::move(v).or_else(never_called); - assert(val.has_value()); - } -} - -constexpr bool test() { - test_fail(); - test_val_types(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp deleted file mode 100644 index ea90006e3199..000000000000 --- a/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// <expected> - -// template<class F> constexpr auto transform_error(F&& f) &; -// template<class F> constexpr auto transform_error(F&& f) const &; -// template<class F> constexpr auto transform_error(F&& f) &&; -// template<class F> constexpr auto transform_error(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <memory> -#include <type_traits> -#include <utility> - -template <class E, class F> -concept has_transform = - requires(E&& e, F&& f) { - { std::forward<E>(e).transform(std::forward<F>(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&, int()>); -static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&&, int()>); - -constexpr void test_val_types() { - // Test & overload - { - auto l = [] -> int { return 1; }; - std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l); - assert(val == 1); - } - - // Test const& overload - { - auto l = [] -> int { return 1; }; - const std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l); - assert(val == 1); - } - - // Test && overload - { - auto l = [] -> int { return 1; }; - std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l); - assert(val == 1); - } - - // Test const&& overload - { - auto l = [] -> int { return 1; }; - const std::expected<void, int> v; - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l); - assert(val == 1); - } -} - -constexpr void test_fail() { - // Test & overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - std::expected<void, int> v(std::unexpected<int>(5)); - std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l); - assert(val.error() == 5); - } - - // Test const& overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - const std::expected<void, int> v(std::unexpected<int>(5)); - std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l); - assert(val.error() == 5); - } - - // Test && overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - std::expected<void, int> v(std::unexpected<int>(5)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l); - assert(val.error() == 5); - } - - // Test const&& overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - const std::expected<void, int> v(std::unexpected<int>(5)); - std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l); - assert(val.error() == 5); - } -} - -constexpr bool test() { - test_fail(); - test_val_types(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp deleted file mode 100644 index f0e19ac3c398..000000000000 --- a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, -// please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333, but we have a workaround to -// avoid this issue. - -// <expected> - -// template<class F> constexpr auto transform_error(F&& f) &; -// template<class F> constexpr auto transform_error(F&& f) const &; -// template<class F> constexpr auto transform_error(F&& f) &&; -// template<class F> constexpr auto transform_error(F&& f) const &&; - -#include <expected> -#include <concepts> -#include <cassert> -#include <type_traits> -#include <utility> - -struct NonCopy { - int value; - constexpr explicit NonCopy(int val) : value(val) {} - NonCopy(const NonCopy&) = delete; -}; - -constexpr void test_val_types() { - // Test & overload - { - auto l = [](auto) -> int { return 1; }; - std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l); - assert(val.error() == 1); - } - - // Test const& overload - { - auto l = [](auto) -> int { return 1; }; - const std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l); - assert(val.error() == 1); - } - - // Test && overload - { - auto l = [](auto) -> int { return 1; }; - std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l); - assert(val.error() == 1); - } - - // Test const&& overload - { - auto l = [](auto) -> int { return 1; }; - const std::expected<void, int> v(std::unexpected<int>(2)); - std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l); - assert(val.error() == 1); - } -} - -constexpr void test_fail() { - // Test & overload - { - auto l = [](auto) -> int { - assert(false); - return 0; - }; - std::expected<void, int> v; - std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l); - assert(val.has_value()); - } - - // Test const& overload - { - auto l = [](auto) -> int { - assert(false); - return 0; - }; - const std::expected<void, int> v; - std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l); - assert(val.has_value()); - } - - // Test && overload - { - auto l = [](auto) -> int { - assert(false); - return 0; - }; - std::expected<void, int> v; - std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l); - assert(val.has_value()); - } - - // Test const&& overload - { - auto l = [](auto) -> int { - assert(false); - return 0; - }; - const std::expected<void, int> v; - std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l); - assert(val.has_value()); - } -} - -// check unex member is direct-non-list-initialized with invoke(std::forward<F>(f)) -constexpr void test_direct_non_list_init() { - auto x = [](int i) { return NonCopy(i); }; - std::expected<void, int> v(std::unexpected<int>(2)); - std::expected<void, NonCopy> nv = v.transform_error(x); - assert(nv.error().value == 2); -} - -constexpr bool test() { - test_fail(); - test_val_types(); - test_direct_non_list_init(); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/utilities/expected/expected.void/observers/error_or.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/error_or.pass.cpp deleted file mode 100644 index db2891f61c3c..000000000000 --- a/libcxx/test/std/utilities/expected/expected.void/observers/error_or.pass.cpp +++ /dev/null @@ -1,96 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// template<class G = E> constexpr E error_or(G&& e) const &; -// template<class G = E> constexpr E error_or(G&& e) &&; - -#include <cassert> -#include <concepts> -#include <expected> -#include <type_traits> -#include <utility> - -struct ConstructFromInt { - int value; - constexpr ConstructFromInt(int v) : value(v) {} -}; - -constexpr bool test_default_template_arg() { - // const &, has_value() - { - const std::expected<void, ConstructFromInt> e; - std::same_as<ConstructFromInt> decltype(auto) x = e.error_or(10); - assert(x.value == 10); - } - - // const &, !has_value() - { - const std::expected<void, ConstructFromInt> e(std::unexpect, 5); - std::same_as<ConstructFromInt> decltype(auto) x = e.error_or(10); - assert(x.value == 5); - } - - // &&, has_value() - { - const std::expected<void, ConstructFromInt> e; - std::same_as<ConstructFromInt> decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 10); - } - - // &&, !has_value() - { - const std::expected<void, ConstructFromInt> e(std::unexpect, 5); - std::same_as<ConstructFromInt> decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 5); - } - - return true; -} - -constexpr bool test() { - // const &, has_value() - { - const std::expected<void, int> e; - std::same_as<int> decltype(auto) x = e.error_or(10); - assert(x == 10); - } - - // const &, !has_value() - { - const std::expected<void, int> e(std::unexpect, 5); - std::same_as<int> decltype(auto) x = e.error_or(10); - assert(x == 5); - } - - // &&, has_value() - { - std::expected<void, int> e; - std::same_as<int> decltype(auto) x = std::move(e).error_or(10); - assert(x == 10); - } - - // &&, !has_value() - { - std::expected<void, int> e(std::unexpect, 5); - std::same_as<int> decltype(auto) x = std::move(e).error_or(10); - assert(x == 5); - } - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - test_default_template_arg(); - static_assert(test_default_template_arg()); - - return 0; -} diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index c23ebd5b7a03..5ace82348dcb 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -306,7 +306,7 @@ feature_test_macros = [ add_version_header(x) for x in [ "unimplemented": True, }, { "name": "__cpp_lib_expected", - "values": { "c++2b": 202211 }, + "values": { "c++2b": 202202 }, "headers": ["expected"], }, { "name": "__cpp_lib_filesystem", |