Parallel foreach over AliasSec?

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Feb 27 03:53:09 PST 2017


On 02/27/2017 10:52 AM, Bastiaan Veelo wrote:
> On Monday, 27 February 2017 at 02:02:57 UTC, ag0aep6g wrote:
[...]
>> enum fptr(alias f) = &f;
> (This is still a bit magical to me: it this a shorthand for a template?)

Yes, it's short for this:

template fptr(alias f) { enum fptr = &f; }

"addrOf" is probably a better name for this. It's not restricted to 
functions.

> Can the following be made to work?
>
> int one(int) {return 1;}
[...]
> int one(string) {return 0;} // How to ignore this?
>
> int[8] values;
>
> template eval_all(funcs...)
> {
>     void eval_all(int val)
>     {
[...]
>         //enum fptr(alias f) = &f;          // Error: cannot infer type
> from
>                                             // overloaded function
> symbol & one
>         enum fptr(alias int f(int)) = &f;   // ditto.

Aside: That funky, C-like syntax surprised me. I guess that's a function 
type as opposed to a function pointer type, which would be `alias int 
function(int) f`. That distinction always trips me up.

>         enum fptrs = staticMap!(fptr, funcs);
>         auto r = only(fptrs);
>
>         foreach (i, f; parallel(r))
>             values[i] = f(val);
>     }
> }

You can generate wrapper functions that have no overloads:

----
static int wrap(alias f)(int arg) { return f(arg); }
enum addrOf(alias f) = &f;
enum fptrs = staticMap!(addrOf, staticMap!(wrap, funcs));
/* ... r and foreach as before ... */
----

This also unifies the signatures in other ways. For example, you can 
have a function that takes a `long` instead of an int.

Of course, if you passed the functions at run time, and not in a 
template parameter, the code would be much shorter:

----
void eval_all(int val, int function(int)[] funcs ...)
{
     import std.parallelism;

     foreach (i, f; parallel(funcs))
         values[i] = f(val);
}
void main()
{
     eval_all(42, &one, &two, &three, &four, &five, &six, &seven,
	&eight);
     foreach(i, val; values)
         assert(val == i + 1);
}
----

One little disadvantage of this is that the signatures have to match 
exactly. Overloads are fine, but you can't have a function with a `long` 
parameter. But that's really minor, and can be handled at the call site.

I think I'd prefer this over the template version. You have to make a 
run-time list of the functions anyway, for `parallel`, so the template 
stuff just seems to add complexity.


More information about the Digitalmars-d-learn mailing list