Skip to content

Commit 7498faf

Browse files
committed
[oneDPL][ranges] + a fix: ranges::transform algo requires the all 3 ranges to be sized (according to p3179r4)
1 parent 19cc54f commit 7498faf

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,35 +99,32 @@ struct __transform_fn
9999
return {std::ranges::begin(__r) + __size, std::ranges::begin(__out_r) + __size};
100100
}
101101

102-
template<typename _ExecutionPolicy, std::ranges::random_access_range _R1, std::ranges::random_access_range _R2,
103-
std::ranges::random_access_range _OutRange, std::copy_constructible _F, typename _Proj1 = std::identity,
104-
typename _Proj2 = std::identity>
105-
requires oneapi::dpl::is_execution_policy_v<std::remove_cvref_t<_ExecutionPolicy>> && (std::ranges::sized_range<_R1>
106-
|| std::ranges::sized_range<_R2>) && std::ranges::sized_range<_OutRange>
107-
&& std::indirectly_writable<std::ranges::iterator_t<_OutRange>,
108-
std::indirect_result_t<_F&, std::projected<std::ranges::iterator_t<_R1>, _Proj1>,
109-
std::projected<std::ranges::iterator_t<_R2>, _Proj2>>>
110-
111-
std::ranges::binary_transform_result<std::ranges::borrowed_iterator_t<_R1>, std::ranges::borrowed_iterator_t<_R2>,
112-
std::ranges::borrowed_iterator_t<_OutRange>>
113-
operator()(_ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, _F __binary_op,
114-
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
102+
template <typename _ExecutionPolicy, std::ranges::random_access_range _R1, std::ranges::random_access_range _R2,
103+
std::ranges::random_access_range _OutRange, std::copy_constructible _F, typename _Proj1 = std::identity,
104+
typename _Proj2 = std::identity>
105+
requires oneapi::dpl::is_execution_policy_v<std::remove_cvref_t<_ExecutionPolicy>>&& std::ranges::sized_range<_R1>&&
106+
std::ranges::sized_range<_R2>&& std::ranges::sized_range<_OutRange>&&
107+
std::indirectly_writable<std::ranges::iterator_t<_OutRange>,
108+
std::indirect_result_t<_F&, std::projected<std::ranges::iterator_t<_R1>, _Proj1>,
109+
std::projected<std::ranges::iterator_t<_R2>, _Proj2>>>
110+
111+
std::ranges::binary_transform_result<std::ranges::borrowed_iterator_t<_R1>,
112+
std::ranges::borrowed_iterator_t<_R2>,
113+
std::ranges::borrowed_iterator_t<_OutRange>>
114+
operator()(_ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, _F __binary_op,
115+
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
115116
{
116117
const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec);
117118

118119
using _Size = std::common_type_t<oneapi::dpl::__internal::__range_size_t<_R1>,
119120
oneapi::dpl::__internal::__range_size_t<_R2>, std::ranges::range_size_t<_OutRange>>;
120-
_Size __size = std::ranges::size(__out_r);
121-
if constexpr(std::ranges::sized_range<_R1>)
122-
__size = std::ranges::min(__size, (_Size)std::ranges::size(__r1));
123-
if constexpr(std::ranges::sized_range<_R2>)
124-
__size = std::ranges::min(__size, (_Size)std::ranges::size(__r2));
121+
const _Size __size = std::ranges::min((_Size)std::ranges::size(__r1), (_Size)std::ranges::size(__r2),
122+
(_Size)std::ranges::size(__out_r));
125123

126-
//take_view doesn't make unsized range sized, so subrange is used below
127-
oneapi::dpl::__internal::__ranges::__pattern_transform(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
128-
std::ranges::subrange(std::ranges::begin(__r1), std::ranges::begin(__r1) + __size),
129-
std::ranges::subrange(std::ranges::begin(__r2), std::ranges::begin(__r2) + __size),
130-
std::ranges::take_view(__out_r, __size), __binary_op, __proj1, __proj2);
124+
oneapi::dpl::__internal::__ranges::__pattern_transform(
125+
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), std::ranges::take_view(__r1, __size),
126+
std::ranges::take_view(__r2, __size), std::ranges::take_view(__out_r, __size), __binary_op, __proj1,
127+
__proj2);
131128

132129
return {std::ranges::begin(__r1) + __size, std::ranges::begin(__r2) + __size, std::ranges::begin(__out_r) + __size};
133130
}

test/parallel_api/ranges/std_ranges_transform_iota.pass.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ main()
2121
#if _ENABLE_STD_RANGES_TESTING
2222
using namespace test_std_ranges;
2323
namespace dpl_ranges = oneapi::dpl::ranges;
24-
const char* err_msg = "Wrong effect algo transform with unsized ranges.";
24+
const char* err_msg = "Wrong effect algo ranges::transform.";
2525

26-
const int n = medium_size;
27-
std::ranges::iota_view view1(0, n); //size range
28-
std::ranges::iota_view view2(0, std::unreachable_sentinel_t{}); //unsized
26+
const int n1 = medium_size;
27+
const int n2 = medium_size/2;
28+
std::ranges::iota_view view1(0, n1);
29+
std::ranges::iota_view view2(0, n2);
2930

3031
std::vector<int> res(n), expected(n);
3132
std::ranges::transform(view1, view2, expected.begin(), binary_f, proj, proj);

0 commit comments

Comments
 (0)