Skip to content
Draft
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
601bd65
include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h - refactoring of…
SergeyKopienko Sep 25, 2025
d617268
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix e…
SergeyKopienko Sep 25, 2025
36cc203
@@@ comments
SergeyKopienko Sep 25, 2025
d774033
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - using…
SergeyKopienko Oct 6, 2025
a1422c5
include/oneapi/dpl/pstl/utils_ranges.h - define template alias iterat…
SergeyKopienko Oct 6, 2025
7f5257b
Now all implementations of __pattern_minmax_element + __hetero_tag re…
SergeyKopienko Oct 6, 2025
8aaad1a
Revert "@@@ comments"
SergeyKopienko Oct 6, 2025
4b4452d
test/support/utils.h - fix compile error in struct MinimalisticRange
SergeyKopienko Oct 8, 2025
c1c7fa8
include/oneapi/dpl/pstl/utils_ranges.h - implementation of universal …
SergeyKopienko Oct 7, 2025
095dead
include/oneapi/dpl/pstl/utils_ranges.h - insert additional comments
SergeyKopienko Oct 7, 2025
8f01d1d
include/oneapi/dpl/pstl/utils_ranges.h - define __iterator_t type for…
SergeyKopienko Oct 7, 2025
659ffeb
include/oneapi/dpl/pstl/utils_ranges.h - re-implement oneapi::dpl::__…
SergeyKopienko Oct 7, 2025
d8cd950
include/oneapi/dpl/pstl/utils_ranges.h - re-implement oneapi::dpl::__…
SergeyKopienko Oct 7, 2025
83462de
include/oneapi/dpl/pstl/utils_ranges.h - apply oneapi::dpl::__ranges:…
SergeyKopienko Oct 7, 2025
56db3b4
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - apply…
SergeyKopienko Oct 7, 2025
9b70191
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - apply…
SergeyKopienko Oct 7, 2025
ea5a684
include/oneapi/dpl/pstl/utils_ranges.h - re-implement oneapi::dpl::__…
SergeyKopienko Oct 7, 2025
e433702
Revert "include/oneapi/dpl/pstl/utils_ranges.h - re-implement oneapi:…
SergeyKopienko Oct 7, 2025
b4ca0c9
include/oneapi/dpl/pstl/utils_ranges.h - remove try to lookup begin()…
SergeyKopienko Oct 7, 2025
4309083
include/oneapi/dpl/pstl/utils_ranges.h - remove try to lookup begin()…
SergeyKopienko Oct 7, 2025
435f5b4
include/oneapi/dpl/pstl/utils_ranges.h - fix compile errors
SergeyKopienko Oct 7, 2025
fb22a88
include/oneapi/dpl/pstl/utils_ranges.h - fix review comment
SergeyKopienko Oct 7, 2025
d912ec8
include/oneapi/dpl/pstl/utils_ranges.h - refactoring of oneapi::dpl::…
SergeyKopienko Oct 8, 2025
a3b51b7
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - defin…
SergeyKopienko Oct 8, 2025
42ce3ba
include/oneapi/dpl/pstl/utils_ranges.h - remove the definition of __i…
SergeyKopienko Oct 8, 2025
0b445fa
include/oneapi/dpl/pstl/utils_ranges.h - remove extra names of namesp…
SergeyKopienko Oct 8, 2025
6c0d832
include/oneapi/dpl/pstl/utils_ranges.h - remove extra comments
SergeyKopienko Oct 8, 2025
d9b5da0
include/oneapi/dpl/pstl/utils_ranges.h - fix compile error
SergeyKopienko Oct 8, 2025
5196ffd
Merge branch 'dev/skopienko/fix_compile_error_in_tests' into dev/skop…
SergeyKopienko Oct 8, 2025
79b55d0
Revert "include/oneapi/dpl/pstl/utils_ranges.h - remove extra names o…
SergeyKopienko Oct 8, 2025
04b78fe
include/oneapi/dpl/pstl/utils_ranges.h - remove extra names of namesp…
SergeyKopienko Oct 8, 2025
cac6744
include/oneapi/dpl/pstl/utils_ranges.h - simplify oneapi::dpl::__rang…
SergeyKopienko Oct 8, 2025
5959306
include/oneapi/dpl/pstl/utils_ranges.h - refactoring of oneapi::dpl::…
SergeyKopienko Oct 8, 2025
a0e7610
Merge branch 'main' into dev/skopienko/avoid_begin_end_calls_for_ranges
SergeyKopienko Oct 8, 2025
e70a6c3
include/oneapi/dpl/pstl/utils_ranges.h - simplify __subscription_impl…
SergeyKopienko Oct 8, 2025
243dc62
include/oneapi/dpl/pstl/utils_ranges.h - simplify __size(_Range&& __rng)
SergeyKopienko Oct 8, 2025
33a7581
include/oneapi/dpl/pstl/utils_ranges.h - remove extra macro checks
SergeyKopienko Oct 8, 2025
be15f37
include/oneapi/dpl/pstl/utils_ranges.h - simplify __subscription_impl…
SergeyKopienko Oct 8, 2025
c1d8d2c
simplify oneapi::dpl::__ranges::__get_subscription_view()
SergeyKopienko Oct 8, 2025
30b1a23
Merge branch 'main' into dev/skopienko/declare_types_for_pattern_minm…
SergeyKopienko Oct 8, 2025
86c79c2
include/oneapi/dpl/pstl/utils_ranges.h - change struct __nth_range_si…
SergeyKopienko Oct 8, 2025
ce40dfd
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix a…
SergeyKopienko Oct 8, 2025
ea84263
Merge branch 'dev/skopienko/avoid_begin_end_calls_for_ranges' into de…
SergeyKopienko Oct 8, 2025
b64c1c1
include/oneapi/dpl/pstl/utils_ranges.h - define oneapi::dpl::__ranges…
SergeyKopienko Oct 8, 2025
0636f9d
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix c…
SergeyKopienko Oct 8, 2025
1b0b06b
Fix self-review comments
SergeyKopienko Oct 8, 2025
646b9b2
Declare return type for pattern oneapi::dpl::__internal::__range::__p…
SergeyKopienko Oct 8, 2025
71337cb
include/oneapi/dpl/pstl/algorithm_ranges_impl.h - fix error in __patt…
SergeyKopienko Oct 8, 2025
3d358e1
Avoid auto result type in oneapi::dpl::__internal::__ranges::__patter…
SergeyKopienko Oct 8, 2025
24d1f8a
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - intro…
SergeyKopienko Oct 8, 2025
90413ab
include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h - fix compile error
SergeyKopienko Oct 8, 2025
774da31
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - small…
SergeyKopienko Oct 8, 2025
6f14490
include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h - fix an error: …
SergeyKopienko Oct 8, 2025
053aa98
include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h - fix compile er…
SergeyKopienko Oct 9, 2025
01a71e2
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix c…
SergeyKopienko Oct 9, 2025
5feae77
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix r…
SergeyKopienko Oct 9, 2025
2793222
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h - fix r…
SergeyKopienko Oct 9, 2025
077aca5
include/oneapi/dpl/pstl/algorithm_ranges_impl.h - fix compile error i…
SergeyKopienko Oct 9, 2025
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
6 changes: 3 additions & 3 deletions include/oneapi/dpl/pstl/algorithm_ranges_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ __pattern_min(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Pr
//---------------------------------------------------------------------------------------------------------------------

template <typename _Tag, typename _ExecutionPolicy, typename _R, typename _Proj, typename _Comp>
auto
std::pair<oneapi::dpl::__ranges::__iterator_t<_R>, oneapi::dpl::__ranges::__iterator_t<_R>>
__pattern_minmax_element(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj)
{
static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{});
Expand All @@ -495,7 +495,7 @@ __pattern_minmax_element(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp
}

template <typename _ExecutionPolicy, typename _R, typename _Proj, typename _Comp>
auto
std::pair<oneapi::dpl::__ranges::__iterator_t<_R>, oneapi::dpl::__ranges::__iterator_t<_R>>
__pattern_minmax_element(__serial_tag</*IsVector*/ std::false_type>, _ExecutionPolicy&&, _R&& __r, _Comp __comp,
_Proj __proj)
{
Expand All @@ -511,7 +511,7 @@ std::pair<std::ranges::range_value_t<_R>, std::ranges::range_value_t<_R>>
__pattern_minmax(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj)
{
auto [__it_min, __it_max] =
__pattern_minmax_element(__tag, std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __comp, __proj);
__pattern_minmax_element(__tag, std::forward<_ExecutionPolicy>(__exec), __r, __comp, __proj);

return {*__it_min, *__it_max};
}
Expand Down
20 changes: 13 additions & 7 deletions include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -617,11 +617,12 @@ struct __minmax_element_fn
operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec);
const auto& [__min, __max] =
oneapi::dpl::__internal::__ranges::__pattern_minmax_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
std::forward<_R>(__r), __comp, __proj);

return {__min, __max};
std::pair<oneapi::dpl::__ranges::__iterator_t<_R>, oneapi::dpl::__ranges::__iterator_t<_R>> __res =
oneapi::dpl::__internal::__ranges::__pattern_minmax_element(
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __r, __comp, __proj);

return {__res.first, __res.second};
}
}; //__minmax_element_fn
} //__internal
Expand Down Expand Up @@ -2031,9 +2032,14 @@ minmax_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp)
{
const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng);

return oneapi::dpl::__internal::__ranges::__pattern_minmax_element(
__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)),
__comp);
auto __view = views::all_read(std::forward<_Range>(__rng));
auto __v_begin = __view.begin();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version of minmax_element is a part of experimental API which can accept a SYCl buffer. In that case views::all_read returns a placeholder accessor.

SYCL spec tells:
"... a placeholder accessor is not yet bound to a command group. Before such an accessor can be used in a command, it must be bound by calling handler::require(). Passing a placeholder accessor as an argument to a command without first being bound to a command group with handler::require() will result in undefined behavior."

So, a result of accessor::begin() call is undefined behavior.

using __v_iterator_t = decltype(__v_begin);

std::pair<__v_iterator_t, __v_iterator_t> __res = oneapi::dpl::__internal::__ranges::__pattern_minmax_element(
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __view, __comp);

return {std::distance(__v_begin, __res.first), std::distance(__v_begin, __res.second)};
}

template <typename _ExecutionPolicy, typename _Range>
Expand Down
61 changes: 34 additions & 27 deletions include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ __pattern_min_element_impl(_BackendTag __tag, _ExecutionPolicy&& __exec, _Range&
{
assert(oneapi::dpl::__ranges::__size(__rng) > 0);

using _IteratorValueType = typename ::std::iterator_traits<decltype(__rng.begin())>::value_type;
using _IteratorValueType = oneapi::dpl::__internal::__value_t<_Range>;
using _IndexValueType = oneapi::dpl::__internal::__difference_t<_Range>;
using _ReduceValueType = oneapi::dpl::__internal::tuple<_IndexValueType, _IteratorValueType>;

Expand Down Expand Up @@ -1312,14 +1312,21 @@ __pattern_min(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _R&& __r, _C
// minmax_element
//------------------------------------------------------------------------

template <typename _Range>
using __range_index_and_value =
std::pair<oneapi::dpl::__internal::__difference_t<_Range>, oneapi::dpl::__internal::__value_t<_Range>>;

template <typename _Range>
using __pattern_minmax_element_impl_return_t =
std::pair<__range_index_and_value<_Range>, __range_index_and_value<_Range>>;

template <typename _BackendTag, typename _ExecutionPolicy, typename _Range, typename _Compare>
std::pair<std::pair<oneapi::dpl::__internal::__difference_t<_Range>, oneapi::dpl::__internal::__value_t<_Range>>,
std::pair<oneapi::dpl::__internal::__difference_t<_Range>, oneapi::dpl::__internal::__value_t<_Range>>>
__pattern_minmax_element_impl_return_t<_Range>
__pattern_minmax_element_impl(_BackendTag, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp)
{
assert(oneapi::dpl::__ranges::__size(__rng) > 0);

using _IteratorValueType = typename ::std::iterator_traits<decltype(__rng.begin())>::value_type;
using _IteratorValueType = oneapi::dpl::__internal::__value_t<_Range>;
using _IndexValueType = oneapi::dpl::__internal::__difference_t<_Range>;
using _ReduceValueType =
oneapi::dpl::__internal::tuple<_IndexValueType, _IndexValueType, _IteratorValueType, _IteratorValueType>;
Expand All @@ -1333,48 +1340,52 @@ __pattern_minmax_element_impl(_BackendTag, _ExecutionPolicy&& __exec, _Range&& _
// a `tuple` of `difference_type`, not the `difference_type` itself.
oneapi::dpl::__internal::__pattern_minmax_element_transform_fn<_ReduceValueType> __transform_fn;

const auto& [__idx_min, __idx_max, __min, __max] =
const auto& [__idx_min, __idx_max, __val_min, __val_max] =
oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType,
::std::false_type /*is_commutative*/>(
_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn,
unseq_backend::__no_init_value{}, // no initial value
oneapi::dpl::__ranges::__get_subscription_view(std::forward<_Range>(__rng)))
.get();

return {{__idx_min, __min}, {__idx_max, __max}};
return {{__idx_min, __val_min}, {__idx_max, __val_max}};
}

template <typename _BackendTag, typename _ExecutionPolicy, typename _Range, typename _Compare>
std::pair<oneapi::dpl::__internal::__difference_t<_Range>, oneapi::dpl::__internal::__difference_t<_Range>>
std::pair<oneapi::dpl::__ranges::__iterator_t<_Range>, oneapi::dpl::__ranges::__iterator_t<_Range>>
__pattern_minmax_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp)
{
auto __begin = oneapi::dpl::__ranges::__begin(__rng);

//If size == 1, result is the zero-indexed element. If size == 0, result is 0.
if (oneapi::dpl::__ranges::__size(__rng) < 2)
return {0, 0};

[[maybe_unused]] const auto& [__res_min, __res_max] = __pattern_minmax_element_impl(
_BackendTag{}, std::forward<_ExecutionPolicy>(__exec),
oneapi::dpl::__ranges::__get_subscription_view(std::forward<_Range>(__rng)), __comp);
return {__begin, __begin};

[[maybe_unused]] const auto& [__idx_min, __min] = __res_min;
[[maybe_unused]] const auto& [__idx_max, __max] = __res_max;
__pattern_minmax_element_impl_return_t<_Range> __res =
__pattern_minmax_element_impl(_BackendTag{}, std::forward<_ExecutionPolicy>(__exec), __rng, __comp);

return {__idx_min, __idx_max};
return {__begin + __res.first.first, __begin + __res.second.first};
}

#if _ONEDPL_CPP20_RANGES_PRESENT
template <typename _BackendTag, typename _ExecutionPolicy, typename _R, typename _Proj, typename _Comp>
std::pair<std::ranges::borrowed_iterator_t<_R>, std::ranges::borrowed_iterator_t<_R>>
std::pair<std::ranges::iterator_t<_R>, std::ranges::iterator_t<_R>>
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type should use std::ranges::borrowed_iterator_t<_R> instead of std::ranges::iterator_t<_R> to properly handle dangling iterator cases when the range is a temporary object.

Suggested change
std::pair<std::ranges::iterator_t<_R>, std::ranges::iterator_t<_R>>
std::pair<std::ranges::borrowed_iterator_t<_R>, std::ranges::borrowed_iterator_t<_R>>

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

@SergeyKopienko SergeyKopienko Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declined.

As far as we apply the result of this function like in minmax_element below

template <typename _ExecutionPolicy, typename _Range, typename _Compare>
oneapi::dpl::__internal::__enable_if_execution_policy<
    _ExecutionPolicy,
    ::std::pair<oneapi::dpl::__internal::__difference_t<_Range>, oneapi::dpl::__internal::__difference_t<_Range>>>
minmax_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp)
{
    const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng);

    auto __begin = __rng.begin();

    auto [__it_min, __it_max] = oneapi::dpl::__internal::__ranges::__pattern_minmax_element(
        __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), views::all_read(__rng), __comp);

    return {std::distance(__begin, __it_min), std::distance(__begin, __it_max)};
}

we can't return std::ranges::borrowed_iterator_t<_R> from __pattern_minmax_element because in that case std::distance can't be called for __begin and std::ranges::dangling instance.

Also this implementation of minmax_element exists not under _ONEDPL_CPP20_RANGES_PRESENT macro (it's inside namespace oneapi::dpl::experimental::ranges) so we can't use the types like std::ranges::borrowed_iterator_t in return types of __pattern_minmax_element.

__pattern_minmax_element(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp,
_Proj __proj)
{
oneapi::dpl::__internal::__binary_op<_Comp, _Proj, _Proj> __comp_2{__comp, __proj, __proj};

const auto [__min_idx, __max_idx] =
oneapi::dpl::__internal::__ranges::__pattern_minmax_element(__tag, std::forward<_ExecutionPolicy>(__exec),
oneapi::dpl::__ranges::views::all_read(__r), __comp_2);
auto __r_begin = __r.begin();

auto __view = oneapi::dpl::__ranges::views::all_read(__r);
auto __v_begin = __view.begin();
using __v_iterator_t = decltype(__v_begin);

return {std::ranges::begin(__r) + __min_idx, std::ranges::begin(__r) + __max_idx};
std::pair<__v_iterator_t, __v_iterator_t> __res = oneapi::dpl::__internal::__ranges::__pattern_minmax_element(
__tag, std::forward<_ExecutionPolicy>(__exec), __view, __comp_2);

return {__r_begin + std::ranges::distance(__v_begin, __res.first),
__r_begin + std::ranges::distance(__v_begin, __res.second)};
}

template <typename _BackendTag, typename _ExecutionPolicy, typename _R, typename _Proj, typename _Comp>
Expand All @@ -1383,14 +1394,10 @@ __pattern_minmax(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _R&& __r,
{
oneapi::dpl::__internal::__binary_op<_Comp, _Proj, _Proj> __comp_2{__comp, __proj, __proj};

[[maybe_unused]] const auto& [__res_min, __res_max] =
__pattern_minmax_element_impl(_BackendTag{}, std::forward<_ExecutionPolicy>(__exec),
oneapi::dpl::__ranges::__get_subscription_view(std::forward<_R>(__r)), __comp_2);

[[maybe_unused]] const auto& [__idx_min, __min] = __res_min;
[[maybe_unused]] const auto& [__idx_max, __max] = __res_max;
__pattern_minmax_element_impl_return_t<_R> __res = __pattern_minmax_element_impl(
_BackendTag{}, std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __comp_2);

return {__min, __max};
return {__res.first.second, __res.second.second};
}

template <typename _BackendTag, typename _ExecutionPolicy, typename _R1, typename _R2, typename _Pred, typename _Proj1,
Expand Down
86 changes: 45 additions & 41 deletions include/oneapi/dpl/pstl/utils_ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,77 +121,85 @@ using projected_value_t = std::remove_cvref_t<std::invoke_result_t<Proj&, std::i
namespace __ranges
{

#if _ONEDPL_CPP20_RANGES_PRESENT
template <typename _Range>
bool
__empty(_Range&& __rng)
auto
__begin(_Range&& __rng)
{
return std::ranges::empty(__rng);
#if _ONEDPL_CPP20_RANGES_PRESENT
return std::ranges::begin(__rng);
#else
return __rng.begin();
#endif
}

template <typename _Range>
auto
__end(_Range&& __rng)
{
#if _ONEDPL_CPP20_RANGES_PRESENT
return std::ranges::end(__rng);
#else
return __rng.end();
#endif
}

template <typename _Range>
using __iterator_t = decltype(__begin(std::declval<_Range&>()));

template <typename _R, typename = void>
struct __has_empty : std::false_type
struct __has_size : std::false_type
{
};

template <typename _R>
struct __has_empty<_R, std::void_t<decltype(std::declval<_R>().empty())>> : std::true_type
struct __has_size<_R, std::void_t<decltype(std::declval<_R>().size())>> : std::true_type
{
};

template <typename _Range>
bool
__empty(_Range&& __rng)
auto
__size(_Range&& __rng)
{
if constexpr (__has_empty<_Range>::value)
return __rng.empty();
#if _ONEDPL_CPP20_RANGES_PRESENT
return std::ranges::size(__rng);
#else
if constexpr (__has_size<_Range>::value)
return __rng.size();
else
return __rng.begin() == __rng.end();
}
return std::distance(__begin(__rng), __end(__rng));
#endif
}

template <typename _R, typename = void>
struct __has_size : std::false_type
struct __has_empty : std::false_type
{
};

template <typename _R>
struct __has_size<_R, std::void_t<decltype(std::declval<_R>().size())>> : std::true_type
struct __has_empty<_R, std::void_t<decltype(std::declval<_R>().empty())>> : std::true_type
{
};

template <typename _Range>
std::enable_if_t<__has_size<_Range>::value, decltype(std::declval<_Range>().size())>
__size(_Range&& __rng)
bool
__empty(_Range&& __rng)
{
return __rng.size();
}

#if _ONEDPL_CPP20_RANGES_PRESENT
template <typename _Range>
std::enable_if_t<!__has_size<_Range>::value,
decltype(std::ranges::distance(std::declval<_Range>().begin(), std::declval<_Range>().end()))>
__size(_Range&& __rng)
{
return std::ranges::distance(__rng.begin(), __rng.end());
}
return std::ranges::empty(__rng);
#else
template <typename _Range>
std::enable_if_t<!__has_size<_Range>::value,
decltype(std::distance(std::declval<_Range>().begin(), std::declval<_Range>().end()))>
__size(_Range&& __rng)
{
return std::distance(__rng.begin(), __rng.end());
}
if constexpr (__has_empty<_Range>::value)
return __rng.empty();
else
return __size(__rng) == 0;
#endif
}

template <typename... _Rng>
using __common_size_t = std::common_type_t<std::make_unsigned_t<decltype(__size(std::declval<_Rng>()))>...>;

template <std::size_t _RngIndex>
struct __nth_range_size
class __nth_range_size
{
private:
template <std::size_t _RngIndexCurrent, typename _Range, typename... _Ranges>
auto
__nth_range_size_impl(const _Range& __rng, const _Ranges&... __rngs) const
Expand Down Expand Up @@ -754,13 +762,13 @@ struct __subscription_impl_view_simple : _Base
decltype(auto)
operator[](index_type __i)
{
return *std::next(_Base::begin(), __i);
return *std::next(__begin(*static_cast<_Base*>(this)), __i);
}

decltype(auto)
operator[](index_type __i) const
{
return *std::next(_Base::begin(), __i);
return *std::next(__begin(*static_cast<const _Base*>(this)), __i);
}
};

Expand All @@ -769,13 +777,9 @@ decltype(auto)
__get_subscription_view(_Range&& __rng)
{
if constexpr (__has_subscription_op<_Range>::value)
{
return std::forward<_Range>(__rng);
}
else
{
return __subscription_impl_view_simple<_Range>(std::forward<_Range>(__rng));
}
}

} // namespace __ranges
Expand Down
Loading