Re: adding delegate to opApply

2019-09-03 Thread berni via Digitalmars-d-learn

On Monday, 2 September 2019 at 14:20:11 UTC, Paul Backus wrote:

If you have an existing delegate that you want to use with 
opApply, the easiest way is like this:


void delegate(Thing) myDelegate = ...;

foreach(thing; things) {
myDelegate(thing);
}
// Equivalent to: things.opApply((Thing t) => myDelegate(t))


Thanks for your answer. It's not exactly, what I was looking for, 
but meanwhile I think, the whole idea was not reasonable. I 
meanwhile returned to using a normal function call instead of 
opApply, which makes it easy to pass a delegate as one of the 
parameters.


Re: adding delegate to opApply

2019-09-02 Thread Paul Backus via Digitalmars-d-learn

On Monday, 2 September 2019 at 12:43:31 UTC, berni wrote:
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.)


The delegate that gets passed to opApply is constructed from the 
body of the foreach loop; you don't (normally) pass it explicitly.


If you have an existing delegate that you want to use with 
opApply, the easiest way is like this:


void delegate(Thing) myDelegate = ...;

foreach(thing; things) {
myDelegate(thing);
}
// Equivalent to: things.opApply((Thing t) => myDelegate(t))


adding delegate to opApply

2019-09-02 Thread berni via Digitalmars-d-learn
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.