From 5ae9098e5c1564bdfe0ae0fdbc02e581138eeac7 Mon Sep 17 00:00:00 2001 From: yronglin Date: Thu, 18 May 2023 00:55:03 +0800 Subject: [PATCH] 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 --- libcxx/docs/FeatureTestMacroTable.rst | 2 +- libcxx/docs/ReleaseNotes.rst | 1 - libcxx/docs/Status/Cxx2bIssues.csv | 4 +- libcxx/docs/Status/Cxx2bPapers.csv | 2 +- libcxx/include/__expected/expected.h | 618 +----------------- libcxx/include/version | 4 +- .../and_then.mandates.verify.cpp | 126 ---- .../error_or.mandates.verify.cpp | 72 -- .../no_unique_address.compile.pass.cpp | 16 - .../or_else.mandates.verify.cpp | 125 ---- .../transform_error.mandates.verify.cpp | 84 --- .../and_then.mandates.verify.cpp | 125 ---- .../error_or.mandates.verify.cpp | 71 -- .../no_unique_address.compile.pass.cpp | 12 - .../expected.void/or_else.mandates.verify.cpp | 121 ---- .../transform_error.mandates.verify.cpp | 84 --- .../expected.version.compile.pass.cpp | 6 +- .../version.version.compile.pass.cpp | 6 +- .../monadic/and_then.pass.cpp | 288 -------- .../monadic/or_else.pass.cpp | 202 ------ .../monadic/transform.pass.cpp | 251 ------- .../monadic/transform_error.pass.cpp | 221 ------- .../observers/error_or.pass.cpp | 96 --- .../expected.void/monadic/and_then.pass.cpp | 149 ----- .../expected.void/monadic/or_else.pass.cpp | 104 --- .../expected.void/monadic/transform.pass.cpp | 126 ---- .../monadic/transform_error.pass.cpp | 134 ---- .../expected.void/observers/error_or.pass.cpp | 96 --- .../generate_feature_test_macro_components.py | 2 +- 29 files changed, 35 insertions(+), 3113 deletions(-) delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.expected/error_or.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.expected/or_else.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.void/and_then.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.void/or_else.mandates.verify.cpp delete mode 100644 libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.expected/monadic/and_then.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.expected/monadic/or_else.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.expected/observers/error_or.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.void/monadic/and_then.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.void/monadic/or_else.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp delete mode 100644 libcxx/test/std/utilities/expected/expected.void/observers/error_or.pass.cpp diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 48c2d0ddfae19..0f5ee6c24485a 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 d2db69e67b986..6e6cdc25ce634 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 d658c18a64896..95cc327b0d01e 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -274,7 +274,7 @@ "`3853 `__","``basic_const_iterator::operator->`` is ill-formed","February 2023","","","" "`3857 `__","``basic_string_view`` should allow explicit conversion when only traits vary","February 2023","|Complete|","17.0","" "`3860 `__","``range_common_reference_t`` is missing","February 2023","|Complete|","17.0","|ranges|" -"`3866 `__","Bad Mandates for ``expected::transform_error`` overloads","February 2023","|Complete|","17.0","" +"`3866 `__","Bad Mandates for ``expected::transform_error`` overloads","February 2023","","","" "`3867 `__","Should ``std::basic_osyncstream``'s move assignment operator be ``noexcept``?","February 2023","","","" "`3441 `__","Misleading note about calls to customization points","February 2023","","","" "`3622 `__","Misspecified transitivity of equivalence in ยง[unord.req.general]","February 2023","","","" @@ -301,7 +301,7 @@ "`3872 `__","``basic_const_iterator`` should have custom ``iter_move``","February 2023","","","" "`3875 `__","``std::ranges::repeat_view::iterator`` may be ill-formed","February 2023","","","|ranges|" "`3876 `__","Default constructor of ``std::layout_XX::mapping`` misses precondition","February 2023","","","" -"`3877 `__","Incorrect constraints on ``const``-qualified monadic overloads for ``std::expected``","February 2023","|Complete|","17.0","" +"`3877 `__","Incorrect constraints on ``const``-qualified monadic overloads for ``std::expected``","February 2023","","","" "`3878 `__","import ``std;`` should guarantee initialization of standard iostreams objects","February 2023","","","" "`3879 `__","``erase_if`` for ``flat_{,multi}set`` is incorrectly specified","February 2023","","","" "`3880 `__","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 a49dc627a7fab..550fb34d4b34e 100644 --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -100,7 +100,7 @@ "`P1478R8 `__","LWG", "``Byte-wise`` ``atomic`` ``memcpy``", "November 2022","","","|concurrency TS|" "`P2167R3 `__","LWG", "Improved Proposed Wording for LWG 2114", "November 2022","","","" "`P2396R1 `__","LWG", "Concurrency TS 2 fixes ", "November 2022","","","|concurrency TS|" -"`P2505R5 `__","LWG", "Monadic Functions for ``std::expected``", "November 2022","|Complete|","17.0","" +"`P2505R5 `__","LWG", "Monadic Functions for ``std::expected``", "November 2022","","","" "`P2539R4 `__","LWG", "Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?", "November 2022","","","|format|" "`P2602R2 `__","LWG", "Poison Pills are Too Toxic", "November 2022","","","|ranges|" "`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 668e23f21c71b..3ff8fbc7b2110 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 expected; - -template -struct __is_std_expected : false_type {}; - -template -struct __is_std_expected> : true_type {}; - -struct __expected_construct_in_place_from_invoke_tag {}; -struct __expected_construct_unexpected_from_invoke_tag {}; +namespace __expected { template _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 expected { static_assert( @@ -176,15 +166,6 @@ class expected { _Not, const expected<_Up, _OtherErr>&>>, _Not, const expected<_Up, _OtherErr>>> >; - template - _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 - _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 @@ -557,28 +538,28 @@ class expected { _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 @@ class expected { return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); } - template - _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 - _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 - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { - using _Up = remove_cvref_t>; - 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, - "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 - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { - using _Up = remove_cvref_t>; - 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, - "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 - requires is_constructible_v<_Tp, _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { - using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - requires is_constructible_v<_Tp, const _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { - using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - requires is_constructible_v<_Tp, _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { - using _Gp = remove_cvref_t>; - 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, - "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 - requires is_constructible_v<_Tp, const _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { - using _Gp = remove_cvref_t>; - 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, - "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 - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Tp, _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { - using _Gp = remove_cv_t>; - 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 - requires is_constructible_v<_Tp, const _Tp&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { - using _Gp = remove_cv_t>; - 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 - requires is_constructible_v<_Tp, _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { - using _Gp = remove_cv_t>; - 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 - requires is_constructible_v<_Tp, const _Tp&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { - using _Gp = remove_cv_t>; - 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 requires(!is_void_v<_T2>) @@ -883,66 +625,24 @@ class expected { private: struct __empty_t {}; - - template - union __union_t { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {} - - template - _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 - _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 - 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 - _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 - _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 @@ class expected<_Tp, _Err> { std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); } -private: - template - _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 - _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 @@ class expected<_Tp, _Err> { _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 @@ class expected<_Tp, _Err> { return std::move(__union_.__unex_); } - template - _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 - _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 - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v, "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 - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v, "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 - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v, "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 - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { - using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); - static_assert( - is_same_v, "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 - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { - using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { - using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); - static_assert(is_same_v, - "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 - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { - using _Gp = remove_cvref_t>; - 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, - "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 - _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { - using _Gp = remove_cvref_t>; - 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, - "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 - requires is_constructible_v<_Err, _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, const _Err&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { - using _Up = remove_cv_t>; - 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 - requires is_constructible_v<_Err, const _Err&&> - _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { - using _Up = remove_cv_t>; - 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 - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { - using _Gp = remove_cv_t>; - 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 - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { - using _Gp = remove_cv_t>; - 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 - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { - using _Gp = remove_cv_t>; - 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 - _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { - using _Gp = remove_cv_t>; - 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 requires is_void_v<_T2> @@ -1489,55 +947,23 @@ class expected<_Tp, _Err> { private: struct __empty_t {}; - - template - 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 - _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 - requires is_trivially_move_constructible_v<_ErrorType> - union __union_t<_ErrorType> { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - - template - _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 4cb74e29cbf2f..b87abdfce5226 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -82,7 +82,7 @@ __cpp_lib_erase_if 202002L __cpp_lib_execution 201902L 201603L // C++17 -__cpp_lib_expected 202211L +__cpp_lib_expected 202202L __cpp_lib_filesystem 201703L __cpp_lib_format 202106L __cpp_lib_format_ranges 202207L @@ -399,7 +399,7 @@ __cpp_lib_void_t 201411L # 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 692ac60d07383..0000000000000 --- 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 constexpr auto and_then(F&& f) &; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) const &; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) &&; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) const &&; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -#include -#include - -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 lval_error_type_not_same_as_int(int&) { return {}; } -std::expected clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected 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 f1(1); - f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - std::expected f1(1); - f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)(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 f1(1); - f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - const std::expected f1(1); - f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)(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 f1(1); - std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - std::expected f1(1); - std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)(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 f1(1); - std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - const std::expected f1(1); - std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)(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 f0ab5c4955171..0000000000000 --- 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 constexpr E error_or(G&&) const &; -// Mandates: is_copy_constructible_v is true and is_convertible_v is true. - -// template constexpr E error_or(G&&) &&; -// Mandates: is_move_constructible_v is true and is_convertible_v is true. - -#include -#include - -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, - { - const std::expected f1(std::unexpect, 0); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 - { - const std::expected f1(std::unexpect, NotConvertibleFromInt{}); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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, - { - std::expected f1(std::unexpect, 0); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 - { - std::expected f1(std::unexpect, NotConvertibleFromInt{}); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 c8c217054ae6c..3fd047df7134c 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) == sizeof(bool)); -static_assert(sizeof(std::expected) == 2 * sizeof(int) + alignof(std::expected)); -static_assert(sizeof(std::expected) == sizeof(B) + alignof(std::expected)); -static_assert(sizeof(std::expected) == 2 * sizeof(int) + alignof(std::expected)); -static_assert(sizeof(std::expected) == 2 * sizeof(int) + alignof(std::expected)); -static_assert(sizeof(std::expected) == sizeof(B) + alignof(std::expected)); -static_assert(sizeof(std::expected) == sizeof(B) + alignof(std::expected)); 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 1264cc06b48c5..0000000000000 --- 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 constexpr auto or_else(F&& f) &; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) const &; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) &&; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) const &&; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -#include -#include - -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 lval_error_type_not_same_as_int(int&) { return {}; } -std::expected clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected 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 f1(std::unexpected(1)); - f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - std::expected f1(std::unexpected(1)); - f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - const std::expected f1(std::unexpected(1)); - f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - std::expected f1(std::unexpected(1)); - std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - const std::expected f1(std::unexpected(1)); - std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 32b82fdaa2551..0000000000000 --- 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 constexpr auto transform_error(F&& f) &; -// template constexpr auto transform_error(F&& f) const &; -// -// Let G be remove_cv_t> -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward(f), error())); is well-formed. - -// template constexpr auto transform_error(F&& f) &&; -// template constexpr auto transform_error(F&& f) const &&; -// -// Let G be remove_cv_t>. -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward(f), std::move(error()))); is well-formed. - -#include -#include - -static int val; - -template -std::unexpected return_unexpected(T) { - return std::unexpected(1); -} - -template -int& return_no_object(T) { - return val; -} - -// clang-format off -void test() { - - // Test & overload - { - std::expected e; - e.transform_error(return_unexpected); // 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 for {{.*}} is ill-formed.}} - - e.transform_error(return_no_object); // 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 for {{.*}} is ill-formed.}} - } - - // Test const& overload - { - const std::expected e; - e.transform_error(return_unexpected); // 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); // 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 e; - std::move(e).transform_error(return_unexpected); // 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); // 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 e; - std::move(e).transform_error(return_unexpected); // 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); // 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 615d5347fcc0c..0000000000000 --- 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 constexpr auto and_then(F&& f) &; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) const &; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) &&; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto and_then(F&& f) const &&; -// Mandates: -// Let U be std::remove_cvref_t> -// U is a specialization of std::expected and std::is_same_v is true - -#include -#include - -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 lval_error_type_not_same_as_int(void) { return {}; } -std::expected clval_error_type_not_same_as_int(void) { return {}; } -std::expected rval_error_type_not_same_as_int(void) { return {}; } -std::expected 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 f1; - f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - std::expected f1; - f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)()>' 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 f1; - f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - const std::expected f1; - f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)()>' 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 f1; - std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - std::expected f1; - std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)()>' 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 f1; - std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::and_then' 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 - { - const std::expected f1; - std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::and_then (&)()>' 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 a36665b25c876..0000000000000 --- 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 constexpr E error_or(G&&) const &; -// Mandates: is_copy_constructible_v is true and is_convertible_v is true. - -// template constexpr E error_or(G&&) &&; -// Mandates: is_move_constructible_v is true and is_convertible_v is true. - -#include -#include - -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, - { - const std::expected f1(std::unexpect, 0); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 - { - const std::expected f1(std::unexpect, NotConvertibleFromInt{}); - f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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, - { - std::expected f1(std::unexpect, 0); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 - { - std::expected f1(std::unexpect, NotConvertibleFromInt{}); - std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected::error_or' 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 dc59a6228386b..1ad2aa125c295 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) == sizeof(bool)); -static_assert(sizeof(std::expected) == 2 * sizeof(int) + alignof(std::expected)); -static_assert(sizeof(std::expected) == sizeof(B) + alignof(std::expected)); 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 9ebf6f586de20..0000000000000 --- 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 constexpr auto or_else(F&& f) &; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) const &; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) &&; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -// template constexpr auto or_else(F&& f) const &&; -// Mandates: -// Let G be std::remove_cvref_t> -// G is a specialization of std::expected and std::is_same_v is true - -#include -#include - -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 lval_error_type_not_same_as_int(int&) { return {}; } -std::expected clval_error_type_not_same_as_int(const int&) { return {}; } -std::expected rval_error_type_not_same_as_int(int&&) { return {}; } -std::expected 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 f1(std::unexpected(1)); - f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - std::expected f1(std::unexpected(1)); - f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - const std::expected f1(std::unexpected(1)); - f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - std::expected f1(std::unexpected(1)); - std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 f1(std::unexpected(1)); - std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected::or_else' 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 - { - const std::expected f1(std::unexpected(1)); - std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected::or_else (&)(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 cdae36733a332..0000000000000 --- 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 constexpr auto transform_error(F&& f) &; -// template constexpr auto transform_error(F&& f) const &; -// -// Let G be remove_cv_t> -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward(f), error())); is well-formed. - -// template constexpr auto transform_error(F&& f) &&; -// template constexpr auto transform_error(F&& f) const &&; -// -// Let G be remove_cv_t>. -// G is a valid template argument for unexpected ([expected.un.general]) and the declaration -// G g(invoke(std::forward(f), std::move(error()))); is well-formed. - -#include -#include - -static int val; - -template -std::unexpected return_unexpected(T) { - return std::unexpected(1); -} - -template -int& return_no_object(T) { - return val; -} - -// clang-format off -void test() { - - // Test & overload - { - std::expected e; - e.transform_error(return_unexpected); // 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 with a E that is not a valid argument for unexpected is ill-formed}} - - e.transform_error(return_no_object); // 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 with a E that is not a valid argument for unexpected is ill-formed}} - } - - // Test const& overload - { - const std::expected e; - e.transform_error(return_unexpected); // 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); // 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 e; - std::move(e).transform_error(return_unexpected); // 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); // 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 e; - std::move(e).transform_error(return_unexpected); // 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); // 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 289609838a137..4872981be89e0 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 /* Constant Value - __cpp_lib_expected 202211L [C++2b] + __cpp_lib_expected 202202L [C++2b] */ #include @@ -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 74073cfcf1c13..e1bdde4551a78 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 1630931d4a853..0000000000000 --- 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 - -// - -// template constexpr auto and_then(F&& f) &; -// template constexpr auto and_then(F&& f) const &; -// template constexpr auto and_then(F&& f) &&; -// template constexpr auto and_then(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -struct LVal { - constexpr std::expected operator()(int&) { return 1; } - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct CLVal { - std::expected operator()(int&) = delete; - constexpr std::expected operator()(const int&) { return 1; } - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct RVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - constexpr std::expected operator()(int&&) { return 1; } - std::expected operator()(const int&&) = delete; -}; - -struct CRVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - constexpr std::expected operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr std::expected operator()(int) & { return 1; } - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct CRefQual { - std::expected operator()(int) & = delete; - constexpr std::expected operator()(int) const& { return 1; } - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct RVRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - constexpr std::expected operator()(int) && { return 1; } - std::expected operator()(int) const&& = delete; -}; - -struct RVCRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - constexpr std::expected operator()(int) const&& { return 1; } -}; - -struct UnexpectedLVal { - constexpr std::expected operator()(int&) { return std::expected(std::unexpected(5)); } - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct UnexpectedCLVal { - std::expected operator()(int&) = delete; - constexpr std::expected operator()(const int&) { return std::expected(std::unexpected(5)); } - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct UnexpectedRVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - constexpr std::expected operator()(int&&) { return std::expected(std::unexpected(5)); } - std::expected operator()(const int&&) = delete; -}; - -struct UnexpectedCRVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - constexpr std::expected operator()(const int&&) { return std::expected(std::unexpected(5)); } -}; - -struct UnexpectedRefQual { - constexpr std::expected operator()(int) & { return std::expected(std::unexpected(5)); } - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct UnexpectedCRefQual { - std::expected operator()(int) & = delete; - constexpr std::expected operator()(int) const& { return std::expected(std::unexpected(5)); } - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct UnexpectedRVRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - constexpr std::expected operator()(int) && { return std::expected(std::unexpected(5)); } - std::expected operator()(int) const&& = delete; -}; - -struct UnexpectedRVCRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - constexpr std::expected operator()(int) const&& { return std::expected(std::unexpected(5)); } -}; - -struct NonCopyable { - constexpr NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - constexpr NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -struct NonConst { - std::expected non_const() { return 1; } -}; - -template -concept has_and_then = requires(E&& e, F&& f) { - {std::forward(e).and_then(std::forward(f))}; -}; - -static_assert( has_and_then&, std::expected(int&)>); -static_assert(!has_and_then&, std::expected(int&)>); -static_assert( has_and_then&, std::expected(const int&)>); -static_assert(!has_and_then&, std::expected(const int&)>); -static_assert( has_and_then&&, std::expected(int)>); -static_assert(!has_and_then&&, std::expected(int)>); -static_assert( has_and_then&&, std::expected(const int)>); -static_assert(!has_and_then&&, std::expected(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>&, int()>); -static_assert(!has_and_then>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without &qualifier on F'soperator() - { - std::expected e{0}; - std::same_as> 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 e{0}; - RefQual l{}; - std::same_as> 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 e{0}; - std::same_as> 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 e{0}; - const CRefQual l{}; - std::same_as> 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 e{0}; - std::same_as> 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 e{0}; - std::same_as> 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 e{0}; - std::same_as> 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 e{0}; - const RVCRefQual l{}; - std::same_as> 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 e(std::unexpected(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 e(std::unexpected(1)); - const auto& ce = e; - - const auto never_called = [](int) { - assert(false); - return std::expected(); - }; - - 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 bf5b481a158ac..0000000000000 --- 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 - -// - -// template constexpr auto or_else(F&& f) &; -// template constexpr auto or_else(F&& f) const &; -// template constexpr auto or_else(F&& f) &&; -// template constexpr auto or_else(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -struct LVal { - constexpr std::expected operator()(int&) { return 1; } - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct CLVal { - std::expected operator()(int&) = delete; - constexpr std::expected operator()(const int&) { return 1; } - std::expected operator()(int&&) = delete; - std::expected operator()(const int&&) = delete; -}; - -struct RVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - constexpr std::expected operator()(int&&) { return 1; } - std::expected operator()(const int&&) = delete; -}; - -struct CRVal { - std::expected operator()(int&) = delete; - std::expected operator()(const int&) = delete; - std::expected operator()(int&&) = delete; - constexpr std::expected operator()(const int&&) { return 1; } -}; - -struct RefQual { - constexpr std::expected operator()(int) & { return 1; } - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct CRefQual { - std::expected operator()(int) & = delete; - constexpr std::expected operator()(int) const& { return 1; } - std::expected operator()(int) && = delete; - std::expected operator()(int) const&& = delete; -}; - -struct RVRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - constexpr std::expected operator()(int) && { return 1; } - std::expected operator()(int) const&& = delete; -}; - -struct RVCRefQual { - std::expected operator()(int) & = delete; - std::expected operator()(int) const& = delete; - std::expected operator()(int) && = delete; - constexpr std::expected operator()(int) const&& { return 1; } -}; - -template -concept has_or_else = - requires(E&& e, F&& f) { - { std::forward(e).or_else(std::forward(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, int>&, int()>); -static_assert(!has_or_else, int>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without & qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = e.or_else(LVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator - { - std::expected e(std::unexpected(0)); - RefQual l{}; - std::same_as> decltype(auto) val = e.or_else(l); - assert(val == 1); - } - } - - // Test const& overload - { - // Without const& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = e.or_else(CLVal{}); - assert(val == 1); - } - - // With const& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - const CRefQual l{}; - std::same_as> decltype(auto) val = e.or_else(l); - assert(val == 1); - } - } - - // Test && overload - { - // Without && qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = std::move(e).or_else(RVal{}); - assert(val == 1); - } - - // With && qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> 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 e(std::unexpected(0)); - std::same_as> decltype(auto) val = std::move(e).or_else(CRVal{}); - assert(val == 1); - } - - // With const&& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - const RVCRefQual l{}; - std::same_as> decltype(auto) val = std::move(e).or_else(std::move(l)); - assert(val == 1); - } - } -} -// clang-format on - -struct NonConst { - std::expected non_const() { return std::expected(std::unexpect, 1); } -}; - -// check that the lambda body is not instantiated during overload resolution -constexpr void test_sfinae() { - std::expected 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 e(1); - const auto& ce = e; - - const auto never_called = [](int) { - assert(false); - return std::expected(); - }; - - 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 b72055fb25230..0000000000000 --- 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. - -// - -// template constexpr auto transform(F&& f) &; -// template constexpr auto transform(F&& f) const &; -// template constexpr auto transform(F&& f) &&; -// template constexpr auto transform(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -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 -concept has_transform = - requires(E&& e, F&& f) { - { std::forward(e).transform(std::forward(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_transform>&, int()>); -static_assert(!has_transform>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without &qualifier on F'soperator() - { - std::expected e(0); - std::same_as> decltype(auto) val = e.transform(LVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - std::expected e(0); - RefQual l{}; - std::same_as> decltype(auto) val = e.transform(l); - assert(val == 1); - } - } - - // Test const& overload - { - // Without & qualifier on F's operator() - { - const std::expected e(0); - std::same_as> decltype(auto) val = e.transform(CLVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - const std::expected e(0); - const CRefQual l{}; - std::same_as> decltype(auto) val = e.transform(l); - assert(val == 1); - } - } - - // Test && overload - { - // Without & qualifier on F's operator() - { - std::expected e(0); - std::same_as> decltype(auto) val = std::move(e).transform(RVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - std::expected e(0); - std::same_as> decltype(auto) val = std::move(e).transform(RVRefQual{}); - assert(val == 1); - } - } - - // Test const&& overload - { - // Without & qualifier on F's operator() - { - const std::expected e(0); - std::same_as> decltype(auto) val = std::move(e).transform(CRVal{}); - assert(val == 1); - } - - // With & qualifier on F's operator() - { - const std::expected e(0); - const RVCRefQual l{}; - std::same_as> decltype(auto) val = e.transform(std::move(l)); - assert(val == 1); - } - } -} -// clang-format on - -constexpr void test_take_val_return_void() { - std::expected e(1); - int val = 0; - e.transform([&val](T&&) -> void { - static_assert(std::is_same_v); - assert(val == 0); - val = 1; - }); - assert(val == 1); - std::move(e).transform([&val](T&&) -> void { - static_assert(std::is_same_v); - assert(val == 1); - val = 2; - }); - - const auto& ce = e; - assert(val == 2); - ce.transform([&val](T&&) -> void { - static_assert(std::is_same_v); - assert(val == 2); - val = 3; - }); - assert(val == 3); - std::move(ce).transform([&val](T&&) -> void { - static_assert(std::is_same_v); - assert(val == 3); - val = 4; - }); - assert(val == 4); -} - -// check val member is direct-non-list-initialized with invoke(std::forward(f), value()) -constexpr void test_direct_non_list_init() { - auto xform = [](int i) { return NonCopy(i); }; - std::expected e(2); - std::expected 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 e(std::unexpected(2)); - auto l = [](auto&& x) { return x.non_const(); }; - e.transform(l); - std::move(e).transform(l); - - std::expected e1(std::unexpected(1)); - const auto& ce1 = e1; - const auto never_called = [](int) { - assert(false); - return std::expected(); - }; - - 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 edcc56abc2f7d..0000000000000 --- 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. - -// - -// template constexpr auto transform_error(F&& f) &; -// template constexpr auto transform_error(F&& f) const &; -// template constexpr auto transform_error(F&& f) &&; -// template constexpr auto transform_error(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -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 -concept has_transform_error = - requires(E&& e, F&& f) { - { std::forward(e).transform_error(std::forward(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, int>&, int()>); -static_assert(!has_transform_error, int>&&, int()>); - -// clang-format off -constexpr void test_val_types() { - // Test & overload - { - // Without & qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = e.transform_error(LVal{}); - assert(val.error() == 1); - } - - // With & qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - RefQual l{}; - std::same_as> decltype(auto) val = e.transform_error(l); - assert(val.error() == 1); - } - } - - // Test const& overload - { - // Without const& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = e.transform_error(CLVal{}); - assert(val.error() == 1); - } - - // With const& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - const CRefQual l{}; - std::same_as> decltype(auto) val = e.transform_error(l); - assert(val.error() == 1); - } - } - - // Test && overload - { - // Without && qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> decltype(auto) val = std::move(e).transform_error(RVal{}); - assert(val.error() == 1); - } - - // With && qualifier on F's operator() - { - std::expected e(std::unexpected(0)); - std::same_as> 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 e(std::unexpected(0)); - std::same_as> decltype(auto) val = std::move(e).transform_error(CRVal{}); - assert(val.error() == 1); - } - - // With const&& qualifier on F's operator() - { - const std::expected e(std::unexpected(0)); - const RVCRefQual l{}; - std::same_as> 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), error()) -constexpr void test_direct_non_list_init() { - auto xform = [](int i) { return NonCopy(i); }; - std::expected e(std::unexpected(2)); - std::expected 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 e(2); - auto l = [](auto&& x) { return x.non_const(); }; - e.transform_error(l); - std::move(e).transform_error(l); - - std::expected 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 f698f44ba8f3a..0000000000000 --- 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 constexpr E error_or(G&& e) const &; -// template constexpr E error_or(G&& e) &&; - -#include -#include -#include -#include -#include - -struct ConstructFromInt { - int value; - constexpr ConstructFromInt(int v) : value(v) {} -}; - -constexpr bool test_default_template_arg() { - // const &, has_value() - { - const std::expected e(5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x.value == 10); - } - - // const &, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x.value == 5); - } - - // &&, has_value() - { - const std::expected e(5); - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 10); - } - - // &&, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 5); - } - - return true; -} - -constexpr bool test() { - // const &, has_value() - { - const std::expected e(5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x == 10); - } - - // const &, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x == 5); - } - - // &&, has_value() - { - std::expected e(5); - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x == 10); - } - - // &&, !has_value() - { - std::expected e(std::unexpect, 5); - std::same_as 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 f60002c67ebc0..0000000000000 --- 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 - -// - -// template constexpr auto and_then(F&& f) &; -// template constexpr auto and_then(F&& f) const &; -// template constexpr auto and_then(F&& f) &&; -// template constexpr auto and_then(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -struct NonCopyable { - constexpr NonCopyable(int) {} - NonCopyable(const NonCopyable&) = delete; -}; - -struct NonMovable { - constexpr NonMovable(int) {} - NonMovable(NonMovable&&) = delete; -}; - -template -concept has_and_then = - requires(E&& e, F&& f) { - { std::forward(e).and_then(std::forward(f)) }; - }; - -std::expected return_int() { return {}; } -std::expected return_noncopyable() { return {}; } -std::expected return_nonmovable() { return {}; } - -static_assert(has_and_then&, decltype(return_int)>); -static_assert(!has_and_then&, decltype(return_noncopyable)>); -static_assert(has_and_then&, decltype(return_int)>); -static_assert(!has_and_then&, decltype(return_noncopyable)>); -static_assert(has_and_then&&, decltype(return_int)>); -static_assert(!has_and_then&&, decltype(return_nonmovable)>); -static_assert(has_and_then&&, decltype(return_int)>); -static_assert(!has_and_then&&, 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>&, int()>); -static_assert(!has_and_then>&&, int()>); - -constexpr void test_val_types() { - // Test & overload - { - auto l = [] -> std::expected { return 2; }; - std::expected v; - std::same_as> decltype(auto) val = v.and_then(l); - assert(val == 2); - } - - // Test const& overload - { - auto l = [] -> std::expected { return 2; }; - const std::expected v; - assert(v.and_then(l).value() == 2); - static_assert(std::is_same_v< decltype(v.and_then(l)), std::expected>); - } - - // Test && overload - { - auto l = [] -> std::expected { return 2; }; - std::expected v; - std::same_as> decltype(auto) val = std::move(v).and_then(l); - assert(val == 2); - } - - // Test const&& overload - { - auto l = [] -> std::expected { return 2; }; - const std::expected v; - std::same_as> decltype(auto) val = std::move(v).and_then(l); - assert(val == 2); - } -} - -constexpr void test_fail() { - // Test & overload - { - auto f = [] -> std::expected { - assert(false); - return 0; - }; - std::expected v(std::unexpected(2)); - std::same_as> decltype(auto) val = v.and_then(f); - assert(val.error() == 2); - } - - // Test const& overload - { - auto f = [] -> std::expected { - assert(false); - return 0; - }; - const std::expected v(std::unexpected(2)); - std::same_as> decltype(auto) val = v.and_then(f); - assert(val.error() == 2); - } - - // Test && overload - { - auto f = [] -> std::expected { - assert(false); - return 0; - }; - std::expected v(std::unexpected(2)); - std::same_as> decltype(auto) val = std::move(v).and_then(f); - assert(val.error() == 2); - } - - // Test const&& overload - { - auto f = [] -> std::expected { - assert(false); - return 0; - }; - const std::expected v(std::unexpected(2)); - std::same_as> 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 13e341c6d20c1..0000000000000 --- 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 - -// - -// template constexpr auto or_else(F&& f) &; -// template constexpr auto or_else(F&& f) const &; -// template constexpr auto or_else(F&& f) &&; -// template constexpr auto or_else(F&& f) const &&; - -#include -#include -#include -#include -#include - -constexpr void test_val_types() { - // Test & overload - { - auto l = [](auto) -> std::expected { return {}; }; - std::expected v(std::unexpected(1)); - std::same_as> decltype(auto) val = v.or_else(l); - assert(val.has_value()); - } - - // Test const& overload - { - auto l = [](auto) -> std::expected { return {}; }; - const std::expected v(std::unexpected(1)); - std::same_as> decltype(auto) val = v.or_else(l); - assert(val.has_value()); - } - - // Test && overload - { - auto l = [](auto) -> std::expected { return {}; }; - std::expected v(std::unexpected(1)); - std::same_as> decltype(auto) val = std::move(v).or_else(l); - assert(val.has_value()); - } - - // Test const&& overload - { - auto l = [](auto) -> std::expected { return {}; }; - const std::expected v(std::unexpected(1)); - std::same_as> decltype(auto) val = std::move(v).or_else(l); - assert(val.has_value()); - } -} - -constexpr void test_fail() { - auto never_called = [](auto) -> std::expected { - assert(false); - return std::expected(std::unexpected(5)); - }; - - // Test & overload - { - std::expected v; - std::same_as> decltype(auto) val = v.or_else(never_called); - assert(val.has_value()); - } - - // Test const& overload - { - const std::expected v; - std::same_as> decltype(auto) val = v.or_else(never_called); - assert(val.has_value()); - } - - // Test && overload - { - std::expected v; - std::same_as> decltype(auto) val = std::move(v).or_else(never_called); - assert(val.has_value()); - } - - // Test const&& overload - { - const std::expected v; - std::same_as> 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 ea90006e3199e..0000000000000 --- 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 - -// - -// template constexpr auto transform_error(F&& f) &; -// template constexpr auto transform_error(F&& f) const &; -// template constexpr auto transform_error(F&& f) &&; -// template constexpr auto transform_error(F&& f) const &&; - -#include -#include -#include -#include -#include -#include - -template -concept has_transform = - requires(E&& e, F&& f) { - { std::forward(e).transform(std::forward(f)) }; - }; - -// [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. -static_assert(!has_transform>&, int()>); -static_assert(!has_transform>&&, int()>); - -constexpr void test_val_types() { - // Test & overload - { - auto l = [] -> int { return 1; }; - std::expected v; - std::same_as> decltype(auto) val = v.transform(l); - assert(val == 1); - } - - // Test const& overload - { - auto l = [] -> int { return 1; }; - const std::expected v; - std::same_as> decltype(auto) val = v.transform(l); - assert(val == 1); - } - - // Test && overload - { - auto l = [] -> int { return 1; }; - std::expected v; - std::same_as> decltype(auto) val = std::move(v).transform(l); - assert(val == 1); - } - - // Test const&& overload - { - auto l = [] -> int { return 1; }; - const std::expected v; - std::same_as> 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 v(std::unexpected(5)); - std::same_as> decltype(auto) val = v.transform(l); - assert(val.error() == 5); - } - - // Test const& overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - const std::expected v(std::unexpected(5)); - std::same_as> decltype(auto) val = v.transform(l); - assert(val.error() == 5); - } - - // Test && overload - { - auto l = [] -> int { - assert(false); - return 0; - }; - std::expected v(std::unexpected(5)); - std::same_as> 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 v(std::unexpected(5)); - std::same_as> 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 f0e19ac3c3982..0000000000000 --- 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. - -// - -// template constexpr auto transform_error(F&& f) &; -// template constexpr auto transform_error(F&& f) const &; -// template constexpr auto transform_error(F&& f) &&; -// template constexpr auto transform_error(F&& f) const &&; - -#include -#include -#include -#include -#include - -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 v(std::unexpected(2)); - std::same_as> decltype(auto) val = v.transform_error(l); - assert(val.error() == 1); - } - - // Test const& overload - { - auto l = [](auto) -> int { return 1; }; - const std::expected v(std::unexpected(2)); - std::same_as> decltype(auto) val = v.transform_error(l); - assert(val.error() == 1); - } - - // Test && overload - { - auto l = [](auto) -> int { return 1; }; - std::expected v(std::unexpected(2)); - std::same_as> 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 v(std::unexpected(2)); - std::same_as> 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 v; - std::same_as> 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 v; - std::same_as> decltype(auto) val = v.transform_error(l); - assert(val.has_value()); - } - - // Test && overload - { - auto l = [](auto) -> int { - assert(false); - return 0; - }; - std::expected v; - std::same_as> 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 v; - std::same_as> 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)) -constexpr void test_direct_non_list_init() { - auto x = [](int i) { return NonCopy(i); }; - std::expected v(std::unexpected(2)); - std::expected 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 db2891f61c3cb..0000000000000 --- 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 constexpr E error_or(G&& e) const &; -// template constexpr E error_or(G&& e) &&; - -#include -#include -#include -#include -#include - -struct ConstructFromInt { - int value; - constexpr ConstructFromInt(int v) : value(v) {} -}; - -constexpr bool test_default_template_arg() { - // const &, has_value() - { - const std::expected e; - std::same_as decltype(auto) x = e.error_or(10); - assert(x.value == 10); - } - - // const &, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x.value == 5); - } - - // &&, has_value() - { - const std::expected e; - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 10); - } - - // &&, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x.value == 5); - } - - return true; -} - -constexpr bool test() { - // const &, has_value() - { - const std::expected e; - std::same_as decltype(auto) x = e.error_or(10); - assert(x == 10); - } - - // const &, !has_value() - { - const std::expected e(std::unexpect, 5); - std::same_as decltype(auto) x = e.error_or(10); - assert(x == 5); - } - - // &&, has_value() - { - std::expected e; - std::same_as decltype(auto) x = std::move(e).error_or(10); - assert(x == 10); - } - - // &&, !has_value() - { - std::expected e(std::unexpect, 5); - std::same_as 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 c23ebd5b7a035..5ace82348dcb7 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -306,7 +306,7 @@ def add_version_header(tc): "unimplemented": True, }, { "name": "__cpp_lib_expected", - "values": { "c++2b": 202211 }, + "values": { "c++2b": 202202 }, "headers": ["expected"], }, { "name": "__cpp_lib_filesystem",