Skip to content

Commit a35a720

Browse files
Fix element_type initialization logic for parallel projections
The parallel implementations of min_element, max_element, and minmax_element previously deduced element_type solely from the underlying iterator, ignoring the projection. This resulted in hard initialization failures when projections returned a different type than the iterator's value type, causing CI to break when the SFINAE paths instantiated the tag_invoke dispatch bodies for parallel executions. By explicitly inferring element_type directly from the decayed decltype mapped to the projection invocation, the element_type now robustly propagates and enables projection polymorphism.
1 parent ebbee07 commit a35a720

1 file changed

Lines changed: 21 additions & 23 deletions

File tree

  • libs/core/algorithms/include/hpx/parallel/algorithms

libs/core/algorithms/include/hpx/parallel/algorithms/minmax.hpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,11 @@ namespace hpx::parallel {
404404
if (count == 0 || count == 1)
405405
return it;
406406

407-
using element_type = hpx::traits::proxy_value_t<
408-
typename std::iterator_traits<FwdIter>::value_type>;
409-
410407
auto smallest = it;
411408

409+
using element_type = hpx::traits::proxy_value_t<
410+
std::decay_t<decltype(HPX_INVOKE(proj, *smallest))>>;
411+
412412
element_type value = HPX_INVOKE(proj, *smallest);
413413
util::loop_n<std::decay_t<ExPolicy>>(
414414
++it, count - 1, [&](FwdIter const& curr) -> void {
@@ -443,9 +443,8 @@ namespace hpx::parallel {
443443

444444
auto smallest = *it;
445445

446-
using element_type =
447-
hpx::traits::proxy_value_t<typename std::iterator_traits<
448-
decltype(smallest)>::value_type>;
446+
using element_type = hpx::traits::proxy_value_t<
447+
std::decay_t<decltype(HPX_INVOKE(proj, *smallest))>>;
449448

450449
element_type value = HPX_INVOKE(proj, *smallest);
451450
util::loop_n<std::decay_t<ExPolicy>>(
@@ -474,11 +473,11 @@ namespace hpx::parallel {
474473
if (first == last)
475474
return first;
476475

477-
using element_type = hpx::traits::proxy_value_t<
478-
typename std::iterator_traits<FwdIter>::value_type>;
479-
480476
auto smallest = first;
481477

478+
using element_type = hpx::traits::proxy_value_t<
479+
std::decay_t<decltype(HPX_INVOKE(proj, *smallest))>>;
480+
482481
element_type value = HPX_INVOKE(proj, *smallest);
483482
util::loop(HPX_FORWARD(ExPolicy, policy), ++first, last,
484483
[&](FwdIter const& curr) -> void {
@@ -557,11 +556,11 @@ namespace hpx::parallel {
557556
if (count == 0 || count == 1)
558557
return it;
559558

560-
using element_type = hpx::traits::proxy_value_t<
561-
typename std::iterator_traits<FwdIter>::value_type>;
562-
563559
auto largest = it;
564560

561+
using element_type = hpx::traits::proxy_value_t<
562+
std::decay_t<decltype(HPX_INVOKE(proj, *largest))>>;
563+
565564
element_type value = HPX_INVOKE(proj, *largest);
566565
util::loop_n<std::decay_t<ExPolicy>>(
567566
++it, count - 1, [&](FwdIter const& curr) -> void {
@@ -596,9 +595,8 @@ namespace hpx::parallel {
596595

597596
auto largest = *it;
598597

599-
using element_type =
600-
hpx::traits::proxy_value_t<typename std::iterator_traits<
601-
decltype(largest)>::value_type>;
598+
using element_type = hpx::traits::proxy_value_t<
599+
std::decay_t<decltype(HPX_INVOKE(proj, *largest))>>;
602600

603601
element_type value = HPX_INVOKE(proj, *largest);
604602
util::loop_n<std::decay_t<ExPolicy>>(
@@ -627,11 +625,11 @@ namespace hpx::parallel {
627625
if (first == last)
628626
return first;
629627

630-
using element_type = hpx::traits::proxy_value_t<
631-
typename std::iterator_traits<FwdIter>::value_type>;
632-
633628
auto largest = first;
634629

630+
using element_type = hpx::traits::proxy_value_t<
631+
std::decay_t<decltype(HPX_INVOKE(proj, *largest))>>;
632+
635633
element_type value = HPX_INVOKE(proj, *largest);
636634
util::loop(HPX_FORWARD(ExPolicy, policy), ++first, last,
637635
[&](FwdIter const& curr) -> void {
@@ -713,7 +711,7 @@ namespace hpx::parallel {
713711
return result;
714712

715713
using element_type = hpx::traits::proxy_value_t<
716-
typename std::iterator_traits<FwdIter>::value_type>;
714+
std::decay_t<decltype(HPX_INVOKE(proj, *it))>>;
717715

718716
element_type min_value = HPX_INVOKE(proj, *it);
719717
element_type max_value = min_value;
@@ -754,11 +752,11 @@ namespace hpx::parallel {
754752
if (count == 1)
755753
return *it;
756754

757-
using element_type = hpx::traits::proxy_value_t<
758-
typename std::iterator_traits<Iter>::value_type>;
759-
760755
auto result = *it;
761756

757+
using element_type = hpx::traits::proxy_value_t<
758+
std::decay_t<decltype(HPX_INVOKE(proj, *result.min))>>;
759+
762760
element_type min_value = HPX_INVOKE(proj, *result.min);
763761
element_type max_value = HPX_INVOKE(proj, *result.max);
764762
util::loop_n<std::decay_t<ExPolicy>>(
@@ -803,7 +801,7 @@ namespace hpx::parallel {
803801
}
804802

805803
using element_type = hpx::traits::proxy_value_t<
806-
typename std::iterator_traits<FwdIter>::value_type>;
804+
std::decay_t<decltype(HPX_INVOKE(proj, *min))>>;
807805

808806
element_type min_value = HPX_INVOKE(proj, *min);
809807
element_type max_value = HPX_INVOKE(proj, *max);

0 commit comments

Comments
 (0)