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..1ad5f4e12e747 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,46 @@ 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 + } + + // 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" } 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 +122,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 +186,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 +471,12 @@ 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 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 @@ -452,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 @@ -864,8 +945,6 @@ module std [system] { } module array { - module fwd { header "__fwd/array.h" } - header "array" export * export std.iterator.reverse_iterator @@ -1056,35 +1135,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 * @@ -1419,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" } @@ -1494,10 +1550,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 +1558,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 +1565,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 +1582,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 +1675,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 +1699,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 +1955,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" @@ -2113,12 +2152,7 @@ module std [system] { module ignore { header "__tuple/ignore.h" } 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 * @@ -2157,16 +2191,13 @@ 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" 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" } module no_destroy { header "__utility/no_destroy.h" } module pair { header "__utility/pair.h" } module piecewise_construct { header "__utility/piecewise_construct.h" } @@ -2189,7 +2220,6 @@ module std [system] { } module variant { - module fwd { header "__fwd/variant.h" } module monostate { header "__variant/monostate.h" } header "variant" @@ -2266,16 +2296,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 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&>(); +}