Overloading the foreach statement in d programming language

Hello, I would like to define my own set of classes and make it iterable in the foreach statement, like this:

public class Collection(Type) { ... private T head; private Collection!(T) queue; } Collection!(int) temp; foreach (int t; temp) { ... } 

What methods should be determined and how?

+6
source share
3 answers

you can specify the functions front , popfront() and empty : (but this will consume your collection if you do not use save ())

 public class Collection(T) { ... private T head; private Collection!(T) queue; @property T front(){ return head; } @property bool empty(){ return queue is null; } void popfront(){ head = queue.head; queue = queue.queue; } Collection!T save(){ return new Collection!T(head,queue); } } 

or use the selected structure for iteration (as is done in the std.container module

 public class Collection(T) { ... private T head; private Collection!(T) queue; Range opSlice(){ return Range(head,queue); } struct Range{ T h; Collection!(T) q; this(T he, Collection!(T) qu){ h=he; q=qu; } @property T front(){ return h; } @property bool empty(){ return q is null; } void popfront(){ h = q.head; q= q.queue; } Collection!T save(){ return this; } } } 

therefore iteration is performed like this:

 Collection!(int) temp; foreach (int t;temp[]) { ... } 

you can also add opApply for regular foreach:

 public int opApply(int delegate(ref T) dg){ int res=0; foreach(ref T;this[]){ res = dg(t); if(res)return res; } return res; } 
+9
source

Take a look at the documentation on ForeachStatements and scroll through the page a bit.

If I read your example correctly, you can define opApply for Collection as follows:

 public int opApply(int delegate(ref T) dg){ Collection!T p = this; int res = 0; while(!res && p !is null){ res = dg(p.head); p = p.queue; } return res; } 
+4
source

The Collection class must implement opApply. Your foreach body becomes a delegate to the inner for loop, and you iterate over your inner collection (in your case, the queue) using the for loop.

Consider the example provided in the docs

 class Foo { uint array[2]; int opApply(int delegate(ref uint) dg) { int result = 0; for (int i = 0; i < array.length; i++) { result = dg(array[i]); if (result) break; } return result; } } 
+3
source

Source: https://habr.com/ru/post/907392/


All Articles