Skip to content

<algorithm>, <execution>, <xutility>: Parallel algorithms inconsistently _REQUIRE_MEOW #2985

@StephanTLavavej

Description

@StephanTLavavej

Should be addressed after merging #2960, not before.

We're currently inconsistent about whether parallel algorithms use _REQUIRE_PARALLEL_ITERATOR (for reading) and _REQUIRE_CPP17_MUTABLE_ITERATOR (for writing).

The following overloads (found by searching for all occurrences of _ExPo&&) are missing enforcement. Some are just calling the classic serial algorithms, others are doing real parallel work:

  • <algorithm>:
    • swap_ranges(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Dest)
    • generate(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Fn _Func)
    • unique(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
    • unique(_ExPo&&, _FwdIt _First, _FwdIt _Last)
    • shift_left(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Iter_diff_t<_FwdIt> _Pos_to_shift)
    • shift_right(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Iter_diff_t<_FwdIt> _Pos_to_shift)
    • stable_partition(_ExPo&&, _BidIt _First, _BidIt _Last, _Pr _Pred)
    • inplace_merge(_ExPo&&, _BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred)
    • inplace_merge(_ExPo&&, _BidIt _First, _BidIt _Mid, _BidIt _Last)
    • partial_sort(_ExPo&&, _RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred)
    • partial_sort(_ExPo&&, _RanIt _First, _RanIt _Mid, _RanIt _Last)
    • nth_element(_ExPo&&, _RanIt _First, _RanIt _Nth, _RanIt _Last, _Pr _Pred)
    • nth_element(_ExPo&&, _RanIt _First, _RanIt _Nth, _RanIt _Last)
    • max_element(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
    • max_element(_ExPo&&, _FwdIt _First, _FwdIt _Last)
    • min_element(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
    • min_element(_ExPo&&, _FwdIt _First, _FwdIt _Last)
    • minmax_element(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
    • minmax_element(_ExPo&&, _FwdIt _First, _FwdIt _Last)
  • <execution>:
    • adjacent_find(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
    • search_n(_ExPo&&, const _FwdIt _First, _FwdIt _Last, const _Diff _Count_raw, const _Ty& _Val, _Pr _Pred)
    • remove_if(_ExPo&&, _FwdIt _First, const _FwdIt _Last, _Pr _Pred)
    • sort(_ExPo&&, const _RanIt _First, const _RanIt _Last, _Pr _Pred)
    • stable_sort(_ExPo&&, const _BidIt _First, const _BidIt _Last, _Pr _Pred)
    • partition(_ExPo&&, _FwdIt _First, const _FwdIt _Last, _Pr _Pred)
  • <xutility>:
    • reverse(_ExPo&&, _BidIt _First, _BidIt _Last)
    • rotate(_ExPo&&, _FwdIt _First, _FwdIt _Mid, _FwdIt _Last)

Additionally (although less concerning), there are some _ExPo&& overloads that check the requirements and then call another _ExPo&& overload. This is inconsistently done (more often, it seems that we directly call another _ExPo&& overload and expect it to perform checking).

I think that a reasonable policy would be: all _ExPo&& overloads (of publicly usable functions) should immediately perform checking, whether they're calling classic serial or doing real work, unless they are immediately calling another _ExPo&& overload (typically to provide defaulted comparators etc).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSomething can be improvedfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions