diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp @@ -24,6 +24,7 @@ #include "almost_satisfies_types.h" #include "test_iterators.h" +#include "type_algorithms.h" template > concept HasCopyIt = requires(In in, Sent sent, Out out) { std::ranges::copy(in, sent, out); }; @@ -101,36 +102,23 @@ test_iterators>(); } -template -constexpr void test_in_iterators() { - test_iterators, Out, sentinel_wrapper>>(); - test_sentinels, Out>(); - test_sentinels, Out>(); - test_sentinels, Out>(); - test_sentinels, Out>(); -} - -template -constexpr void test_proxy_in_iterators() { - test_iterators>, Out, sentinel_wrapper>>>(); - test_iterators>, Out>(); - test_iterators>, Out>(); - test_iterators>, Out>(); - test_iterators>, Out>(); -} - constexpr bool test() { - test_in_iterators>(); - test_in_iterators>(); - test_in_iterators>(); - test_in_iterators>(); - test_in_iterators>(); - - test_proxy_in_iterators>>(); - test_proxy_in_iterators>>(); - test_proxy_in_iterators>>(); - test_proxy_in_iterators>>(); - test_proxy_in_iterators>>(); + meta::apply_all( + meta::concatenate_t< + meta::cartesian_product_t, meta::cpp20_input_iterator_list>, + meta::cartesian_product_t, + meta::proxy_cpp20_input_iterator_list>>{}, + []() { test_sentinels(); }); + + meta::apply_all(meta::cpp20_input_iterator_list{}, [] { + test_iterators, Out, sentinel_wrapper>>(); + }); + + meta::apply_all(meta::proxy_cpp20_input_iterator_list{}, [] { + test_iterators>, + Out, + sentinel_wrapper>>>(); + }); { // check that ranges::dangling is returned std::array out; diff --git a/libcxx/test/std/language.support/support.limits/limits/is_specialized.pass.cpp b/libcxx/test/std/language.support/support.limits/limits/is_specialized.pass.cpp --- a/libcxx/test/std/language.support/support.limits/limits/is_specialized.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/limits/is_specialized.pass.cpp @@ -26,11 +26,11 @@ #include #include -#include "test_macros.h" +#include "type_algorithms.h" -template -void test() -{ +struct Test { + template + void operator()() { static_assert(std::numeric_limits::is_specialized, "std::numeric_limits::is_specialized"); static_assert(std::numeric_limits::is_specialized, @@ -39,37 +39,15 @@ "std::numeric_limits::is_specialized"); static_assert(std::numeric_limits::is_specialized, "std::numeric_limits::is_specialized"); -} + } +}; int main(int, char**) { - test(); - test(); - test(); -#if TEST_STD_VER > 17 && defined(__cpp_char8_t) - test(); -#endif - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef TEST_HAS_NO_INT128 - test<__int128_t>(); - test<__uint128_t>(); -#endif - test(); - test(); - test(); - static_assert(!std::numeric_limits >::is_specialized, - "!std::numeric_limits >::is_specialized"); + meta::apply_all(meta::arithmetic_types(), Test()); + + static_assert(!std::numeric_limits >::is_specialized, + "!std::numeric_limits >::is_specialized"); return 0; } diff --git a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp --- a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp @@ -17,7 +17,9 @@ #include "min_allocator.h" +#include "make_string.h" #include "test_macros.h" +#include "type_algorithms.h" template TEST_CONSTEXPR_CXX20 void @@ -57,17 +59,24 @@ template TEST_CONSTEXPR_CXX20 void test_string() { test(S(), 0); - test(S("123"), 0); - test(S("123"), 1); - test(S("123"), 2); - test(S("123"), 3); + test(S(MAKE_CSTRING(typename S::value_type, "123")), 0); + test(S(MAKE_CSTRING(typename S::value_type, "123")), 1); + test(S(MAKE_CSTRING(typename S::value_type, "123")), 2); + test(S(MAKE_CSTRING(typename S::value_type, "123")), 3); } -TEST_CONSTEXPR_CXX20 bool test() { - test_string(); +struct TestCaller { + template + TEST_CONSTEXPR_CXX20 void operator()() { + test_string>(); #if TEST_STD_VER >= 11 - test_string, min_allocator>>(); + test_string, min_allocator>>(); #endif + } +}; + +TEST_CONSTEXPR_CXX20 bool test() { + meta::apply_all(meta::character_types{}, TestCaller{}); return true; } diff --git a/libcxx/test/support/test.support/type_algorithms.pass.cpp b/libcxx/test/support/test.support/type_algorithms.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/support/test.support/type_algorithms.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "type_algorithms.h" + +// concatenate +static_assert(std::is_same_v, meta::type_list>); +static_assert(std::is_same_v, meta::type_list>); +static_assert(std::is_same_v>, meta::type_list<>>); +static_assert(std::is_same_v>, meta::type_list>); +static_assert(std::is_same_v, long>, meta::type_list>); +static_assert( + std::is_same_v, meta::type_list>, meta::type_list>); +static_assert(std::is_same_v, meta::type_list, long long>, + meta::type_list>); +static_assert( + std::is_same_v, meta::type_list, meta::type_list>, + meta::type_list>); + +// wrap_list +template +struct Wrapper {}; + +template +using Wrap = Wrapper; + +static_assert( + std::is_same_v>, meta::type_list< Wrapper, Wrapper>>); + +// cartesian_product +static_assert(std::is_same_v, meta::type_list>, + meta::type_list>>); +static_assert(std::is_same_v, meta::type_list>, + meta::type_list, meta::type_list>>); +static_assert( + std::is_same_v, meta::type_list, Wrapper>>, + meta::type_list>, + meta::type_list>, + meta::type_list>, + meta::type_list>>>); + +// apply +constexpr void test_apply() { + meta::apply(meta::type_list{}, [] { + static_assert(std::is_same_v && std::is_same_v); + }); +} + +// apply_all +template +class NumT {}; + +struct ApplyAllTest { + int* last_call; + + template + constexpr void check_num(NumT) { + assert(++*last_call == N); + } + + template + constexpr void check_num(NumT, NumT) { + assert(++*last_call == N + M); + } + + template + constexpr void operator()() { + check_num(Types{}...); + } +}; + +constexpr void test_apply_all() { + { + int last_call = -1; + meta::apply_all(meta::type_list, NumT<1>, NumT<2>>{}, ApplyAllTest{&last_call}); + assert(last_call == 2); + } + + { + int last_call = -1; + meta::apply_all(meta::cartesian_product_t< meta::type_list, NumT<1>, NumT<2>>, + meta::type_list, NumT<3>, NumT<6>>>{}, + ApplyAllTest{&last_call}); + assert(last_call == 8); + } +} + +constexpr bool test() { + test_apply(); + test_apply_all(); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -18,6 +18,7 @@ #include #include "test_macros.h" +#include "type_algorithms.h" // This iterator meets C++20's Cpp17OutputIterator requirements, as described @@ -1297,6 +1298,34 @@ requires std::ranges::viewable_range ProxyRange(R&&) -> ProxyRange>; +namespace meta { +template +using random_access_iterator_list = type_list, random_access_iterator>; + +template +using proxy_random_access_iterator_list = wrap_list_t>; + +template +using bidirectional_iterator_list = concatenate_t, bidirectional_iterator>; + +template +using proxy_bidirectional_iterator_list = wrap_list_t>; + +template +using forward_iterator_list = concatenate_t, forward_iterator>; + +template +using proxy_forward_iterator_list = wrap_list_t>; + +template +using cpp20_input_iterator_list = + concatenate_t, type_list, cpp17_input_iterator>>; + +template +using proxy_cpp20_input_iterator_list = wrap_list_t>; + +} // namespace meta + #endif // TEST_STD_VER > 17 #endif // SUPPORT_TEST_ITERATORS_H diff --git a/libcxx/test/support/type_algorithms.h b/libcxx/test/support/type_algorithms.h new file mode 100644 --- /dev/null +++ b/libcxx/test/support/type_algorithms.h @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// 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 TEST_SUPPORT_TYPE_ALGORITHMS_H +#define TEST_SUPPORT_TYPE_ALGORITHMS_H + +#include + +#include "test_macros.h" + +namespace meta { +template +struct type_list {}; + +// concatenates +// - T -> type_list +// - T, U -> type_list +// - type_list -> type_list +// - type_list, T -> type_list +// - N type_lists to one +template +struct concatenate; + +template +using concatenate_t = typename concatenate::type; + +// wrap_list wraps a template type (or alias) around every type of a type_list +// i.e. Wrapper, type_list -> type_list, Wrapper> +template