From dbdd17f02337d5f244daedf4e2921aef2b73842f Mon Sep 17 00:00:00 2001 From: David Olsen Date: Thu, 25 Aug 2022 14:54:58 -0700 Subject: [PATCH] Parallel for_each iterators don't have to be mutable The overloads of for_each that take an execution policy argument do not require that the iterator arguments always be mutable iterators. Whether or not the iterators need to be mutable depends on what the function object does. for_each is unusual, if not unique, in this regard; for all other algorithms the mutability of the iterators is specified by the algorithm. See http://eel.is/c++draft/alg.foreach#7 , though I admit that the wording is not particularly clear about this. Since the compiler can't realiably figure out whether or not the function object modifies the elements in the sequence, for_each should only check for constant iterators (_REQUIRE_PARALLEL_ITERATOR), not mutable iterators (_REQUIRE_CPP17_MUTABLE_ITERATOR). This bug was introduced by https://github.com/microsoft/STL/pull/2960 . That PR should not have changed for_each. --- stl/inc/execution | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/execution b/stl/inc/execution index 43e01bd07a..99c9a37091 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -1189,7 +1189,7 @@ struct _Static_partitioned_for_each2 { // for_each task scheduled on the system template /* = 0 */> void for_each(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Fn _Func) noexcept /* terminates */ { // perform function for each element [_First, _Last) with the indicated execution policy - _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt); + _REQUIRE_PARALLEL_ITERATOR(_FwdIt); _Adl_verify_range(_First, _Last); auto _UFirst = _Get_unwrapped(_First); const auto _ULast = _Get_unwrapped(_Last);