Skip to content

Commit 0b537e6

Browse files
committed
[oneDPL][ranges] + implementation fix for a random access range without operator[] and size() method
1 parent 62863bd commit 0b537e6

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,47 @@ namespace dpl
4848
namespace ranges
4949
{
5050

51+
namespace __internal
52+
{
53+
54+
template<typename _T>
55+
concept __is_subscriptable = requires(_T&& __a) { __a[0]; };
56+
57+
template<typename _T>
58+
concept __is_not_subscriptable = !__is_subscriptable<_T>;
59+
60+
template<typename _T>
61+
concept __is_sizeable = requires(_T&& __a) { __a.size(); };
62+
63+
template <typename _R>
64+
struct _WrapperRAR: public _R
65+
{
66+
template <typename _Base>
67+
_WrapperRAR(_Base&& __r): _R(std::forward<_Base>(__r)) {}
68+
decltype(auto) operator[](auto __i) { return _R::begin()[__i]; }
69+
decltype(auto) operator[](auto __i) const { return _R::begin()[__i]; }
70+
71+
std::enable_if_t<!__is_sizeable<_R>, std::ranges::range_size_t<_R>>
72+
size() const { return this->_R::end() - this->_R::begin(); }
73+
};
74+
75+
template <__is_not_subscriptable _R>
76+
constexpr decltype (auto)
77+
__get_r(_R&& __r)
78+
{
79+
using _T = std::remove_reference_t<_R>;
80+
return _WrapperRAR<_T>(std::forward<_R>(__r));
81+
}
82+
83+
template <__is_subscriptable _R>
84+
constexpr decltype (auto)
85+
__get_r(_R&& __r)
86+
{
87+
return std::forward<_R>(__r);
88+
}
89+
90+
} //__internal
91+
5192
// [alg.foreach]
5293

5394
namespace __internal
@@ -64,7 +105,7 @@ struct __for_each_fn
64105
{
65106
const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec);
66107
oneapi::dpl::__internal::__ranges::__pattern_for_each(
67-
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __r, __f, __proj);
108+
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __get_r(__r), __f, __proj);
68109

69110
return {std::ranges::begin(__r) + std::ranges::size(__r)};
70111
}

0 commit comments

Comments
 (0)