[pstl] A hot fix for exclusive_scan (+ lost enable_if in declaration)

It fixes an ambiguity issue in case of a user has a custom policy and
calls a version of exclusive_scan with binary operation.

Differential Revision: https://reviews.llvm.org/D62719
This commit is contained in:
Mikhail Dvorskiy 2020-03-17 16:03:02 -04:00 committed by Louis Dionne
parent c48442c9f3
commit 36b8d02c8d
3 changed files with 52 additions and 6 deletions

View File

@ -60,7 +60,7 @@ exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIte
_ForwardIterator2 __result, _Tp __init);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
_ForwardIterator2
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op);

View File

@ -101,17 +101,25 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init)
{
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
std::plus<_Tp>(), __pstl::__internal::__no_op());
using namespace __pstl;
return __internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
std::plus<_Tp>(), /*inclusive=*/std::false_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
_ForwardIterator2
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op)
{
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
__binary_op, __pstl::__internal::__no_op());
using namespace __pstl;
return __internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
__binary_op, /*inclusive=*/std::false_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
}
// [inclusive.scan]

View File

@ -0,0 +1,38 @@
// -*- C++ -*-
//===-- scan.fail.cpp -----------------------------------------------------===//
//
// 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++98, c++03, c++11, c++14
#include <execution>
#include <numeric>
struct CustomPolicy
{
constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
} policy;
int32_t
main()
{
int *first = nullptr, *last = nullptr, *result = nullptr;
std::exclusive_scan(policy, first, last, result, 0); // expected-error {{no matching function for call to 'exclusive_scan'}}
std::exclusive_scan(policy, first, last, result, 0, std::plus<int>()); // expected-error {{no matching function for call to 'exclusive_scan'}}
return 0;
}