Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
2 changes: 1 addition & 1 deletion include/oneapi/dpl/pstl/glue_algorithm_ranges_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,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
87 changes: 71 additions & 16 deletions include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ struct __transform_fn

inline constexpr __internal::__transform_fn transform;

// [alg.find_if]
// [alg.find]

namespace __internal
{
Expand All @@ -159,8 +159,6 @@ struct __find_if_fn

inline constexpr __internal::__find_if_fn find_if;

// [alg.find_if_not]

namespace __internal
{
struct __find_if_not_fn
Expand All @@ -173,39 +171,96 @@ struct __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

struct __find_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_iterator_t<_R>
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);
}
}; //__find_fn
} //__internal

inline constexpr __internal::__find_if_not_fn find_if_not;
inline constexpr __internal::__find_fn find;

// [alg.find]
// [alg.find.last]

namespace __internal
{
struct __find_fn
struct __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
{
auto __last = std::ranges::begin(__r) + std::ranges::size(__r);
std::ranges::reverse_view __reverse_r{std::forward<_R>(__r)};

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

return {(__res == __reverse_r.end()) ? __last : __res.base() - 1, __last};
Comment thread
dmitriy-sobolev marked this conversation as resolved.
Outdated
}
}; //__find_last_if_fn
} //__internal

inline constexpr __internal::__find_last_if_fn find_last_if;

namespace __internal
{
struct __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

struct __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_iterator_t<_R>
std::ranges::borrowed_subrange_t<_R>
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);
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_fn
}; //__find_last_fn
} //__internal

inline constexpr __internal::__find_fn find;
inline constexpr __internal::__find_last_if_not_fn find_last_if_not;
inline constexpr __internal::__find_last_fn find_last;

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

namespace __internal
{
Expand All @@ -232,7 +287,7 @@ struct __find_first_of_fn

inline constexpr __internal::__find_first_of_fn find_first_of;

// [alg.find_end]
// [alg.find.end]

namespace __internal
{
Expand Down Expand Up @@ -1441,7 +1496,7 @@ find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2)
::std::forward<_Range2>(__rng2), oneapi::dpl::__internal::__pstl_equal());
}

// [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
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