Hello I would like to define my own class collection, and make it iterable in a foreach statement, just like this :
public class Collection(Type)
{
...
private T head;
private Collection!(T) queue;
}
Collection!(int) temp;
foreach (int t; temp) { ... }
What methods should I define, and how ?
you can specify the front
, popfront()
and empty
functions: (but this will consume your collection unless you 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 a dedicated struct 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;
}
}
}
so iteration is done like so
Collection!(int) temp; foreach (int t;temp[]) { ... }
you also can add an opApply
for the normal 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;
}
Take a look at this documentation on ForeachStatements and scroll down a bit.
If I'm reading your example correctly, you could define an 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;
}
Your Collection class should implement opApply. Your foreach body becomes a delegate to an internal for loop, and you iterate over your internal collection (in your case a queue) using a for loop.
Consider the example given 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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With