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,129 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include "test_macros.h" +#include "type_algorithms.h" + +// concatenate +static_assert(std::is_same, meta::type_list >::value, ""); +static_assert(std::is_same, meta::type_list >::value, ""); +static_assert(std::is_same >, meta::type_list<> >::value, ""); +static_assert(std::is_same >, meta::type_list >::value, ""); +static_assert(std::is_same, long>, meta::type_list >::value, ""); +static_assert( + std::is_same, meta::type_list >, meta::type_list >::value, + ""); +static_assert(std::is_same, meta::type_list, long long>, + meta::type_list >::value, + ""); +static_assert( + std::is_same, meta::type_list, meta::type_list >, + meta::type_list >::value, + ""); + +// wrap_list +template +struct Wrapper {}; + +template +using Wrap = Wrapper; + +static_assert(std::is_same >, + meta::type_list< Wrapper, Wrapper > >::value, + ""); + +// cartesian_product +static_assert(std::is_same, meta::type_list >, + meta::type_list > >::value, + ""); +static_assert(std::is_same, meta::type_list >, + meta::type_list, meta::type_list > >::value, + ""); +static_assert( + std::is_same, meta::type_list, Wrapper > >, + meta::type_list >, + meta::type_list >, + meta::type_list >, + meta::type_list > > >::value, + ""); + +struct CheckApply { + template + TEST_CONSTEXPR_CXX14 void operator()() { + static_assert(std::is_same::value && std::is_same::value, ""); + } +}; + +// apply +TEST_CONSTEXPR_CXX20 void test_apply() { meta::apply(meta::type_list(), CheckApply()); } + +// apply_all +template +class NumT {}; + +struct ApplyAllTest { + bool* is_called_array_; + + TEST_CONSTEXPR ApplyAllTest(bool* is_called_array) : is_called_array_(is_called_array) {} + + template + TEST_CONSTEXPR_CXX20 void check_num(NumT) { + assert(!is_called_array_[N]); + is_called_array_[N] = true; + } + + template + TEST_CONSTEXPR_CXX20 void check_num(NumT, NumT) { + assert(!is_called_array_[N + M]); + is_called_array_[N + M] = true; + } + + template + TEST_CONSTEXPR_CXX20 void operator()() { + check_num(Types()...); + } +}; + +struct Identity { + TEST_CONSTEXPR bool operator()(bool b) const { return b; } +}; + +TEST_CONSTEXPR_CXX20 void test_apply_all() { + { + bool is_called_array[3] = {}; + meta::apply_all(meta::type_list, NumT<1>, NumT<2> >(), ApplyAllTest(is_called_array)); + assert(std::all_of(is_called_array, is_called_array + 3, Identity())); + } + + { + bool is_called_array[9] = {}; + meta::apply_all(meta::cartesian_product_t, NumT<1>, NumT<2> >, + meta::type_list, NumT<3>, NumT<6> > >(), + ApplyAllTest(is_called_array)); + assert(std::all_of(is_called_array, is_called_array + 9, Identity())); + } +} + +TEST_CONSTEXPR_CXX20 bool test() { + test_apply(); + test_apply_all(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 20 + static_assert(test()); +#endif + + 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