From 6cf03e7ba074fb6eb2f7ee556ac0e130bddcc52c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 31 Jul 2025 17:26:24 +0800 Subject: [PATCH 1/8] [libc++] Implement the `` parts of P1317R2 Changes of `std::apply` are still blocked on related changes in P2165R4. --- libcxx/docs/ReleaseNotes/22.rst | 2 + libcxx/docs/Status/Cxx2cPapers.csv | 2 +- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__type_traits/is_applicable.h | 115 +++ libcxx/include/module.modulemap.in | 4 + libcxx/include/type_traits | 16 + libcxx/modules/std/type_traits.inc | 18 + .../type_traits/no_specializations.verify.cpp | 9 +- ...ed_from_integral_constant.compile.pass.cpp | 2 + .../meta.rel/is_applicable.compile.pass.cpp | 598 ++++++++++++++++ .../is_nothrow_applicable.compile.pass.cpp | 652 ++++++++++++++++++ .../apply_result.compile.pass.cpp | 629 +++++++++++++++++ 12 files changed, 2046 insertions(+), 2 deletions(-) create mode 100644 libcxx/include/__type_traits/is_applicable.h create mode 100644 libcxx/test/std/utilities/meta/meta.rel/is_applicable.compile.pass.cpp create mode 100644 libcxx/test/std/utilities/meta/meta.rel/is_nothrow_applicable.compile.pass.cpp create mode 100644 libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/apply_result.compile.pass.cpp diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 15bf46d44b07f..05c375359a688 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -38,6 +38,8 @@ What's New in Libc++ 22.0.0? Implemented Papers ------------------ +- P1317R2: Remove return type deduction in ``std::apply`` (`Github `__) + (Only components in ```` are implemented.) - P2321R2: ``zip`` (`Github `__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release) Improvements and New Features diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index febb0c176f9c4..99be92021434e 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -155,5 +155,5 @@ "`P2781R9 `__","``std::constant_wrapper``","2025-06 (Sofia)","","","" "`P3697R1 `__","Minor additions to C++26 standard library hardening","2025-06 (Sofia)","","","" "`P3552R3 `__","Add a Coroutine Task Type","2025-06 (Sofia)","","","" -"`P1317R2 `__","Remove return type deduction in ``std::apply``","2025-06 (Sofia)","","","" +"`P1317R2 `__","Remove return type deduction in ``std::apply``","2025-06 (Sofia)","|In Progress|","","" "","","","","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 51444ec668e2b..a823a2f3a7a50 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -819,6 +819,7 @@ set(files __type_traits/is_aggregate.h __type_traits/is_allocator.h __type_traits/is_always_bitcastable.h + __type_traits/is_applicable.h __type_traits/is_arithmetic.h __type_traits/is_array.h __type_traits/is_assignable.h diff --git a/libcxx/include/__type_traits/is_applicable.h b/libcxx/include/__type_traits/is_applicable.h new file mode 100644 index 0000000000000..00db70ac072b2 --- /dev/null +++ b/libcxx/include/__type_traits/is_applicable.h @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_APPLICABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_APPLICABLE_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__fwd/get.h> +#include <__tuple/tuple_like.h> +#include <__tuple/tuple_size.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/invoke.h> +#include <__type_traits/remove_reference.h> +#include <__utility/declval.h> +#include <__utility/integer_sequence.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 26 + +template +struct __apply_result_disabled_base {}; + +template +struct __apply_result_enabled_base { + using type _LIBCPP_NODEBUG = _Tp; +}; + +template +struct __applicability_traits { + static constexpr bool __applicable = true; + static constexpr bool __nothrow_applicable = _Nothrow; + + template + using __base_type _LIBCPP_NODEBUG = __apply_result_enabled_base<_Fn, _Tuple, _Tp>; +}; + +template +struct __applicability_traits { + static_assert(!_Nothrow, "misspecified [_Applicable = false, _Nothrow = true]"); + static constexpr bool __applicable = false; + static constexpr bool __nothrow_applicable = false; + + template + using __base_type _LIBCPP_NODEBUG = __apply_result_disabled_base<_Fn, _Tuple>; +}; + +template +concept __tuple_applicable_impl = requires(_Tuple&& __tuple) { + [](auto&&...) {}(std::get<_Is>(static_cast<_Tuple &&>(__tuple))...); +} && __is_invocable_v<_Fn, decltype(std::get<_Is>(std::declval<_Tuple>()))...>; + +template +concept __tuple_nothrow_applicable_impl = requires(_Tuple&& __tuple) { + { + [](auto&&...) noexcept {}(std::get<_Is>(static_cast<_Tuple &&>(__tuple))...) + } noexcept; +} && __is_nothrow_invocable_v<_Fn, decltype(std::get<_Is>(std::declval<_Tuple>()))...>; + +template +consteval auto __applicability_traits_of() { + if constexpr (__tuple_like<_Tuple>) + return [](index_sequence<_Is...>) { + if constexpr (__tuple_applicable_impl<_Fn, _Tuple, _Is...>) { + return __applicability_traits< + true, + __tuple_nothrow_applicable_impl<_Fn, _Tuple, _Is...>, + // FIXME: Use __invoke_result_y after merging https://github.com/llvm/llvm-project/pull/151028. + typename __invoke_result<_Fn, decltype(std::get<_Is>(std::declval<_Tuple>()))...>::type>{}; + } else + return __applicability_traits{}; + }(make_index_sequence>>{}); + else + return __applicability_traits{}; +} + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_applicable + : bool_constant())::__applicable> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_applicable + : bool_constant())::__nothrow_applicable> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_applicable_v = + decltype(std::__applicability_traits_of<_Fn, _Tuple>())::__applicable; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_applicable_v = + decltype(std::__applicability_traits_of<_Fn, _Tuple>())::__nothrow_applicable; + +template +struct _LIBCPP_NO_SPECIALIZATIONS apply_result + : decltype(std::__applicability_traits_of<_Fn, _Tuple>())::template __base_type<_Fn, _Tuple> {}; + +template +using apply_result_t = apply_result<_Fn, _Tuple>::type; + +#endif // _LIBCPP_STD_VER >= 26 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_APPLICABLE_H diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 5857a83b5fe14..6766960144a83 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -112,6 +112,10 @@ module std_core [system] { header "__type_traits/is_always_bitcastable.h" export std_core.type_traits.integral_constant } + module is_applicable { + header "__type_traits/is_applicable.h" + export std_core.type_traits.integral_constant + } module is_arithmetic { header "__type_traits/is_arithmetic.h" export std_core.type_traits.integral_constant diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index a6e0c1867566b..f8c3f744e07f4 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -168,6 +168,10 @@ namespace std template struct is_nothrow_invocable_r; // since C++17 + template struct is_applicable; // since C++26 + template + struct is_nothrow_applicable; // since C++26 + // Alignment properties and transformations: template struct alignment_of; template @@ -183,6 +187,7 @@ namespace std struct result_of; // deprecated in C++17; removed in C++20 template struct invoke_result; // since C++17 + template struct apply_result; // since C++26 // const-volatile modifications: template @@ -265,6 +270,9 @@ namespace std template using invoke_result_t = typename invoke_result::type; // since C++17 + template + using apply_result_t + = typename invoke_result::type; // since C++26 template using void_t = void; // since C++17 @@ -442,6 +450,10 @@ namespace std = is_nothrow_invocable::value; // since C++17 template inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r::value; // since C++17 + template constexpr bool is_applicable_v + = is_applicable::value; // since C++26 + template constexpr bool is_nothrow_applicable_v + = is_nothrow_applicable::value; // since C++26 // [meta.logical], logical operator traits: template struct conjunction; // since C++17 @@ -559,6 +571,10 @@ namespace std # include <__type_traits/reference_converts_from_temporary.h> # endif +# if _LIBCPP_STD_VER >= 26 +# include <__type_traits/is_applicable.h> +# endif + # include # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc index 6823c86ed153b..0ad2bb4bea27f 100644 --- a/libcxx/modules/std/type_traits.inc +++ b/libcxx/modules/std/type_traits.inc @@ -121,6 +121,9 @@ export namespace std { using std::rank; // [meta.rel], type relations +#if _LIBCPP_STD_VER >= 26 + using std::is_applicable; +#endif using std::is_base_of; #if _LIBCPP_STD_VER >= 26 && __has_builtin(__builtin_is_virtual_base_of) using std::is_virtual_base_of; @@ -134,6 +137,9 @@ export namespace std { using std::is_invocable; using std::is_invocable_r; +#if _LIBCPP_STD_VER >= 26 + using std::is_nothrow_applicable; +#endif using std::is_nothrow_invocable; using std::is_nothrow_invocable_r; @@ -183,6 +189,9 @@ export namespace std { using std::remove_pointer_t; // [meta.trans.other], other transformations +#if _LIBCPP_STD_VER >= 26 + using std::apply_result; +#endif using std::basic_common_reference; using std::common_reference; using std::common_type; @@ -196,6 +205,9 @@ export namespace std { using std::unwrap_ref_decay; using std::unwrap_reference; +#if _LIBCPP_STD_VER >= 26 + using std::apply_result_t; +#endif using std::common_reference_t; using std::common_type_t; using std::conditional_t; @@ -305,6 +317,9 @@ export namespace std { using std::rank_v; // [meta.rel], type relations +#if _LIBCPP_STD_VER >= 26 + using std::is_applicable_v; +#endif using std::is_base_of_v; #if _LIBCPP_STD_VER >= 26 && __has_builtin(__builtin_is_virtual_base_of) using std::is_virtual_base_of_v; @@ -313,6 +328,9 @@ export namespace std { using std::is_invocable_r_v; using std::is_invocable_v; // using std::is_layout_compatible_v; +#if _LIBCPP_STD_VER >= 26 + using std::is_nothrow_applicable_v; +#endif using std::is_nothrow_convertible_v; using std::is_nothrow_invocable_r_v; using std::is_nothrow_invocable_v; diff --git a/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp b/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp index 897ae89365014..b76a75a3b1584 100644 --- a/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp +++ b/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp @@ -53,6 +53,11 @@ SPECIALIZE_TRAIT(unwrap_reference); // expected-error {{cannot be specialized}} SPECIALIZE_TRAIT(unwrap_ref_decay); // expected-error {{cannot be specialized}} # endif +# if TEST_STD_VER >= 26 +template <> +struct std::apply_result; // expected-error {{cannot be specialized}} +# endif + # undef SPECIALIZE_TRAIT # define SPECIALIZE_UTT(Trait) \ template <> \ @@ -165,7 +170,9 @@ SPECIALIZE_BTT(reference_converts_from_temporary); // expected-error 2 {{cannot # endif # if TEST_STD_VER >= 26 -SPECIALIZE_BTT(is_virtual_base_of); // expected-error 2 {{cannot be specialized}} +SPECIALIZE_BTT(is_applicable); // expected-error 2 {{cannot be specialized}} +SPECIALIZE_BTT(is_nothrow_applicable); // expected-error 2 {{cannot be specialized}} +SPECIALIZE_BTT(is_virtual_base_of); // expected-error 2 {{cannot be specialized}} # endif # undef SPECIALIZE_UTT diff --git a/libcxx/test/std/utilities/meta/derived_from_integral_constant.compile.pass.cpp b/libcxx/test/std/utilities/meta/derived_from_integral_constant.compile.pass.cpp index 3db7a214b27bd..eb021f5840c6c 100644 --- a/libcxx/test/std/utilities/meta/derived_from_integral_constant.compile.pass.cpp +++ b/libcxx/test/std/utilities/meta/derived_from_integral_constant.compile.pass.cpp @@ -113,4 +113,6 @@ static_assert(std::is_base_of>::value, # if defined(__cpp_lib_is_virtual_base_of) && __cpp_lib_is_virtual_base_of >= 202406L static_assert(std::is_base_of>::value, ""); # endif +static_assert(std::is_base_of>::value, ""); +static_assert(std::is_base_of>::value, ""); #endif diff --git a/libcxx/test/std/utilities/meta/meta.rel/is_applicable.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.rel/is_applicable.compile.pass.cpp new file mode 100644 index 0000000000000..7f70f19044d0f --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.rel/is_applicable.compile.pass.cpp @@ -0,0 +1,598 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// + +// template struct is_applicable; + +// template +// constexpr bool is_applicable_v = is_applicable::value; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "callable_types.h" +#include "test_iterators.h" + +struct empty_aggregate {}; + +struct derived_from_tuple_int : std::tuple {}; + +template <> +struct std::tuple_size : std::integral_constant {}; + +template + requires(I < 1) +struct std::tuple_element { + using type = std::tuple_element_t>; +}; + +template +void test_is_applicable() { + static_assert(std::is_applicable::value == Expected); + static_assert(std::is_applicable_v == Expected); + + static_assert(std::is_base_of_v, std::is_applicable>); + static_assert(std::is_convertible_v*, std::bool_constant*>); +} + +template +void test_is_applicable_from_function() { + static_assert(std::is_function_v); + + test_is_applicable(); + test_is_applicable(); + + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); +} + +void test_valid() { + // test array + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function, 0>&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function, 0>&, true>(); + + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::array, true>(); + test_is_applicable, std::array&, true>(); + test_is_applicable, const std::array, true>(); + test_is_applicable, const std::array&, true>(); + + test_is_applicable, std::array, true>(); + test_is_applicable, std::array&, true>(); + test_is_applicable, const std::array, true>(); + test_is_applicable, const std::array&, true>(); + + // test complex + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, + true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + test_is_applicable, std::complex, true>(); + test_is_applicable, std::complex&, true>(); + test_is_applicable, const std::complex, true>(); + test_is_applicable, const std::complex&, true>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, copyable_subrange, true>(); + test_is_applicable, copyable_subrange&, true>(); + test_is_applicable, const copyable_subrange, true>(); + test_is_applicable, const copyable_subrange&, true>(); + + test_is_applicable, copyable_subrange, true>(); + test_is_applicable, copyable_subrange&, true>(); + test_is_applicable, const copyable_subrange, true>(); + test_is_applicable, const copyable_subrange&, true>(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, move_only_subrange, true >(); + + test_is_applicable, move_only_subrange, true>(); + + // test tuple + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::tuple<>, true>(); + test_is_applicable, std::tuple&, true>(); + test_is_applicable, const std::tuple, true>(); + test_is_applicable, const std::tuple&, true>(); + + test_is_applicable, std::tuple<>, true>(); + test_is_applicable, std::tuple&, true>(); + test_is_applicable, const std::tuple, true>(); + test_is_applicable, const std::tuple&, true>(); + + // test pair + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + test_is_applicable_from_function, true>(); + test_is_applicable_from_function&, true>(); + + test_is_applicable, std::pair, true>(); + test_is_applicable, std::pair&, true>(); + test_is_applicable, const std::pair, true>(); + test_is_applicable, const std::pair&, true>(); + + test_is_applicable, std::pair, true>(); + test_is_applicable, std::pair&, true>(); + test_is_applicable, const std::pair, true>(); + test_is_applicable, const std::pair&, true>(); +} + +void test_volatile() { + // test array + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + test_is_applicable, volatile std::array, false>(); + test_is_applicable, volatile std::array&, false>(); + test_is_applicable, const volatile std::array, false>(); + test_is_applicable, const volatile std::array&, false>(); + + // test complex + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + test_is_applicable, volatile std::complex, false>(); + test_is_applicable, volatile std::complex&, false>(); + test_is_applicable, const volatile std::complex, false>(); + test_is_applicable, const volatile std::complex&, false>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, volatile copyable_subrange, false>(); + test_is_applicable, volatile copyable_subrange&, false>(); + test_is_applicable, const volatile copyable_subrange, false>(); + test_is_applicable, const volatile copyable_subrange&, false>(); + + // test tuple + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, + false>(); + test_is_applicable_from_function, + false>(); + test_is_applicable_from_function&, + false>(); + + test_is_applicable, volatile std::tuple, false>(); + test_is_applicable, volatile std::tuple&, false>(); + test_is_applicable, const volatile std::tuple, false>(); + test_is_applicable, const volatile std::tuple&, false>(); + + // test pair + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + test_is_applicable, volatile std::pair, false>(); + test_is_applicable, volatile std::pair&, false>(); + test_is_applicable, const volatile std::pair, false>(); + test_is_applicable, const volatile std::pair&, false>(); +} + +void test_invalid_nontuple_types() { + // test void + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, void, false>(); + test_is_applicable, const void, false>(); + test_is_applicable, volatile void, false>(); + test_is_applicable, const volatile void, false>(); + + // test function + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, void(), false>(); + test_is_applicable, void (&)(), false>(); + test_is_applicable, void() const & noexcept, false>(); + + // test scalar + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, int, false>(); + test_is_applicable, int&, false>(); + test_is_applicable, const int, false>(); + test_is_applicable, const int&, false>(); + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, void*, false>(); + test_is_applicable, void*&, false>(); + test_is_applicable, void* const, false>(); + test_is_applicable, void* const&, false>(); + + // test plain aggregate + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, empty_aggregate, false>(); + test_is_applicable, empty_aggregate&, false>(); + test_is_applicable, const empty_aggregate, false>(); + test_is_applicable, const empty_aggregate&, false>(); + + // test std::get-able class + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, derived_from_tuple_int, false>(); + test_is_applicable, derived_from_tuple_int&, false>(); + test_is_applicable, const derived_from_tuple_int, false>(); + test_is_applicable, const derived_from_tuple_int&, false>(); + + // test built-in array + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable, int[1], false>(); + test_is_applicable, int (&)[1], false>(); + test_is_applicable, const int[1], false>(); + test_is_applicable, const int (&)[1], false>(); +} + +void test_invalid_invocations() { + // test array + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + // test complex + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + test_is_applicable(); + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + test_is_applicable_from_function(); + + // test tuple + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + + // test pair + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable, false>(); + test_is_applicable, false>(); + + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); + test_is_applicable_from_function, false>(); + test_is_applicable_from_function&, false>(); +} diff --git a/libcxx/test/std/utilities/meta/meta.rel/is_nothrow_applicable.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.rel/is_nothrow_applicable.compile.pass.cpp new file mode 100644 index 0000000000000..de8c8a44c3396 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.rel/is_nothrow_applicable.compile.pass.cpp @@ -0,0 +1,652 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// + +// template struct is_nothrow_applicable; + +// template +// constexpr bool is_nothrow_applicable_v = is_nothrow_applicable::value; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "callable_types.h" +#include "test_iterators.h" + +struct empty_aggregate {}; + +struct derived_from_tuple_int : std::tuple {}; + +template <> +struct std::tuple_size : std::integral_constant {}; + +template + requires(I < 1) +struct std::tuple_element { + using type = std::tuple_element_t>; +}; + +template +void test_is_nothrow_applicable() { + static_assert(std::is_nothrow_applicable::value == Expected); + static_assert(std::is_nothrow_applicable_v == Expected); + + static_assert(std::is_base_of_v, std::is_nothrow_applicable>); + static_assert(std::is_convertible_v*, std::bool_constant*>); +} + +template +void test_is_nothrow_applicable_from_function() { + static_assert(std::is_function_v); + + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); +} + +void test_valid() { + // test array + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function, 0>&, true>(); + + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable, std::array, true>(); + test_is_nothrow_applicable, std::array&, true>(); + test_is_nothrow_applicable, const std::array, true>(); + test_is_nothrow_applicable, const std::array&, true>(); + + // test complex + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable, std::complex, true>(); + test_is_nothrow_applicable, std::complex&, true>(); + test_is_nothrow_applicable, const std::complex, true>(); + test_is_nothrow_applicable, const std::complex&, true>(); + + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable, std::complex, true>(); + test_is_nothrow_applicable, std::complex&, true>(); + test_is_nothrow_applicable, const std::complex, true>(); + test_is_nothrow_applicable, const std::complex&, true>(); + + test_is_nothrow_applicable_from_function, + true>(); + test_is_nothrow_applicable_from_function&, + true>(); + test_is_nothrow_applicable_from_function, + true>(); + test_is_nothrow_applicable_from_function&, + true>(); + + test_is_nothrow_applicable, std::complex, true>(); + test_is_nothrow_applicable, std::complex&, true>(); + test_is_nothrow_applicable, const std::complex, true>(); + test_is_nothrow_applicable, const std::complex&, true>(); + + // test subrange + // Exception specifications may be different among implementations, see [res.on.exception.handling]/5. + using copyable_subrange = std::ranges::subrange; + constexpr bool can_nothrow_get_copyable_subrange_lv = + noexcept((void)std::get<0>(std::declval()), + (void)std::get<1>(std::declval())); + constexpr bool can_nothrow_get_copyable_subrange_rv = noexcept( + (void)std::get<0>(std::declval()), (void)std::get<1>(std::declval())); + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, copyable_subrange, can_nothrow_get_copyable_subrange_rv>(); + test_is_nothrow_applicable, copyable_subrange&, can_nothrow_get_copyable_subrange_lv>(); + test_is_nothrow_applicable, const copyable_subrange, can_nothrow_get_copyable_subrange_lv>(); + test_is_nothrow_applicable, const copyable_subrange&, can_nothrow_get_copyable_subrange_lv>(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + constexpr bool can_nothrow_get_move_only_subrange_rv = noexcept( + (void)std::get<0>(std::declval()), (void)std::get<1>(std::declval())); + + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, move_only_subrange, can_nothrow_get_move_only_subrange_rv>(); + + // test tuple + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable, std::tuple<>, true>(); + test_is_nothrow_applicable, std::tuple&, true>(); + test_is_nothrow_applicable, const std::tuple, true>(); + test_is_nothrow_applicable, const std::tuple&, true>(); + + // test pair + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + test_is_nothrow_applicable_from_function, true>(); + test_is_nothrow_applicable_from_function&, true>(); + + test_is_nothrow_applicable, std::pair, true>(); + test_is_nothrow_applicable, std::pair&, true>(); + test_is_nothrow_applicable, const std::pair, true>(); + test_is_nothrow_applicable, const std::pair&, true>(); +} + +void test_potentially_throwing() { + // test array + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function, 0>&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::array, false>(); + test_is_nothrow_applicable, std::array&, false>(); + test_is_nothrow_applicable, const std::array, false>(); + test_is_nothrow_applicable, const std::array&, false>(); + + // test complex + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::complex, false>(); + test_is_nothrow_applicable, std::complex&, false>(); + test_is_nothrow_applicable, const std::complex, false>(); + test_is_nothrow_applicable, const std::complex&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::complex, false>(); + test_is_nothrow_applicable, std::complex&, false>(); + test_is_nothrow_applicable, const std::complex, false>(); + test_is_nothrow_applicable, const std::complex&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, + false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::complex, false>(); + test_is_nothrow_applicable, std::complex&, false>(); + test_is_nothrow_applicable, const std::complex, false>(); + test_is_nothrow_applicable, const std::complex&, false>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, copyable_subrange, false>(); + test_is_nothrow_applicable, copyable_subrange&, false>(); + test_is_nothrow_applicable, const copyable_subrange, false>(); + test_is_nothrow_applicable, const copyable_subrange&, false>(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, move_only_subrange, false>(); + + // test tuple + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::tuple<>, false>(); + test_is_nothrow_applicable, std::tuple&, false>(); + test_is_nothrow_applicable, const std::tuple, false>(); + test_is_nothrow_applicable, const std::tuple&, false>(); + + // test pair + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, std::pair, false>(); + test_is_nothrow_applicable, std::pair&, false>(); + test_is_nothrow_applicable, const std::pair, false>(); + test_is_nothrow_applicable, const std::pair&, false>(); +} + +void test_volatile() { + // test array + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, volatile std::array, false>(); + test_is_nothrow_applicable, volatile std::array&, false>(); + test_is_nothrow_applicable, const volatile std::array, false>(); + test_is_nothrow_applicable, const volatile std::array&, false>(); + + // test complex + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, + false>(); + + test_is_nothrow_applicable, volatile std::complex, false>(); + test_is_nothrow_applicable, volatile std::complex&, false>(); + test_is_nothrow_applicable, const volatile std::complex, false>(); + test_is_nothrow_applicable, const volatile std::complex&, false>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, volatile copyable_subrange, false>(); + test_is_nothrow_applicable, volatile copyable_subrange&, false>(); + test_is_nothrow_applicable, const volatile copyable_subrange, false>(); + test_is_nothrow_applicable, const volatile copyable_subrange&, false>(); + + // test tuple + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, + false>(); + test_is_nothrow_applicable_from_function&, + false>(); + test_is_nothrow_applicable_from_function, + false>(); + test_is_nothrow_applicable_from_function&, + false>(); + test_is_nothrow_applicable_from_function, + false>(); + test_is_nothrow_applicable_from_function&, + false>(); + + test_is_nothrow_applicable, volatile std::tuple, false>(); + test_is_nothrow_applicable, volatile std::tuple&, false>(); + test_is_nothrow_applicable, const volatile std::tuple, false>(); + test_is_nothrow_applicable, const volatile std::tuple&, false>(); + + // test pair + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable, volatile std::pair, false>(); + test_is_nothrow_applicable, volatile std::pair&, false>(); + test_is_nothrow_applicable, const volatile std::pair, false>(); + test_is_nothrow_applicable, const volatile std::pair&, false>(); +} + +void test_invalid_nontuple_types() { + // test void + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, void, false>(); + test_is_nothrow_applicable, const void, false>(); + test_is_nothrow_applicable, volatile void, false>(); + test_is_nothrow_applicable, const volatile void, false>(); + + // test function + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, void(), false>(); + test_is_nothrow_applicable, void (&)(), false>(); + test_is_nothrow_applicable, void() const & noexcept, false>(); + + // test scalar + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, int, false>(); + test_is_nothrow_applicable, int&, false>(); + test_is_nothrow_applicable, const int, false>(); + test_is_nothrow_applicable, const int&, false>(); + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, void*, false>(); + test_is_nothrow_applicable, void*&, false>(); + test_is_nothrow_applicable, void* const, false>(); + test_is_nothrow_applicable, void* const&, false>(); + + // test plain aggregate + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, empty_aggregate, false>(); + test_is_nothrow_applicable, empty_aggregate&, false>(); + test_is_nothrow_applicable, const empty_aggregate, false>(); + test_is_nothrow_applicable, const empty_aggregate&, false>(); + + // test std::get-able class + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, derived_from_tuple_int, false>(); + test_is_nothrow_applicable, derived_from_tuple_int&, false>(); + test_is_nothrow_applicable, const derived_from_tuple_int, false>(); + test_is_nothrow_applicable, const derived_from_tuple_int&, false>(); + + // test built-in array + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable, int[1], false>(); + test_is_nothrow_applicable, int (&)[1], false>(); + test_is_nothrow_applicable, const int[1], false>(); + test_is_nothrow_applicable, const int (&)[1], false>(); +} + +void test_invalid_invocations() { + // test array + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + // test complex + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + test_is_nothrow_applicable(); + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + test_is_nothrow_applicable_from_function(); + + // test tuple + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + + // test pair + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable, false>(); + test_is_nothrow_applicable, false>(); + + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); + test_is_nothrow_applicable_from_function, false>(); + test_is_nothrow_applicable_from_function&, false>(); +} diff --git a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/apply_result.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/apply_result.compile.pass.cpp new file mode 100644 index 0000000000000..21ec35aba8a0a --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/apply_result.compile.pass.cpp @@ -0,0 +1,629 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// + +// template struct apply_result; + +// template +// using apply_result_t = typename apply_result::type; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "callable_types.h" +#include "test_iterators.h" + +struct empty_aggregate {}; + +struct derived_from_tuple_int : std::tuple {}; + +template <> +struct std::tuple_size : std::integral_constant {}; + +template + requires(I < 1) +struct std::tuple_element { + using type = std::tuple_element_t>; +}; + +template +concept apply_result_has_member_type = requires { typename std::apply_result::type; }; + +template +concept apply_result_t_is_valid = requires { typename std::apply_result_t; }; + +template +void test_valid_apply_result() { + static_assert(apply_result_has_member_type); + static_assert(apply_result_t_is_valid); + static_assert(std::is_same_v::type, Expected>); + static_assert(std::is_same_v, Expected>); +} + +template +void test_valid_apply_result_from_function() { + static_assert(std::is_function_v); + + test_valid_apply_result(); + test_valid_apply_result(); + + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); + test_valid_apply_result(); +} + +template +void test_invalid_apply_result() { + static_assert(!apply_result_has_member_type); + static_assert(!apply_result_t_is_valid); +} + +template +void test_invalid_apply_result_from_function() { + static_assert(std::is_function_v); + + test_invalid_apply_result(); + test_invalid_apply_result(); + + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); +} + +void test_valid() { + // test array + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function, 0>&, int>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function, 0>&, int>(); + + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + + test_valid_apply_result, std::array, bool>(); + test_valid_apply_result, std::array&, signed char>(); + test_valid_apply_result, const std::array, short>(); + test_valid_apply_result, const std::array&, int>(); + + test_valid_apply_result, std::array, bool>(); + test_valid_apply_result, std::array&, unsigned char>(); + test_valid_apply_result, const std::array, unsigned short>(); + test_valid_apply_result, const std::array&, unsigned int>(); + + // test complex + test_valid_apply_result_from_function, float>(); + test_valid_apply_result_from_function&, float>(); + test_valid_apply_result_from_function, void>(); + test_valid_apply_result_from_function&, double>(); + test_valid_apply_result_from_function, float>(); + test_valid_apply_result_from_function&, float>(); + test_valid_apply_result_from_function, void>(); + test_valid_apply_result_from_function&, double>(); + + test_valid_apply_result, std::complex, bool>(); + test_valid_apply_result, std::complex&, signed char>(); + test_valid_apply_result, const std::complex, int>(); + test_valid_apply_result, const std::complex&, short>(); + + test_valid_apply_result, std::complex, unsigned long>(); + test_valid_apply_result, std::complex&, bool>(); + test_valid_apply_result, const std::complex, unsigned int>(); + test_valid_apply_result, const std::complex&, unsigned short>(); + + test_valid_apply_result_from_function, double>(); + test_valid_apply_result_from_function&, double&>(); + test_valid_apply_result_from_function, void>(); + test_valid_apply_result_from_function&, double>(); + test_valid_apply_result_from_function, double>(); + test_valid_apply_result_from_function&, double&>(); + test_valid_apply_result_from_function, void>(); + test_valid_apply_result_from_function&, double>(); + + test_valid_apply_result, std::complex, bool>(); + test_valid_apply_result, std::complex&, signed char>(); + test_valid_apply_result, const std::complex, short>(); + test_valid_apply_result, const std::complex&, int>(); + + test_valid_apply_result, std::complex, unsigned short>(); + test_valid_apply_result, std::complex&, unsigned long>(); + test_valid_apply_result, const std::complex, bool>(); + test_valid_apply_result, const std::complex&, unsigned char>(); + + test_valid_apply_result_from_function, + long double>(); + test_valid_apply_result_from_function&, + long double&>(); + test_valid_apply_result_from_function, void>(); + test_valid_apply_result_from_function&, double>(); + test_valid_apply_result_from_function, + long double>(); + test_valid_apply_result_from_function&, + long double&>(); + test_valid_apply_result_from_function, + void>(); + test_valid_apply_result_from_function&, + double>(); + + test_valid_apply_result, std::complex, bool>(); + test_valid_apply_result, std::complex&, signed char>(); + test_valid_apply_result, const std::complex, short>(); + test_valid_apply_result, const std::complex&, int>(); + + test_valid_apply_result, std::complex, bool>(); + test_valid_apply_result, std::complex&, unsigned char>(); + test_valid_apply_result, const std::complex, unsigned short>(); + test_valid_apply_result, const std::complex&, unsigned int>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + + test_valid_apply_result, copyable_subrange, bool>(); + test_valid_apply_result, copyable_subrange&, unsigned char>(); + test_valid_apply_result, const copyable_subrange, short>(); + test_valid_apply_result, const copyable_subrange&, unsigned long>(); + + test_valid_apply_result, copyable_subrange, signed char>(); + test_valid_apply_result, copyable_subrange&, unsigned int>(); + test_valid_apply_result, const copyable_subrange, long long>(); + test_valid_apply_result, const copyable_subrange&, unsigned short>(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + + test_valid_apply_result_from_function(); + test_valid_apply_result_from_function(); + + test_valid_apply_result, move_only_subrange, long long>(); + + test_valid_apply_result, move_only_subrange, unsigned long long>(); + + // test tuple + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, char&>(); + test_valid_apply_result_from_function, long&&>(); + test_valid_apply_result_from_function&, void>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, char&>(); + test_valid_apply_result_from_function, long&&>(); + test_valid_apply_result_from_function&, void>(); + + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + + test_valid_apply_result, std::tuple<>, unsigned long long>(); + test_valid_apply_result, std::tuple&, unsigned long>(); + test_valid_apply_result, const std::tuple, unsigned int>(); + test_valid_apply_result, const std::tuple&, unsigned short>(); + + test_valid_apply_result, std::tuple<>, long long>(); + test_valid_apply_result, std::tuple&, long>(); + test_valid_apply_result, const std::tuple, int>(); + test_valid_apply_result, const std::tuple&, short>(); + + // test pair + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + test_valid_apply_result_from_function, int>(); + test_valid_apply_result_from_function&, int&>(); + test_valid_apply_result_from_function, const int&&>(); + test_valid_apply_result_from_function&, void>(); + + test_valid_apply_result, std::pair, bool>(); + test_valid_apply_result, std::pair&, unsigned char>(); + test_valid_apply_result, const std::pair, unsigned int>(); + test_valid_apply_result, const std::pair&, unsigned short>(); + + test_valid_apply_result, std::pair, int>(); + test_valid_apply_result, std::pair&, short>(); + test_valid_apply_result, const std::pair, long>(); + test_valid_apply_result, const std::pair&, long long>(); +} + +void test_volatile() { + // test array + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result, volatile std::array>(); + test_invalid_apply_result, volatile std::array&>(); + test_invalid_apply_result, const volatile std::array>(); + test_invalid_apply_result, const volatile std::array&>(); + + // test complex + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result, volatile std::complex>(); + test_invalid_apply_result, volatile std::complex&>(); + test_invalid_apply_result, const volatile std::complex>(); + test_invalid_apply_result, const volatile std::complex&>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, volatile copyable_subrange>(); + test_invalid_apply_result, volatile copyable_subrange&>(); + test_invalid_apply_result, const volatile copyable_subrange>(); + test_invalid_apply_result, const volatile copyable_subrange&>(); + + // test tuple + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result, volatile std::tuple>(); + test_invalid_apply_result, volatile std::tuple&>(); + test_invalid_apply_result, const volatile std::tuple>(); + test_invalid_apply_result, const volatile std::tuple&>(); + + // test pair + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result, volatile std::pair>(); + test_invalid_apply_result, volatile std::pair&>(); + test_invalid_apply_result, const volatile std::pair>(); + test_invalid_apply_result, const volatile std::pair&>(); +} + +void test_invalid_nontuple_types() { + // test void + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, void>(); + test_invalid_apply_result, const void>(); + test_invalid_apply_result, volatile void>(); + test_invalid_apply_result, const volatile void>(); + + // test function + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, void()>(); + test_invalid_apply_result, void (&)()>(); + test_invalid_apply_result, void() const & noexcept>(); + + // test scalar + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, int>(); + test_invalid_apply_result, int&>(); + test_invalid_apply_result, const int>(); + test_invalid_apply_result, const int&>(); + + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, void*>(); + test_invalid_apply_result, void*&>(); + test_invalid_apply_result, void* const>(); + test_invalid_apply_result, void* const&>(); + + // test plain aggregate + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, empty_aggregate>(); + test_invalid_apply_result, empty_aggregate&>(); + test_invalid_apply_result, const empty_aggregate>(); + test_invalid_apply_result, const empty_aggregate&>(); + + // test std::get-able class + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, derived_from_tuple_int>(); + test_invalid_apply_result, derived_from_tuple_int&>(); + test_invalid_apply_result, const derived_from_tuple_int>(); + test_invalid_apply_result, const derived_from_tuple_int&>(); + + // test built-in array + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result, int[1]>(); + test_invalid_apply_result, int (&)[1]>(); + test_invalid_apply_result, const int[1]>(); + test_invalid_apply_result, const int (&)[1]>(); +} + +void test_invalid_invocations() { + // test array + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + // test complex + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + // test subrange + using copyable_subrange = std::ranges::subrange; + + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + using move_only_counted_iter = std::counted_iterator>; + using move_only_subrange = std::ranges::subrange; + + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + test_invalid_apply_result(); + + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + test_invalid_apply_result_from_function(); + + // test tuple + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + + // test pair + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result>(); + test_invalid_apply_result>(); + + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); + test_invalid_apply_result_from_function>(); + test_invalid_apply_result_from_function&>(); +} From a700737384e80debf94f113862e40ddbdda8f223 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Aug 2025 19:23:39 +0800 Subject: [PATCH 2/8] Address review comments (except for tests) --- libcxx/docs/ReleaseNotes/22.rst | 2 -- libcxx/include/{__type_traits => __tuple}/is_applicable.h | 0 libcxx/include/module.modulemap.in | 8 ++++---- libcxx/include/type_traits | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) rename libcxx/include/{__type_traits => __tuple}/is_applicable.h (100%) diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 05c375359a688..15bf46d44b07f 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -38,8 +38,6 @@ What's New in Libc++ 22.0.0? Implemented Papers ------------------ -- P1317R2: Remove return type deduction in ``std::apply`` (`Github `__) - (Only components in ```` are implemented.) - P2321R2: ``zip`` (`Github `__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release) Improvements and New Features diff --git a/libcxx/include/__type_traits/is_applicable.h b/libcxx/include/__tuple/is_applicable.h similarity index 100% rename from libcxx/include/__type_traits/is_applicable.h rename to libcxx/include/__tuple/is_applicable.h diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 6766960144a83..4ffbb35c8ede4 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -112,10 +112,6 @@ module std_core [system] { header "__type_traits/is_always_bitcastable.h" export std_core.type_traits.integral_constant } - module is_applicable { - header "__type_traits/is_applicable.h" - export std_core.type_traits.integral_constant - } module is_arithmetic { header "__type_traits/is_arithmetic.h" export std_core.type_traits.integral_constant @@ -2115,6 +2111,10 @@ module std [system] { module tuple { module find_index { header "__tuple/find_index.h" } module ignore { header "__tuple/ignore.h" } + module is_applicable { + header "__tuple/is_applicable.h" + export std_core.type_traits.integral_constant + } module make_tuple_types { header "__tuple/make_tuple_types.h" } module sfinae_helpers { header "__tuple/sfinae_helpers.h" } module tuple_element { header "__tuple/tuple_element.h" } diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index f8c3f744e07f4..9484be752af69 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -572,7 +572,7 @@ namespace std # endif # if _LIBCPP_STD_VER >= 26 -# include <__type_traits/is_applicable.h> +# include <__tuple/is_applicable.h> # endif # include From 12604b69dbade178eb31eebcb7b26c0d81e958d5 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Aug 2025 21:54:51 +0800 Subject: [PATCH 3/8] Fix CMakeLists.txt --- libcxx/include/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index a823a2f3a7a50..7955d94fbc63d 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -780,6 +780,7 @@ set(files __tree __tuple/find_index.h __tuple/ignore.h + __tuple/is_applicable.h __tuple/make_tuple_types.h __tuple/sfinae_helpers.h __tuple/tuple_element.h @@ -819,7 +820,6 @@ set(files __type_traits/is_aggregate.h __type_traits/is_allocator.h __type_traits/is_always_bitcastable.h - __type_traits/is_applicable.h __type_traits/is_arithmetic.h __type_traits/is_array.h __type_traits/is_assignable.h From b51bcad31a7cc175bdf97de02ae4583b6a1bd22b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 6 Aug 2025 10:57:52 +0800 Subject: [PATCH 4/8] Attempt to expand `std_core` ... as `` might be included as a whole by `` --- libcxx/include/CMakeLists.txt | 2 +- .../is_applicable.h | 0 libcxx/include/module.modulemap.in | 144 ++++++++++-------- libcxx/include/type_traits | 2 +- 4 files changed, 80 insertions(+), 68 deletions(-) rename libcxx/include/{__tuple => __type_traits}/is_applicable.h (100%) diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 7955d94fbc63d..a823a2f3a7a50 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -780,7 +780,6 @@ set(files __tree __tuple/find_index.h __tuple/ignore.h - __tuple/is_applicable.h __tuple/make_tuple_types.h __tuple/sfinae_helpers.h __tuple/tuple_element.h @@ -820,6 +819,7 @@ set(files __type_traits/is_aggregate.h __type_traits/is_allocator.h __type_traits/is_always_bitcastable.h + __type_traits/is_applicable.h __type_traits/is_arithmetic.h __type_traits/is_array.h __type_traits/is_assignable.h diff --git a/libcxx/include/__tuple/is_applicable.h b/libcxx/include/__type_traits/is_applicable.h similarity index 100% rename from libcxx/include/__tuple/is_applicable.h rename to libcxx/include/__type_traits/is_applicable.h diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 4ffbb35c8ede4..f929b3687ddab 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -12,6 +12,30 @@ module std_config [system] { } module std_core [system] { + // TODO: Investigate whether we should bring the whole here. + module concepts_core { + module arithmetic { header "__concepts/arithmetic.h" } + module assignable { header "__concepts/assignable.h" } + module boolean_testable { header "__concepts/boolean_testable.h" } + module class_or_enum { header "__concepts/class_or_enum.h" } + module common_reference_with { header "__concepts/common_reference_with.h" } + module constructible { header "__concepts/constructible.h" } + module convertible_to { header "__concepts/convertible_to.h" } + module copyable { header "__concepts/copyable.h" } + module derived_from { header "__concepts/derived_from.h" } + module destructible { header "__concepts/destructible.h" } + module equality_comparable { header "__concepts/equality_comparable.h" } + module invocable { header "__concepts/invocable.h" } + module movable { header "__concepts/movable.h" } + module predicate { header "__concepts/predicate.h" } + module regular { header "__concepts/regular.h" } + module relation { header "__concepts/relation.h" } + module same_as { header "__concepts/same_as.h" } + module semiregular { header "__concepts/semiregular.h" } + module swappable { header "__concepts/swappable.h" } + module totally_ordered { header "__concepts/totally_ordered.h" } + } + module cstddef { module byte { header "__cstddef/byte.h" } module max_align_t { @@ -28,11 +52,41 @@ module std_core [system] { export * } + module get_fwd { + header "__fwd/get.h" + export std_core.fwd.pair + export std_core.fwd.tuple + export std_core.fwd.array + export std_core.fwd.complex + export std_core.fwd.subrange + export std_core.fwd.variant + } + module fwd { + module array { header "__fwd/array.h" } + module complex { header "__fwd/complex.h" } module byte { header "__fwd/byte.h" } module functional { header "__fwd/functional.h" } module pair { header "__fwd/pair.h" } + module subrange { header "__fwd/subrange.h" } module tuple { header "__fwd/tuple.h" } + module variant { header "__fwd/variant.h" } + } + + // Only the truly dependency-free parts of __iterator are here + module iterator_core { + module concepts { + header "__iterator/concepts.h" + export std_core.type_traits.common_reference + } + module incrementable_traits { header "__iterator/incrementable_traits.h" } + module iter_move { header "__iterator/iter_move.h" } + module iterator_traits { + header "__iterator/iterator_traits.h" + export std_core.type_traits.integral_constant + export std_core.type_traits.is_convertible + } + module readable_traits { header "__iterator/readable_traits.h" } } module limits { @@ -63,6 +117,21 @@ module std_core [system] { module trigonometric_functions { header "__math/trigonometric_functions.h" } } + // Only the truly dependency-free parts of __memory are here + module memory_core { + module addressof { header "__memory/addressof.h" } + module pointer_traits { header "__memory/pointer_traits.h" } + } + + // Only the truly dependency-free parts of __tuple are here + module tuple_core { + module tuple_element { header "__tuple/tuple_element.h" } + module tuple_like { header "__tuple/tuple_like.h" } + module tuple_like_no_subrange { header "__tuple/tuple_like_no_subrange.h" } + module tuple_size { header "__tuple/tuple_size.h" } + module tuple_types { header "__tuple/tuple_types.h" } + } + module type_traits { module add_cv_quals { header "__type_traits/add_cv_quals.h" } module add_pointer { header "__type_traits/add_pointer.h" } @@ -112,6 +181,10 @@ module std_core [system] { header "__type_traits/is_always_bitcastable.h" export std_core.type_traits.integral_constant } + module is_applicable { + header "__type_traits/is_applicable.h" + export std_core.type_traits.integral_constant + } module is_arithmetic { header "__type_traits/is_arithmetic.h" export std_core.type_traits.integral_constant @@ -393,9 +466,10 @@ module std_core [system] { // Only the truly dependency-free parts of __utility are here module utility_core { - module declval { header "__utility/declval.h" } - module empty { header "__utility/empty.h" } - module forward { header "__utility/forward.h" } + module declval { header "__utility/declval.h" } + module empty { header "__utility/empty.h" } + module forward { header "__utility/forward.h" } + module integer_sequence { header "__utility/integer_sequence.h" } } } // module std_core @@ -864,8 +938,6 @@ module std [system] { } module array { - module fwd { header "__fwd/array.h" } - header "array" export * export std.iterator.reverse_iterator @@ -1056,35 +1128,13 @@ module std [system] { } module complex { - module fwd { header "__fwd/complex.h" } - header "complex" export * } module concepts { - module arithmetic { header "__concepts/arithmetic.h" } - module assignable { header "__concepts/assignable.h" } - module boolean_testable { header "__concepts/boolean_testable.h" } - module class_or_enum { header "__concepts/class_or_enum.h" } - module common_reference_with { header "__concepts/common_reference_with.h" } module common_with { header "__concepts/common_with.h" } - module constructible { header "__concepts/constructible.h" } - module convertible_to { header "__concepts/convertible_to.h" } - module copyable { header "__concepts/copyable.h" } - module derived_from { header "__concepts/derived_from.h" } - module destructible { header "__concepts/destructible.h" } module different_from { header "__concepts/different_from.h" } - module equality_comparable { header "__concepts/equality_comparable.h" } - module invocable { header "__concepts/invocable.h" } - module movable { header "__concepts/movable.h" } - module predicate { header "__concepts/predicate.h" } - module regular { header "__concepts/regular.h" } - module relation { header "__concepts/relation.h" } - module same_as { header "__concepts/same_as.h" } - module semiregular { header "__concepts/semiregular.h" } - module swappable { header "__concepts/swappable.h" } - module totally_ordered { header "__concepts/totally_ordered.h" } header "concepts" export * @@ -1494,10 +1544,6 @@ module std [system] { module back_insert_iterator { header "__iterator/back_insert_iterator.h" } module bounded_iter { header "__iterator/bounded_iter.h" } module common_iterator { header "__iterator/common_iterator.h" } - module concepts { - header "__iterator/concepts.h" - export std_core.type_traits.common_reference - } module counted_iterator { header "__iterator/counted_iterator.h" } module cpp17_iterator_concepts { header "__iterator/cpp17_iterator_concepts.h" } module data { header "__iterator/data.h" } @@ -1506,7 +1552,6 @@ module std [system] { module empty { header "__iterator/empty.h" } module erase_if_container { header "__iterator/erase_if_container.h" } module front_insert_iterator { header "__iterator/front_insert_iterator.h" } - module incrementable_traits { header "__iterator/incrementable_traits.h" } module indirectly_comparable { header "__iterator/indirectly_comparable.h" } module insert_iterator { header "__iterator/insert_iterator.h" } module istream_iterator { header "__iterator/istream_iterator.h" } @@ -1514,13 +1559,7 @@ module std [system] { header "__iterator/istreambuf_iterator.h" export std.string.char_traits } - module iter_move { header "__iterator/iter_move.h" } module iter_swap { header "__iterator/iter_swap.h" } - module iterator_traits { - header "__iterator/iterator_traits.h" - export std_core.type_traits.integral_constant - export std_core.type_traits.is_convertible - } module iterator_with_data { header "__iterator/iterator_with_data.h" } module iterator { header "__iterator/iterator.h" } module mergeable { header "__iterator/mergeable.h" } @@ -1537,7 +1576,6 @@ module std [system] { module product_iterator { header "__iterator/product_iterator.h" } module projected { header "__iterator/projected.h" } module ranges_iterator_traits { header "__iterator/ranges_iterator_traits.h" } - module readable_traits { header "__iterator/readable_traits.h" } module reverse_access { header "__iterator/reverse_access.h" } module reverse_iterator { header "__iterator/reverse_iterator.h" } module segmented_iterator { header "__iterator/segmented_iterator.h" } @@ -1631,7 +1669,6 @@ module std [system] { } module memory { - module addressof { header "__memory/addressof.h" } module align { header "__memory/align.h" } module aligned_alloc { header "__memory/aligned_alloc.h" } module allocate_at_least { header "__memory/allocate_at_least.h" } @@ -1656,7 +1693,6 @@ module std [system] { module is_sufficiently_aligned { header "__memory/is_sufficiently_aligned.h" } module noexcept_move_assign_container { header "__memory/noexcept_move_assign_container.h" } module out_ptr { header "__memory/out_ptr.h" } - module pointer_traits { header "__memory/pointer_traits.h" } module ranges_construct_at { header "__memory/ranges_construct_at.h" } module ranges_destroy { header "__memory/ranges_destroy.h" } module ranges_uninitialized_algorithms { @@ -1913,10 +1949,7 @@ module std [system] { } module subrange { header "__ranges/subrange.h" - export std.ranges.subrange_fwd - } - module subrange_fwd { - header "__fwd/subrange.h" + export std_core.fwd.subrange } module take_view { header "__ranges/take_view.h" @@ -2111,18 +2144,9 @@ module std [system] { module tuple { module find_index { header "__tuple/find_index.h" } module ignore { header "__tuple/ignore.h" } - module is_applicable { - header "__tuple/is_applicable.h" - export std_core.type_traits.integral_constant - } module make_tuple_types { header "__tuple/make_tuple_types.h" } module sfinae_helpers { header "__tuple/sfinae_helpers.h" } - module tuple_element { header "__tuple/tuple_element.h" } module tuple_like_ext { header "__tuple/tuple_like_ext.h" } - module tuple_like_no_subrange { header "__tuple/tuple_like_no_subrange.h" } - module tuple_like { header "__tuple/tuple_like.h" } - module tuple_size { header "__tuple/tuple_size.h" } - module tuple_types { header "__tuple/tuple_types.h" } header "tuple" export * @@ -2167,7 +2191,6 @@ module std [system] { header "__utility/in_place.h" export std_core.type_traits.integral_constant } - module integer_sequence { header "__utility/integer_sequence.h" } module is_pointer_in_range { header "__utility/is_pointer_in_range.h" } module is_valid_range { header "__utility/is_valid_range.h" } module move { header "__utility/move.h" } @@ -2193,7 +2216,6 @@ module std [system] { } module variant { - module fwd { header "__fwd/variant.h" } module monostate { header "__variant/monostate.h" } header "variant" @@ -2270,16 +2292,6 @@ module std [system] { module strict_weak_ordering_check { header "__debug_utils/strict_weak_ordering_check.h" } } - module get_fwd { - header "__fwd/get.h" - export std_core.fwd.pair - export std_core.fwd.tuple - export std.array.fwd - export std.complex.fwd - export std.ranges.subrange_fwd - export std.variant.fwd - } - module pstl { module backend_fwd { header "__pstl/backend_fwd.h" diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 9484be752af69..f8c3f744e07f4 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -572,7 +572,7 @@ namespace std # endif # if _LIBCPP_STD_VER >= 26 -# include <__tuple/is_applicable.h> +# include <__type_traits/is_applicable.h> # endif # include From f0603612df38034aafbffe705b08c107361dfd7b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 6 Aug 2025 11:19:13 +0800 Subject: [PATCH 5/8] Fix `utility_core` --- libcxx/include/module.modulemap.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index f929b3687ddab..3b3b513635bd0 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -468,8 +468,10 @@ module std_core [system] { module utility_core { module declval { header "__utility/declval.h" } module empty { header "__utility/empty.h" } + module exchange { header "__utility/exchange.h" } module forward { header "__utility/forward.h" } module integer_sequence { header "__utility/integer_sequence.h" } + module move { header "__utility/move.h" } } } // module std_core @@ -2185,7 +2187,6 @@ module std [system] { module convert_to_integral { header "__utility/convert_to_integral.h" } module element_count { header "__utility/element_count.h" } module exception_guard { header "__utility/exception_guard.h" } - module exchange { header "__utility/exchange.h" } module forward_like { header "__utility/forward_like.h" } module in_place { header "__utility/in_place.h" @@ -2193,7 +2194,6 @@ module std [system] { } module is_pointer_in_range { header "__utility/is_pointer_in_range.h" } module is_valid_range { header "__utility/is_valid_range.h" } - module move { header "__utility/move.h" } module no_destroy { header "__utility/no_destroy.h" } module pair { header "__utility/pair.h" } module piecewise_construct { header "__utility/piecewise_construct.h" } From 9f3c5f60be007b79ed3a7197edb4f6231982c9a6 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 6 Aug 2025 11:28:07 +0800 Subject: [PATCH 6/8] Fix `functional_core` --- libcxx/include/module.modulemap.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 3b3b513635bd0..b6145bde7a39f 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -62,6 +62,11 @@ module std_core [system] { export std_core.fwd.variant } + // Only the truly dependency-free parts of __functional are here + module functional_core { + module invoke { header "__functional/invoke.h" } + } + module fwd { module array { header "__fwd/array.h" } module complex { header "__fwd/complex.h" } @@ -1471,7 +1476,6 @@ module std [system] { module function { header "__functional/function.h" } module hash { header "__functional/hash.h" } module identity { header "__functional/identity.h" } - module invoke { header "__functional/invoke.h" } module is_transparent { header "__functional/is_transparent.h" } module mem_fn { header "__functional/mem_fn.h" } module mem_fun_ref { header "__functional/mem_fun_ref.h" } From 6be0f48177074ef66990a351648e5caa13b6115e Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 6 Aug 2025 11:54:18 +0800 Subject: [PATCH 7/8] Fix `iterator_operations` --- libcxx/include/module.modulemap.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index b6145bde7a39f..1ad5f4e12e747 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -533,9 +533,9 @@ module std [system] { module iter_swap { header "__algorithm/iter_swap.h" } module iterator_operations { header "__algorithm/iterator_operations.h" + export std_core.iterator_core.iter_move export std.iterator.advance export std.iterator.distance - export std.iterator.iter_move export std.iterator.iter_swap export std.iterator.next export std.iterator.prev From c4db93fe38b82c0c520fe83214757834a64b7511 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 12 Aug 2025 09:54:25 +0800 Subject: [PATCH 8/8] Remove temporary workaround for `__invoke_result_t` --- libcxx/include/__type_traits/is_applicable.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libcxx/include/__type_traits/is_applicable.h b/libcxx/include/__type_traits/is_applicable.h index 00db70ac072b2..a916d07ae4021 100644 --- a/libcxx/include/__type_traits/is_applicable.h +++ b/libcxx/include/__type_traits/is_applicable.h @@ -73,11 +73,9 @@ consteval auto __applicability_traits_of() { if constexpr (__tuple_like<_Tuple>) return [](index_sequence<_Is...>) { if constexpr (__tuple_applicable_impl<_Fn, _Tuple, _Is...>) { - return __applicability_traits< - true, - __tuple_nothrow_applicable_impl<_Fn, _Tuple, _Is...>, - // FIXME: Use __invoke_result_y after merging https://github.com/llvm/llvm-project/pull/151028. - typename __invoke_result<_Fn, decltype(std::get<_Is>(std::declval<_Tuple>()))...>::type>{}; + return __applicability_traits, + __invoke_result_t<_Fn, decltype(std::get<_Is>(std::declval<_Tuple>()))...>>{}; } else return __applicability_traits{}; }(make_index_sequence>>{});