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