[libc++][PSTL] Implement std::{any, all, none}_of

Reviewed By: ldionne, #libc

Spies: arichardson, libcxx-commits, miyuki

Differential Revision: https://reviews.llvm.org/D143161
This commit is contained in:
Nikolas Klauser 2023-01-14 02:08:27 +01:00 committed by Nikolas Klauser
parent ebc05b93a1
commit 8af259e8d9
33 changed files with 603 additions and 149 deletions

View File

@ -69,6 +69,7 @@ set(files
__algorithm/partition_point.h
__algorithm/pop_heap.h
__algorithm/prev_permutation.h
__algorithm/pstl_any_all_none_of.h
__algorithm/push_heap.h
__algorithm/ranges_adjacent_find.h
__algorithm/ranges_all_of.h
@ -698,6 +699,7 @@ set(files
__type_traits/is_empty.h
__type_traits/is_enum.h
__type_traits/is_equality_comparable.h
__type_traits/is_execution_policy.h
__type_traits/is_final.h
__type_traits/is_floating_point.h
__type_traits/is_function.h
@ -798,6 +800,7 @@ set(files
__utility/priority_tag.h
__utility/rel_ops.h
__utility/swap.h
__utility/terminate_on_exception.h
__utility/to_underlying.h
__utility/unreachable.h
__variant/monostate.h

View File

@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
for (; __first != __last; ++__first)
if (!__pred(*__first))

View File

@ -0,0 +1,77 @@
//===----------------------------------------------------------------------===//
//
// 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___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/not_fn.h>
#include <__pstl/internal/parallel_impl.h>
#include <__pstl/internal/unseq_backend_simd.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return __pstl::__internal::__parallel_or(
__pstl::__internal::__par_backend_tag{},
__policy,
__first,
__last,
[&__policy, &__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
return std::any_of(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __pred);
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
return __pstl::__unseq_backend::__simd_or(__first, __last - __first, __pred);
} else {
return std::any_of(__first, __last, __pred);
}
}
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
return !std::any_of(__policy, __first, __last, std::not_fn(__pred));
}
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
return !std::any_of(__policy, __first, __last, __pred);
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H

View File

@ -21,29 +21,6 @@ _PSTL_HIDE_FROM_ABI_PUSH
namespace __pstl {
namespace __internal {
//------------------------------------------------------------------------
// any_of
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Pred>
bool __brick_any_of(const _ForwardIterator,
const _ForwardIterator,
_Pred,
/*__is_vector=*/std::false_type) noexcept;
template <class _RandomAccessIterator, class _Pred>
bool __brick_any_of(const _RandomAccessIterator,
const _RandomAccessIterator,
_Pred,
/*__is_vector=*/std::true_type) noexcept;
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Pred>
bool __pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred) noexcept;
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Pred>
bool __pattern_any_of(
__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred);
//------------------------------------------------------------------------
// walk1 (pseudo)
//

View File

@ -29,52 +29,6 @@ _PSTL_HIDE_FROM_ABI_PUSH
namespace __pstl {
namespace __internal {
//------------------------------------------------------------------------
// any_of
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Pred>
bool __brick_any_of(const _ForwardIterator __first,
const _ForwardIterator __last,
_Pred __pred,
/*__is_vector=*/std::false_type) noexcept {
return std::any_of(__first, __last, __pred);
};
template <class _RandomAccessIterator, class _Pred>
bool __brick_any_of(const _RandomAccessIterator __first,
const _RandomAccessIterator __last,
_Pred __pred,
/*__is_vector=*/std::true_type) noexcept {
return __unseq_backend::__simd_or(__first, __last - __first, __pred);
};
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Pred>
bool __pattern_any_of(
_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) noexcept {
return __internal::__brick_any_of(__first, __last, __pred, typename _Tag::__is_vector{});
}
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Pred>
bool __pattern_any_of(__parallel_tag<_IsVector> __tag,
_ExecutionPolicy&& __exec,
_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Pred __pred) {
using __backend_tag = typename decltype(__tag)::__backend_tag;
return __internal::__except_handler([&]() {
return __internal::__parallel_or(
__backend_tag{},
std::forward<_ExecutionPolicy>(__exec),
__first,
__last,
[__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) {
return __internal::__brick_any_of(__i, __j, __pred, _IsVector{});
});
});
}
// [alg.foreach]
// for_each_n with no policy

View File

@ -20,24 +20,6 @@ _PSTL_HIDE_FROM_ABI_PUSH
namespace std {
// [alg.any_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred);
// [alg.all_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred);
// [alg.none_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred);
// [alg.foreach]
template <class _ExecutionPolicy, class _ForwardIterator, class _Function>

View File

@ -25,33 +25,6 @@ _PSTL_HIDE_FROM_ABI_PUSH
namespace std {
// [alg.any_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
return __pstl::__internal::__pattern_any_of(
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
}
// [alg.all_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Pred>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred));
}
// [alg.none_of]
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
}
// [alg.foreach]
template <class _ExecutionPolicy, class _ForwardIterator, class _Function>

View File

@ -10,11 +10,9 @@
#ifndef _PSTL_PARALLEL_BACKEND_SERIAL_H
#define _PSTL_PARALLEL_BACKEND_SERIAL_H
#include <algorithm>
#include <cstddef>
#include <memory>
#include <numeric>
#include <utility>
#include <__memory/allocator.h>
#include <__pstl/internal/execution_impl.h>
#include <__utility/forward.h>
#include "pstl_config.h"

View File

@ -12,6 +12,7 @@
#include "pstl_config.h"
#include <__pstl/internal/parallel_backend.h>
#include <atomic>
// This header defines the minimum set of parallel routines required to support Parallel STL,
// implemented on top of Intel(R) Threading Building Blocks (Intel(R) TBB) library
@ -66,9 +67,7 @@ __parallel_find(_BackendTag __tag, _ExecutionPolicy&& __exec, _Index __first, _I
//------------------------------------------------------------------------
//! Return true if brick f[i,j) returns true for some subrange [i,j) of [first,last)
template <class _BackendTag, class _ExecutionPolicy, class _Index, class _Brick>
bool
__parallel_or(_BackendTag __tag, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f)
{
bool __parallel_or(_BackendTag __tag, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f) {
std::atomic<bool> __found(false);
__par_backend::__parallel_for(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__f, &__found](_Index __i, _Index __j)

View File

@ -10,6 +10,7 @@
#ifndef _PSTL_UNSEQ_BACKEND_SIMD_H
#define _PSTL_UNSEQ_BACKEND_SIMD_H
#include <__functional/operations.h>
#include <type_traits>
#include "pstl_config.h"

View File

@ -10,6 +10,7 @@
#ifndef _PSTL_UTILS_H
#define _PSTL_UTILS_H
#include <__exception/terminate.h>
#include <iterator>
#include <new>
#include <utility>

View File

@ -0,0 +1,48 @@
//===----------------------------------------------------------------------===//
//
// 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_EXECUTION_POLICY_H
#define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
#include <__config>
#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
inline constexpr bool is_execution_policy_v = false;
template <class>
inline constexpr bool __is_unsequenced_execution_policy_impl = false;
template <class _Tp>
inline constexpr bool __is_unsequenced_execution_policy_v =
__is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>;
template <class>
inline constexpr bool __is_parallel_execution_policy_impl = false;
template <class _Tp>
inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>;
// Removes the "parallel" part of an execution policy.
// For example, turns par_unseq into unseq, and par into seq.
template <class _ExecutionPolicy>
const auto& __remove_parallel_policy(_ExecutionPolicy&&);
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H

View File

@ -0,0 +1,47 @@
//===----------------------------------------------------------------------===//
//
// 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___UTILITY_TERMINATE_ON_EXCEPTION_H
#define _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H
#include <__config>
#include <exception>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
template <class _Func>
_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
try {
return __func();
} catch (...) {
std::terminate();
}
}
# else // _LIBCPP_HAS_NO_EXCEPTIONS
template <class _Func>
_LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) {
return __func();
}
# endif // _LIBCPP_HAS_NO_EXCEPTIONS
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H

View File

@ -1908,6 +1908,10 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/unwrap_iter.h>
#include <__algorithm/upper_bound.h>
#ifdef _LIBCPP_HAS_PARALLEL_ALGORITHMS
# include <__algorithm/pstl_any_all_none_of.h>
#endif
// standard-mandated includes
// [algorithm.syn]

View File

@ -34,7 +34,9 @@ namespace std {
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/is_same.h>
#include <__type_traits/remove_cvref.h>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@ -74,6 +76,14 @@ struct parallel_unsequenced_policy {
inline constexpr parallel_unsequenced_policy par_unseq{__disable_user_instantiations_tag{}};
struct __unsequenced_policy {
constexpr explicit __unsequenced_policy(__disable_user_instantiations_tag) {}
__unsequenced_policy(const __unsequenced_policy&) = delete;
__unsequenced_policy& operator=(const __unsequenced_policy&) = delete;
};
constexpr __unsequenced_policy __unseq{__disable_user_instantiations_tag{}};
# if _LIBCPP_STD_VER >= 20
struct unsequenced_policy {
@ -88,9 +98,6 @@ inline constexpr unsequenced_policy unseq{__disable_user_instantiations_tag{}};
} // namespace execution
template <class>
inline constexpr bool is_execution_policy_v = false;
template <>
inline constexpr bool is_execution_policy_v<execution::sequenced_policy> = true;
@ -100,14 +107,43 @@ inline constexpr bool is_execution_policy_v<execution::parallel_policy> = true;
template <>
inline constexpr bool is_execution_policy_v<execution::parallel_unsequenced_policy> = true;
template <>
inline constexpr bool is_execution_policy_v<execution::__unsequenced_policy> = true;
template <>
inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_policy> = true;
template <>
inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
template <>
inline constexpr bool __is_unsequenced_execution_policy_impl<execution::__unsequenced_policy> = true;
template <>
inline constexpr bool __is_unsequenced_execution_policy_impl<execution::parallel_unsequenced_policy> = true;
# if _LIBCPP_STD_VER >= 20
template <>
inline constexpr bool is_execution_policy_v<execution::unsequenced_policy> = true;
template <>
inline constexpr bool __is_unsequenced_execution_policy_impl<execution::unsequenced_policy> = true;
# endif
template <class _Tp>
struct is_execution_policy : bool_constant<is_execution_policy_v<_Tp>> {};
template <class _ExecutionPolicy>
const auto& __remove_parallel_policy(_ExecutionPolicy&&) {
using _ExecPol = __remove_cvref_t<_ExecutionPolicy>;
if constexpr (is_same_v<_ExecPol, execution::parallel_policy>) {
return execution::seq;
} else if constexpr (is_same_v<_ExecPol, execution::parallel_unsequenced_policy>) {
return execution::__unseq;
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17

View File

@ -1555,6 +1555,7 @@ module std [system] {
private header "__type_traits/is_equality_comparable.h"
export integral_constant
}
module is_execution_policy { private header "__type_traits/is_execution_policy.h" }
module is_final { private header "__type_traits/is_final.h" }
module is_floating_point { private header "__type_traits/is_floating_point.h" }
module is_function { private header "__type_traits/is_function.h" }
@ -1672,29 +1673,30 @@ module std [system] {
export *
module __utility {
module as_const { private header "__utility/as_const.h" }
module auto_cast {
module as_const { private header "__utility/as_const.h" }
module auto_cast {
private header "__utility/auto_cast.h"
export type_traits.decay
}
module cmp { private header "__utility/cmp.h" }
module convert_to_integral { private header "__utility/convert_to_integral.h" }
module declval { private header "__utility/declval.h" }
module exception_guard { private header "__utility/exception_guard.h" }
module exchange { private header "__utility/exchange.h" }
module forward { private header "__utility/forward.h" }
module forward_like { private header "__utility/forward_like.h" }
module in_place { private header "__utility/in_place.h" }
module integer_sequence { private header "__utility/integer_sequence.h" }
module move { private header "__utility/move.h" }
module pair { private header "__utility/pair.h" }
module pair_fwd { private header "__fwd/pair.h" }
module piecewise_construct { private header "__utility/piecewise_construct.h" }
module priority_tag { private header "__utility/priority_tag.h" }
module rel_ops { private header "__utility/rel_ops.h" }
module swap { private header "__utility/swap.h" }
module to_underlying { private header "__utility/to_underlying.h" }
module unreachable { private header "__utility/unreachable.h" }
module cmp { private header "__utility/cmp.h" }
module convert_to_integral { private header "__utility/convert_to_integral.h" }
module declval { private header "__utility/declval.h" }
module exception_guard { private header "__utility/exception_guard.h" }
module exchange { private header "__utility/exchange.h" }
module forward { private header "__utility/forward.h" }
module forward_like { private header "__utility/forward_like.h" }
module in_place { private header "__utility/in_place.h" }
module integer_sequence { private header "__utility/integer_sequence.h" }
module move { private header "__utility/move.h" }
module pair { private header "__utility/pair.h" }
module pair_fwd { private header "__fwd/pair.h" }
module piecewise_construct { private header "__utility/piecewise_construct.h" }
module priority_tag { private header "__utility/priority_tag.h" }
module rel_ops { private header "__utility/rel_ops.h" }
module swap { private header "__utility/swap.h" }
module terminate_on_exception { private header "__utility/terminate_on_exception.h" }
module to_underlying { private header "__utility/to_underlying.h" }
module unreachable { private header "__utility/unreachable.h" }
}
}
module valarray {

View File

@ -8,7 +8,7 @@
// REQUIRES: has-clang-tidy
// FIXME: This should pass with the PSTL enables
// FIXME: This should pass with the PSTL enabled
// XFAIL: with-pstl
// The GCC compiler flags are not always compatible with clang-tidy.

View File

@ -0,0 +1,27 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// Check that PSTL algorithms aren't marked [[nodiscard]] when
// _LIBCPP_DISBALE_NODISCARD_EXT is defined
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_NODISCARD_EXT
// REQUIRES: with-pstl
// UNSUPPORTED: c++03, c++11, c++14
#include <algorithm>
#include <execution>
void test() {
int a[] = {1};
auto pred = [](auto) { return false; };
std::all_of(std::execution::par, std::begin(a), std::end(a), pred);
std::any_of(std::execution::par, std::begin(a), std::end(a), pred);
std::none_of(std::execution::par, std::begin(a), std::end(a), pred);
}

View File

@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// Check that PSTL algorithms are marked [[nodiscard]] as a conforming extension
// REQUIRES: with-pstl
// UNSUPPORTED: c++03, c++11, c++14
#include <algorithm>
#include <execution>
void test() {
int a[] = {1};
auto pred = [](auto) { return false; };
std::all_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::any_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::none_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

View File

@ -9,6 +9,9 @@
// Test that headers are not tripped up by the surrounding code defining various
// alphabetic macros.
// FIXME: This should pass with the PSTL enabled
// XFAIL: with-pstl
// Prevent <ext/hash_map> from generating deprecated warnings for this test.
#if defined(__DEPRECATED)
# undef __DEPRECATED

View File

@ -683,6 +683,7 @@ END-SCRIPT
#include <__type_traits/is_empty.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_empty.h'}}
#include <__type_traits/is_enum.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_enum.h'}}
#include <__type_traits/is_equality_comparable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_equality_comparable.h'}}
#include <__type_traits/is_execution_policy.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_execution_policy.h'}}
#include <__type_traits/is_final.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_final.h'}}
#include <__type_traits/is_floating_point.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_floating_point.h'}}
#include <__type_traits/is_function.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_function.h'}}
@ -782,6 +783,7 @@ END-SCRIPT
#include <__utility/priority_tag.h> // expected-error@*:* {{use of private header from outside its module: '__utility/priority_tag.h'}}
#include <__utility/rel_ops.h> // expected-error@*:* {{use of private header from outside its module: '__utility/rel_ops.h'}}
#include <__utility/swap.h> // expected-error@*:* {{use of private header from outside its module: '__utility/swap.h'}}
#include <__utility/terminate_on_exception.h> // expected-error@*:* {{use of private header from outside its module: '__utility/terminate_on_exception.h'}}
#include <__utility/to_underlying.h> // expected-error@*:* {{use of private header from outside its module: '__utility/to_underlying.h'}}
#include <__utility/unreachable.h> // expected-error@*:* {{use of private header from outside its module: '__utility/unreachable.h'}}
#include <__variant/monostate.h> // expected-error@*:* {{use of private header from outside its module: '__variant/monostate.h'}}

View File

@ -32,6 +32,9 @@
// this test instead.
// UNSUPPORTED: transitive-includes-disabled
// FIXME: This should pass with the PSTL enabled
// XFAIL: with-pstl
// Prevent <ext/hash_map> from generating deprecated warnings for this test.
#if defined(__DEPRECATED)
# undef __DEPRECATED

View File

@ -213,6 +213,7 @@ exception cstddef
exception cstdlib
exception type_traits
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm atomic
213 exception cstdlib
214 exception type_traits
215 exception version
216 execution cstddef
217 execution version
218 expected cstddef
219 expected initializer_list

View File

@ -213,6 +213,7 @@ exception cstddef
exception cstdlib
exception type_traits
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm atomic
213 exception cstdlib
214 exception type_traits
215 exception version
216 execution cstddef
217 execution version
218 expected cstddef
219 expected initializer_list

View File

@ -213,6 +213,7 @@ exception cstddef
exception cstdlib
exception type_traits
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm atomic
213 exception cstdlib
214 exception type_traits
215 exception version
216 execution cstddef
217 execution version
218 expected cstddef
219 expected initializer_list

View File

@ -213,6 +213,7 @@ exception cstddef
exception cstdlib
exception type_traits
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm atomic
213 exception cstdlib
214 exception type_traits
215 exception version
216 execution cstddef
217 execution version
218 expected cstddef
219 expected initializer_list

View File

@ -221,6 +221,7 @@ exception cstddef
exception cstdlib
exception type_traits
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm atomic
221 exception cstdlib
222 exception type_traits
223 exception version
224 execution cstddef
225 execution version
226 expected cstddef
227 expected initializer_list

View File

@ -140,6 +140,7 @@ deque version
exception cstddef
exception cstdlib
exception version
execution cstddef
execution version
expected cstddef
expected initializer_list

1 algorithm climits
140 exception cstddef
141 exception cstdlib
142 exception version
143 execution cstddef
144 execution version
145 expected cstddef
146 expected initializer_list

View File

@ -0,0 +1,83 @@
//===----------------------------------------------------------------------===//
//
// 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
// REQUIRES: with-pstl
// <algorithm>
// template<class ExecutionPolicy, class ForwardIterator, class Predicate>
// bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
// Predicate pred);
#include <algorithm>
#include <cassert>
#include <vector>
#include "test_macros.h"
#include "test_execution_policies.h"
#include "test_iterators.h"
EXECUTION_POLICY_SFINAE_TEST(all_of);
static_assert(sfinae_test_all_of<int, int*, int*, bool (*)(int)>);
static_assert(!sfinae_test_all_of<std::execution::parallel_policy, int*, int*, bool (*)(int)>);
template <class Iter>
struct Test {
template <class Policy>
void operator()(Policy&& policy) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
// simple test
assert(std::all_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i < 9; }));
assert(!std::all_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i < 8; }));
// check that an empty range works
assert(std::all_of(policy, Iter(std::begin(a)), Iter(std::begin(a)), [](int) { return true; }));
// check that a single-element range works
assert(std::all_of(policy, Iter(a), Iter(a + 1), [](int i) { return i < 2; }));
// check that a two-element range works
assert(std::all_of(policy, Iter(a), Iter(a + 2), [](int i) { return i < 3; }));
// check that false is returned if no element satisfies the condition
assert(!std::all_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 9; }));
// check that false is returned if only one elements satisfies the condition
assert(!std::all_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 1; }));
// check that a one-element range works
assert(std::all_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 1), [](int i) { return i == 1; }));
// check that a two-element range works
assert(std::all_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 2), [](int i) { return i < 3; }));
// check that a large number of elements works
std::vector<int> vec(100);
std::fill(vec.begin(), vec.end(), 3);
assert(std::all_of(Iter(vec.data()), Iter(vec.data() + vec.size()), [](int i) { return i == 3; }));
}
};
int main(int, char**) {
types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
#ifndef TEST_HAS_NO_EXCEPTIONS
std::set_terminate(terminate_successful);
int a[] = {1, 2};
try {
(void)std::all_of(std::execution::par, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
} catch (int) {
assert(false);
}
#endif
return 0;
}

View File

@ -0,0 +1,77 @@
//===----------------------------------------------------------------------===//
//
// 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
// REQUIRES: with-pstl
// <algorithm>
// template<class ExecutionPolicy, class ForwardIterator, class Predicate>
// bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
// Predicate pred);
#include <algorithm>
#include <cassert>
#include <vector>
#include "test_macros.h"
#include "test_execution_policies.h"
#include "test_iterators.h"
EXECUTION_POLICY_SFINAE_TEST(any_of);
static_assert(sfinae_test_any_of<int, int*, int*, bool (*)(int)>);
static_assert(!sfinae_test_any_of<std::execution::parallel_policy, int*, int*, bool (*)(int)>);
template <class Iter>
struct Test {
template <class Policy>
void operator()(Policy&& policy) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
// simple test
assert(std::any_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i < 9; }));
assert(!std::any_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i > 8; }));
// check that an empty range works
assert(!std::any_of(policy, Iter(std::begin(a)), Iter(std::begin(a)), [](int) { return false; }));
// check that false is returned if no element satisfies the condition
assert(!std::any_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 9; }));
// check that true is returned if only one elements satisfies the condition
assert(std::any_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 1; }));
// check that a one-element range works
assert(std::any_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 1), [](int i) { return i == 1; }));
// check that a two-element range works
assert(std::any_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 2), [](int i) { return i == 2; }));
// check that a large number of elements works
std::vector<int> vec(100, 2);
vec[96] = 3;
assert(std::any_of(Iter(vec.data()), Iter(vec.data() + vec.size()), [](int i) { return i == 3; }));
}
};
int main(int, char**) {
types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
#ifndef TEST_HAS_NO_EXCEPTIONS
std::set_terminate(terminate_successful);
int a[] = {1, 2};
try {
(void)std::any_of(std::execution::par, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
} catch (int) {
assert(false);
}
#endif
return 0;
}

View File

@ -0,0 +1,75 @@
//===----------------------------------------------------------------------===//
//
// 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: with-pstl
// <algorithm>
// template<class ExecutionPolicy, class ForwardIterator, class Predicate>
// bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
// Predicate pred);
#include <algorithm>
#include <cassert>
#include <vector>
#include "test_macros.h"
#include "test_execution_policies.h"
#include "test_iterators.h"
EXECUTION_POLICY_SFINAE_TEST(none_of);
static_assert(sfinae_test_none_of<int, int*, int*, bool (*)(int)>);
static_assert(!sfinae_test_none_of<std::execution::parallel_policy, int*, int*, bool (*)(int)>);
template <class Iter>
struct Test {
template <class Policy>
void operator()(Policy&& policy) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
// simple test
assert(std::none_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i > 9; }));
assert(!std::none_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i >= 8; }));
// check that an empty range works
assert(std::none_of(policy, Iter(std::begin(a)), Iter(std::begin(a)), [](int) { return false; }));
// check that true is returned if no element satisfies the condition
assert(std::none_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 9; }));
// check that false is returned if only one elements satisfies the condition
assert(!std::none_of(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 1; }));
// check that a one-element range works
assert(std::none_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 1), [](int i) { return i != 1; }));
// check that a two-element range works
assert(std::none_of(policy, Iter(std::begin(a)), Iter(std::begin(a) + 2), [](int i) { return i > 2; }));
// check that a large number of elements works
std::vector<int> vec(100);
std::fill(vec.begin(), vec.end(), 3);
assert(std::none_of(Iter(vec.data()), Iter(vec.data() + vec.size()), [](int i) { return i != 3; }));
}
};
int main(int, char**) {
types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
#ifndef TEST_HAS_NO_EXCEPTIONS
std::set_terminate(terminate_successful);
int a[] = {1, 2};
try {
(void)std::none_of(std::execution::par, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
} catch (int) {
assert(false);
}
#endif
return 0;
}

View File

@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
//
// 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_TEST_EXECUTION_POLICIES
#define TEST_SUPPORT_TEST_EXECUTION_POLICIES
#include <cstdlib>
#include <execution>
#include <type_traits>
#include <utility>
#include "test_macros.h"
#define EXECUTION_POLICY_SFINAE_TEST(function) \
template <class, class...> \
struct sfinae_test_##function##_impl : std::true_type {}; \
\
template <class... Args> \
struct sfinae_test_##function##_impl<std::void_t<decltype(std::function(std::declval<Args>()...))>, Args...> \
: std::false_type {}; \
\
template <class... Args> \
constexpr bool sfinae_test_##function = sfinae_test_##function##_impl<void, Args...>::value;
template <class Functor>
bool test_execution_policies(Functor func) {
func(std::execution::seq);
#if TEST_STD_VER >= 20
func(std::execution::unseq);
#endif
func(std::execution::par);
func(std::execution::par_unseq);
return true;
}
template <template <class Iter> class TestClass>
struct TestIteratorWithPolicies {
template <class Iter>
void operator()() {
test_execution_policies(TestClass<Iter>{});
}
};
[[noreturn]] inline void terminate_successful() { std::exit(0); }
#endif // TEST_SUPPORT_TEST_EXECUTION_POLICIES

View File

@ -128,7 +128,7 @@ def main():
experimental_headers = sorted(str(p.relative_to(include)) for p in include.glob('experimental/[a-z]*') if is_header(p))
extended_headers = sorted(str(p.relative_to(include)) for p in include.glob('ext/[a-z]*') if is_header(p))
public_headers = toplevel_headers + experimental_headers + extended_headers
private_headers = sorted(str(p.relative_to(include)) for p in include.rglob('*') if is_header(p) and str(p.relative_to(include)).startswith('__'))
private_headers = sorted(str(p.relative_to(include)) for p in include.rglob('*') if is_header(p) and str(p.relative_to(include)).startswith('__') and not p.name.startswith('pstl'))
variables = {
'toplevel_headers': toplevel_headers,
'experimental_headers': experimental_headers,