adding delegate to opApply

berni someone at somewhere.com
Mon Sep 2 12:43:31 UTC 2019


I've tried to make a small example, but it's not easy to get this 
reduced further. At least I didn't manage. The following program 
can also be found at https://run.dlang.io/is/p6l7xN

void main()
{
     auto foo = Ways([Way([8,2,3,0]),Way([4,6,2]),Way([4,7,2,6])]);

     foo.remove_odds();

     assert(foo==Ways([Way([8, 2]), Way([4, 6, 2]), Way([4]), 
Way([0]), Way([2, 6])]));
}

struct Ways
{
     Way[] ways;

     void remove_odds()
     {
         Way[] new_ways;

         foreach (ref way;ways)
             foreach (point, void delegate(void delegate(Way way)) 
remove;way)
                 if (point%2==1)
                     remove(delegate(Way way) {new_ways ~= way;});

         ways ~= new_ways;
     }
}

struct Way
{
     int[] points;

     auto opApply(int delegate(int, void delegate(void 
delegate(Way way))) work)
     {
         size_t[] remove;
         void delegate(Way) add_new_way;

         foreach (index,point;points)
             if (auto result=work(point,(void delegate(Way) 
anw){remove~=index; add_new_way=anw;}))
                 return result;

         import std.algorithm.sorting: sort;
         foreach (index;remove.sort!("a>b"))
         {
             add_new_way(Way(points[index+1..$]));
             points = points[0..index];
         }

         return 0;
     }
}

I need to pass the delegate add_new_way somehow to opApply. Here 
I managed this, by adding this delegate to the remove-delegate 
and safe it away for further use. This works, because if remove 
is never called, add_new_way is not used either. But it's a 
little bit awkward. Is there a better way, to achieve this? (Note 
1: In the real world, point%2==1 is a more complex function call. 
Note 2: The order of elements in Way[] way doesn't matter, if 
that makes things easier.)

Maybe it's possible to work with something like 
std.algorithm.iteration.splitter instead of those loops and 
opApply. But splitter takes an element or a range, not a 
predicate.


More information about the Digitalmars-d-learn mailing list