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); }; @@ -94,48 +95,28 @@ } } -template -constexpr void test_sentinels() { - test_iterators(); - test_iterators>(); - 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::for_each(meta::forward_iterator_list{}, []() { + test_iterators, Out, sentinel_wrapper>>(); + test_iterators>, + ProxyIterator, + sentinel_wrapper>>>(); + + meta::for_each(meta::forward_iterator_list{}, []() { + test_iterators(); + test_iterators>(); + test_iterators>(); + + test_iterators, ProxyIterator>(); + test_iterators, ProxyIterator, sized_sentinel>>(); + test_iterators, ProxyIterator, sentinel_wrapper>>(); + }); + }); { // check that ranges::dangling is returned std::array out; std::same_as> auto ret = - std::ranges::copy(std::array {1, 2, 3, 4}, out.data()); + std::ranges::copy(std::array{1, 2, 3, 4}, out.data()); assert(ret.out == out.data() + 4); assert((out == std::array{1, 2, 3, 4})); } 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::for_each(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::for_each(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,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 >, meta::type_list >::value, + ""); +static_assert( + std::is_same, meta::type_list, meta::type_list >, + meta::type_list >::value, + ""); + +// 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_for_each() { + bool is_called_array[3] = {}; + meta::for_each(meta::type_list, NumT<1>, NumT<2> >(), ApplyAllTest(is_called_array)); + assert(std::all_of(is_called_array, is_called_array + 3, Identity())); +} + +TEST_CONSTEXPR_CXX20 bool test() { + test_for_each(); + 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,22 @@ requires std::ranges::viewable_range ProxyRange(R&&) -> ProxyRange>; +namespace meta { +template +using random_access_iterator_list = type_list, random_access_iterator>; + +template +using bidirectional_iterator_list = concatenate_t, type_list>>; + +template +using forward_iterator_list = concatenate_t, type_list>>; + +template +using cpp20_input_iterator_list = + concatenate_t, type_list, cpp17_input_iterator>>; + +} // 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,105 @@ +//===----------------------------------------------------------------------===// +// +// 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 N type_lists to one (for N >= 1) +template +struct concatenate; + +template +using concatenate_t = typename concatenate::type; + +// for_each takes a type_list calls f with each element as the first template argument +template +TEST_CONSTEXPR_CXX14 void for_each(type_list, Functor f); + +// impl +template +struct concatenate > { + using type = type_list; +}; + +template +struct concatenate, type_list > { + using type = type_list; +}; + +template +struct concatenate, type_list, Rest...> { + using type = concatenate_t, Rest...>; +}; + +template +TEST_CONSTEXPR_CXX14 void swallow(Types...) {} + +template +TEST_CONSTEXPR_CXX14 void for_each(type_list, Functor f) { + swallow((f.template operator()(), 0)...); +} + +// type categories defined in [basic.fundamental] plus extensions (without CV-qualifiers) + +using character_types = + type_list= 11 + , + char16_t, + char32_t +#endif + >; + +using signed_integer_types = + type_list; + +using unsigned_integer_types = + type_list; + +using integral_types = concatenate_t >; + +using floating_point_types = type_list; + +using arithmetic_types = concatenate_t; +} // namespace meta + +#endif // TEST_SUPPORT_TYPE_ALGORITHMS_H