How to provide this arg or functor for algorithm?

cym13 via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 16 05:30:52 PDT 2015


On Sunday, 16 August 2015 at 11:53:42 UTC, FreeSlave wrote:
> Let's say I want to map some range using some context.
> The obvious way is to do:
>
> uint[3] arr = [1,2,3];
> uint context = 2;
> auto r = arr[].map!(delegate(value) { return value * context; 
> });
>
> The problem is that this allocates delegate, so it can't be 
> used in @nogc code.
> What I want to do might look like this:
>
> static struct Caller
> {
>     this(uint context) @nogc {
>         _context = context;
>     }
>     auto opCall(uint value) @nogc {
>         return value * _context;
>     }
>     uint _context;
> }
>
> auto caller = Caller(2);
> auto r = arr[].map!(&caller.opCall);
>
> But it will not work of course since function must be a 
> compile-time parameter.
>
> So the way to go would be:
>
> auto caller = Caller(2);
> auto r = arr[].map!(Caller.opCall)(&caller);
>
> But map and other algorithms don't support this interface.
>
> The other way is
>
> auto r = arr.map!(Caller(2));
>
> But again, since it's template parameter, it can't use 
> variables unknown at compile time:
>
> uint context = ...;
> auto r = arr.map!(Caller(context)); //will not work
>
> So what's the solution? Of course besides rewriting the whole 
> std.algorithm.

Ok, so as my lambda proposition obviously doesn't work, here is 
one way that does using a templated function. There may be a way 
to make it shorter, I don't know.


     import std.conv;
     import std.stdio;

     template fun(uint context) {
         static uint withContext(uint value) {
             return value * context;
         }

         auto fun(uint[] arr) @nogc {
             return arr.map!withContext;
         }
     }

     void main(string[] args) {
         [1, 2, 3].to!(uint[])
                  .fun!2
                  .writeln;
     }



More information about the Digitalmars-d-learn mailing list