From b1cf54f12e83b7aee4aef512fb3700ba4a059f93 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Fri, 26 May 2023 07:45:08 -0700 Subject: [PATCH] [libc++][PSTL] Add a test to make sure that customization points work properly Reviewed By: #libc, ldionne Spies: ldionne, libcxx-commits Differential Revision: https://reviews.llvm.org/D151257 --- libcxx/include/__algorithm/pstl_backend.h | 12 +- ...ainst_customization_points_not_working.pass.cpp | 174 +++++++++++++++++++++ 2 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 libcxx/test/libcxx/algorithms/pstl.robust_against_customization_points_not_working.pass.cpp diff --git a/libcxx/include/__algorithm/pstl_backend.h b/libcxx/include/__algorithm/pstl_backend.h index e80bae8..f574773 100644 --- a/libcxx/include/__algorithm/pstl_backend.h +++ b/libcxx/include/__algorithm/pstl_backend.h @@ -49,7 +49,7 @@ algorithms, otherwise they are implemented in terms of other algorithms. If none implemented, all the algorithms will eventually forward to the basis algorithms listed above: template - void __pstl_for_each_n(_Backend, _ExecutionPolicy&&, _Iterator __first, _Size __n, _Func __f); + void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f); template bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); @@ -61,10 +61,16 @@ implemented, all the algorithms will eventually forward to the basis algorithms bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); template - void __pstl_fill(_Iterator __first, _Iterator __last, const _Tp& __value); + _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); + + template + _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); + + template + void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); template - void __pstl_fill_n(_Iterator __first, _SizeT __n, const _Tp& __value); + void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value); // TODO: Complete this list diff --git a/libcxx/test/libcxx/algorithms/pstl.robust_against_customization_points_not_working.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.robust_against_customization_points_not_working.pass.cpp new file mode 100644 index 0000000..9f27df6 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/pstl.robust_against_customization_points_not_working.pass.cpp @@ -0,0 +1,174 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: libcpp-has-no-incomplete-pstl + +// Having a customization point outside the module doesn't work, so this test is inherintly module-hostile. +// UNSUPPORTED: modules-build + +// Make sure that the customization points get called properly when overloaded + +#include <__config> +#include + +struct TestPolicy {}; +struct TestBackend {}; + +_LIBCPP_BEGIN_NAMESPACE_STD + +bool pstl_any_of_called = false; + +template +bool __pstl_any_of(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_any_of_called); + pstl_any_of_called = true; + return true; +} + +bool pstl_all_of_called = false; + +template +bool __pstl_all_of(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_all_of_called); + pstl_all_of_called = true; + return true; +} + +bool pstl_none_of_called = false; + +template +bool __pstl_none_of(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_none_of_called); + pstl_none_of_called = true; + return true; +} + +bool pstl_find_called = false; + +template +ForwardIterator __pstl_find(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_find_called); + pstl_find_called = true; + return {}; +} + +bool pstl_find_if_called = false; + +template +ForwardIterator __pstl_find_if(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_find_if_called); + pstl_find_if_called = true; + return {}; +} + +bool pstl_find_if_not_called = false; + +template +ForwardIterator __pstl_find_if_not(TestBackend, ForwardIterator, ForwardIterator, Pred) { + assert(!pstl_find_if_not_called); + pstl_find_if_not_called = true; + return {}; +} + +bool pstl_for_each_called = false; + +template +void __pstl_for_each(TestBackend, ForwardIterator, Size, Func) { + assert(!pstl_for_each_called); + pstl_for_each_called = true; +} + +bool pstl_for_each_n_called = false; + +template +void __pstl_for_each_n(TestBackend, ForwardIterator, Size, Func) { + assert(!pstl_for_each_n_called); + pstl_for_each_n_called = true; +} + +bool pstl_fill_called = false; + +template +void __pstl_fill(TestBackend, ForwardIterator, Size, Func) { + assert(!pstl_fill_called); + pstl_fill_called = true; +} + +bool pstl_fill_n_called = false; + +template +void __pstl_fill_n(TestBackend, ForwardIterator, Size, Func) { + assert(!pstl_fill_n_called); + pstl_fill_n_called = true; +} + +bool pstl_unary_transform_called = false; + +template +ForwardOutIterator __pstl_transform(TestBackend, ForwardIterator, ForwardIterator, ForwardOutIterator, UnaryOperation) { + assert(!pstl_unary_transform_called); + pstl_unary_transform_called = true; + return {}; +} + +bool pstl_binary_transform_called = false; + +template +ForwardOutIterator __pstl_transform( + TestBackend, ForwardIterator1, ForwardIterator1, ForwardIterator2, ForwardOutIterator, BinaryOperation) { + assert(!pstl_binary_transform_called); + pstl_binary_transform_called = true; + return {}; +} + +_LIBCPP_END_NAMESPACE_STD + +#include +#include +#include + +template <> +inline constexpr bool std::is_execution_policy_v = true; + +template <> +struct std::__select_backend { + using type = TestBackend; +}; + +int main(int, char**) { + int a[] = {1, 2}; + auto pred = [](auto&&...) { return true; }; + + (void)std::any_of(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_any_of_called); + (void)std::all_of(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_all_of_called); + (void)std::none_of(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_none_of_called); + (void)std::fill(TestPolicy{}, std::begin(a), std::end(a), 0); + assert(std::pstl_fill_called); + (void)std::fill_n(TestPolicy{}, std::begin(a), std::size(a), 0); + assert(std::pstl_fill_n_called); + (void)std::find(TestPolicy{}, std::begin(a), std::end(a), 0); + assert(std::pstl_find_called); + (void)std::find_if(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_find_if_called); + (void)std::find_if_not(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_find_if_not_called); + (void)std::for_each(TestPolicy{}, std::begin(a), std::end(a), pred); + assert(std::pstl_for_each_called); + (void)std::for_each_n(TestPolicy{}, std::begin(a), std::size(a), pred); + assert(std::pstl_for_each_n_called); + (void)std::transform(TestPolicy{}, std::begin(a), std::end(a), std::begin(a), pred); + assert(std::pstl_unary_transform_called); + (void)std::transform(TestPolicy{}, std::begin(a), std::end(a), std::begin(a), std::begin(a), pred); + assert(std::pstl_unary_transform_called); + + return 0; +} -- 2.7.4