Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over dlang struct

Tags:

iteration

d

I have a struct that looks something like this:

struct MultipartMessage {
    ubyte[] mime, data;
    Header header;

    void setSender(string sender) {
        header.sender = sender;
    }
    void setId(int id) {
        header.id = id;
    }
}

and I would like to iterate over it, in another class with something like this:

struct Socket {
    ...

    void send(MultipartMessage msg) {
        foreach (part; msg) {
            sendPart(part);
        }
    }

    ...
}

Is this possible? I'd like to use something analogous to Python's __iter__ in the MultipartMessage that can return the fields in a specific order, and ideally even run some additional code, like header.serialize().

Ideally I would add a function to MultipartMessage that would look something like this (pseudocode):

ubyte[] __iter__() {
    yield mime;
    yield data;
    yield header.serialize(); //header.serialize returns a ubyte[]
}
like image 628
Charles L. Avatar asked Nov 30 '15 23:11

Charles L.


1 Answers

Use tupleof:

foreach (ref part; msg.tupleof)
    sendPart(part);

This will call sendPart with mime, data and header (the struct's fields, in the order they were declared). You can filter fields by checking their type with e.g. static if (!is(typeof(part) == Header)).

To get the field's name, you can use __traits(identifier):

foreach (i, ref part; msg.tupleof)
    writeln(__traits(identifier, msg.tupleof[i]));

(__traits(identifier, part) would return part.)

There's also __traits(allMembers), which also returns methods.

like image 190
Vladimir Panteleev Avatar answered Nov 17 '22 13:11

Vladimir Panteleev