https://issues.dlang.org/show_bug.cgi?id=19984

Nicholas Wilson <iamthewilsona...@hotmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |iamthewilsona...@hotmail.co
                   |                            |m

--- Comment #2 from Nicholas Wilson <iamthewilsona...@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;
    }
}
```

--

Reply via email to