[Issue 19984] Support shared in foreach lambdas
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Mar 19 07:52:25 UTC 2021
https://issues.dlang.org/show_bug.cgi?id=19984
Nicholas Wilson <iamthewilsonator at hotmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |iamthewilsonator at hotmail.co
| |m
--- Comment #2 from Nicholas Wilson <iamthewilsonator at hotmail.com> ---
with explicit captures and no magic changing of type it is possible to do the
below. It shouldn't be too hard to adapt it to multiple captured parameters. If
this is acceptable to close the bug report with then it could be added to
phobos.
```
import core.atomic;
import std.stdio;
import std.range;
struct S {
int result;
void inc(int i) shared { result.atomicOp!"+="(i); }
}
int main(){
S s;
foreach(i,_; iota(1000).parallel(capture!s)){
_.s.inc(i);
}
int a;
foreach (i; iota(1000))
a +=i;
writeln(s.result); // 499500
writeln(a); // 499500
return 0;
}
//alias capture(alias c) = Tuple!(shared typeof(c),__traits(identifier,c));
auto capture(alias c)()
{
return Capture!c(c);
}
struct Capture(alias c)
{
shared typeof(c)* ptr;
this(ref typeof(c) _c)
{
ptr = cast(shared)&c;
}
ref opDispatch(string s)()
{
return *ptr;
}
}
// a fake, minimal, not-parallel std.parallelism.parallel
auto parallel(R, C)(R r, scope C c)
{
return ParallelCapture!(R, C)(r,c);
}
struct ParallelCapture(R, C)
{
R range;
C capture;
this(R r, scope C c)
{
range = r;
capture = c;
}
alias E = ElementType!R;
alias NoIndexDg = int delegate(E, C);
int opApply(scope NoIndexDg dg)
{
foreach(e; range)
{
if (dg(e,capture))
return 1;
}
return 0;
}
}
```
--
More information about the Digitalmars-d-bugs
mailing list