Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
{
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
} //__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