Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/oneapi/dpl/pstl/glue_algorithm_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward
find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
_ForwardIterator2 __s_last);

// [alg.find_first_of]
// [alg.find.first.of]

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
Expand Down
2 changes: 1 addition & 1 deletion include/oneapi/dpl/pstl/glue_algorithm_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1
oneapi::dpl::__internal::__pstl_equal());
}

// [alg.find_first_of]
// [alg.find.first.of]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
Expand Down
5 changes: 4 additions & 1 deletion include/oneapi/dpl/pstl/glue_algorithm_ranges_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct __transform_fn;
struct __find_if_fn;
struct __find_if_not_fn;
struct __find_fn;
struct __find_last_if_fn;
struct __find_last_if_not_fn;
struct __find_last_fn;
struct __find_first_of_fn;
struct __find_end_fn;
struct __any_of_fn;
Expand Down Expand Up @@ -134,7 +137,7 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
oneapi::dpl::__internal::__difference_t<_Range1>>
find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2);

// [alg.find_first_of]
// [alg.find.first.of]

template <typename _ExecutionPolicy, typename _Range1, typename _Range2, typename _BinaryPredicate>
oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
Expand Down
63 changes: 59 additions & 4 deletions include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ struct __internal::__find_if_not_fn
operator()(_ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj = {}) const
{
return oneapi::dpl::ranges::find_if(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r),
oneapi::dpl::__internal::__not_pred<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy,
_Pred>>(__pred), __proj);
oneapi::dpl::__internal::__not_pred<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _Pred>>(__pred),
__proj);
}
}; //__find_if_not_fn
inline constexpr __internal::__find_if_not_fn find_if_not;
Expand All @@ -174,12 +174,67 @@ struct __internal::__find_fn
operator()(_ExecutionPolicy&& __exec, _R&& __r, const _T& __value, _Proj __proj = {}) const
{
return oneapi::dpl::ranges::find_if(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r),
oneapi::dpl::__internal::__equal_value<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy,
const _T>>(__value), __proj);
oneapi::dpl::__internal::__equal_value<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _T>>
(__value), __proj);
}
}; //__find_fn
inline constexpr __internal::__find_fn find;

// [alg.find.last]

struct __internal::__find_last_if_fn
{
template <typename _ExecutionPolicy, std::ranges::random_access_range _R, typename _Proj = std::identity,
std::indirect_unary_predicate<std::projected<std::ranges::iterator_t<_R>, _Proj>> _Pred>
requires oneapi::dpl::is_execution_policy_v<std::remove_cvref_t<_ExecutionPolicy>> &&
std::ranges::sized_range<_R>
std::ranges::borrowed_subrange_t<_R>
operator()(_ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj = {}) const
{
std::ranges::reverse_view __reverse_r{__r};

auto __res = oneapi::dpl::ranges::find_if(std::forward<_ExecutionPolicy>(__exec), __reverse_r, __pred, __proj);

auto __last = std::ranges::begin(__r) + std::ranges::size(__r);
return {(__res == __reverse_r.end()) ? __last : __res.base() - 1, __last};
}
}; //__find_last_if_fn
inline constexpr __internal::__find_last_if_fn find_last_if;

struct __internal::__find_last_if_not_fn
{
template <typename _ExecutionPolicy, std::ranges::random_access_range _R, typename _Proj = std::identity,
std::indirect_unary_predicate<std::projected<std::ranges::iterator_t<_R>, _Proj>> _Pred>
requires oneapi::dpl::is_execution_policy_v<std::remove_cvref_t<_ExecutionPolicy>> &&
std::ranges::sized_range<_R>
std::ranges::borrowed_subrange_t<_R>
operator()(_ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj = {}) const
{
return oneapi::dpl::ranges::find_last_if(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r),
oneapi::dpl::__internal::__not_pred<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _Pred>>(__pred),
__proj);
}
}; //__find_last_if_not_fn
inline constexpr __internal::__find_last_if_not_fn find_last_if_not;

struct __internal::__find_last_fn
{
template <typename _ExecutionPolicy, std::ranges::random_access_range _R, typename _Proj = std::identity,
typename _T = oneapi::dpl::projected_value_t<std::ranges::iterator_t<_R>, _Proj>>
requires oneapi::dpl::is_execution_policy_v<std::remove_cvref_t<_ExecutionPolicy>> &&
std::ranges::sized_range<_R> &&
std::indirect_binary_predicate<std::ranges::equal_to,
std::projected<std::ranges::iterator_t<_R>, _Proj>, const _T*>
std::ranges::borrowed_subrange_t<_R>
operator()(_ExecutionPolicy&& __exec, _R&& __r, const _T& __value, _Proj __proj = {}) const
{
return oneapi::dpl::ranges::find_last_if(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r),
oneapi::dpl::__internal::__equal_value<oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _T>>
(__value), __proj);
}
}; //__find_last_fn
inline constexpr __internal::__find_last_fn find_last;

// [alg.find.first.of]

struct __internal::__find_first_of_fn
Expand Down
50 changes: 50 additions & 0 deletions test/parallel_api/ranges/std_ranges_find_last.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// -*- C++ -*-
//===------------------------------------------------------===//
//
// Copyright (C) UXL Foundation Contributors
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===------------------------------------------------------===//

#include "std_ranges_test.h"

#if _ENABLE_STD_RANGES_TESTING
#if __cpp_lib_ranges_find_last >= 202207L
auto checker = TEST_PREPARE_CALLABLE(std::ranges::find_last);
#else
struct {
template<std::ranges::forward_range R, typename T, typename Proj = std::identity>
std::ranges::borrowed_subrange_t<R> operator()(R&& r, const T& val, Proj proj = {})
{
std::ranges::iterator_t<R> res{}, it{};
bool found = false;
for (it = std::ranges::begin(r); it != std::ranges::end(r); ++it)
{
if (std::invoke(proj, *it) == val)
{
res = it;
found = true;
}
}
return {found? res : it, it};
}
} checker;
#endif
#endif

std::int32_t
main()
{
#if _ENABLE_STD_RANGES_TESTING
using namespace test_std_ranges;
namespace dpl_ranges = oneapi::dpl::ranges;

test_range_algo<0>{big_sz}(dpl_ranges::find_last, checker, 314);
test_range_algo<1>{}(dpl_ranges::find_last, checker, 271, proj);
test_range_algo<2, P2>{}(dpl_ranges::find_last, checker, 99, &P2::x);
test_range_algo<3, P2>{}(dpl_ranges::find_last, checker, -359, &P2::proj); // not found
#endif //_ENABLE_STD_RANGES_TESTING

return TestUtils::done(_ENABLE_STD_RANGES_TESTING);
}
52 changes: 52 additions & 0 deletions test/parallel_api/ranges/std_ranges_find_last_if.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// -*- C++ -*-
//===------------------------------------------------------===//
//
// Copyright (C) UXL Foundation Contributors
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===------------------------------------------------------===//

#include "std_ranges_test.h"

#if _ENABLE_STD_RANGES_TESTING
#if __cpp_lib_ranges_find_last >= 202207L
auto checker = TEST_PREPARE_CALLABLE(std::ranges::find_last_if);
#else
struct {
template<std::ranges::forward_range R, typename Pred, typename Proj = std::identity>
std::ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
{
std::ranges::iterator_t<R> res{}, it{};
bool found = false;
for (it = std::ranges::begin(r); it != std::ranges::end(r); ++it)
{
if (bool(std::invoke(pred, std::invoke(proj, *it))))
{
res = it;
found = true;
}
}
return {found? res : it, it};
}
} checker;
#endif
#endif

std::int32_t
main()
{
#if _ENABLE_STD_RANGES_TESTING
using namespace test_std_ranges;
namespace dpl_ranges = oneapi::dpl::ranges;

auto less397 = [](auto&& val) { return val < 397; };

test_range_algo<0>{big_sz}(dpl_ranges::find_last_if, checker, pred);
test_range_algo<1>{}(dpl_ranges::find_last_if, checker, less397, proj);
test_range_algo<2, P2>{}(dpl_ranges::find_last_if, checker, pred3, &P2::x); // not found
test_range_algo<3, P2>{}(dpl_ranges::find_last_if, checker, pred, &P2::proj);
#endif //_ENABLE_STD_RANGES_TESTING

return TestUtils::done(_ENABLE_STD_RANGES_TESTING);
}
52 changes: 52 additions & 0 deletions test/parallel_api/ranges/std_ranges_find_last_if_not.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// -*- C++ -*-
//===------------------------------------------------------===//
//
// Copyright (C) UXL Foundation Contributors
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===------------------------------------------------------===//

#include "std_ranges_test.h"

#if _ENABLE_STD_RANGES_TESTING
#if __cpp_lib_ranges_find_last >= 202207L
auto checker = TEST_PREPARE_CALLABLE(std::ranges::find_last_if_not);
#else
struct {
template<std::ranges::forward_range R, typename Pred, typename Proj = std::identity>
std::ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
{
std::ranges::iterator_t<R> res{}, it{};
bool found = false;
for (it = std::ranges::begin(r); it != std::ranges::end(r); ++it)
{
if (!bool(std::invoke(pred, std::invoke(proj, *it))))
{
res = it;
found = true;
}
}
return {found? res : it, it};
}
} checker;
#endif
#endif

std::int32_t
main()
{
#if _ENABLE_STD_RANGES_TESTING
using namespace test_std_ranges;
namespace dpl_ranges = oneapi::dpl::ranges;

auto less397 = [](auto&& val) { return val < 397; };

test_range_algo<0>{big_sz}(dpl_ranges::find_last_if_not, checker, less397);
test_range_algo<1>{}(dpl_ranges::find_last_if_not, checker, less397, proj);
test_range_algo<2, P2>{}(dpl_ranges::find_last_if_not, checker, pred1, &P2::x); // not found
test_range_algo<3, P2>{}(dpl_ranges::find_last_if_not, checker, less397, &P2::proj);
#endif //_ENABLE_STD_RANGES_TESTING

return TestUtils::done(_ENABLE_STD_RANGES_TESTING);
}
18 changes: 15 additions & 3 deletions test/parallel_api/ranges/std_ranges_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,21 @@ struct test
// check result types
static_assert(std::is_same_v<decltype(res), decltype(expected_res)>, "Wrong return type");

EXPECT_EQ(ret_in_val(expected_res, expected_view.begin()), ret_in_val(res, r_in.begin()),
(std::string("wrong stop position with ") + typeid(Algo).name() +
typeid(decltype(tr_in(std::declval<Container&>()()))).name() + sizes).c_str());
if constexpr(is_range<std::remove_cvref_t<decltype(res)>>)
{
std::pair exp_split = ret_in_val(expected_res, expected_view.begin());
std::pair split = ret_in_val(res, r_in.begin());
EXPECT_EQ(exp_split.first, split.first, (std::string("wrong stop position with ") + typeid(Algo).name() +
typeid(decltype(tr_in(std::declval<Container&>()()))).name() + sizes).c_str());
EXPECT_EQ(exp_split.second, split.second, (std::string("wrong subrange size with ") + typeid(Algo).name() +
typeid(decltype(tr_in(std::declval<Container&>()()))).name() + sizes).c_str());
}
else
{
EXPECT_EQ(ret_in_val(expected_res, expected_view.begin()), ret_in_val(res, r_in.begin()),
(std::string("wrong stop position with ") + typeid(Algo).name() +
typeid(decltype(tr_in(std::declval<Container&>()()))).name() + sizes).c_str());
}

//check result
auto n = std::ranges::size(expected_view);
Expand Down
Loading