Indeed the ref can be applied to the return type:
http://dlang.org/function.html#ref-functions

So, does the following code copy any data from "nodes"?
If that is the case this solution avoids the "class" storage, avoids pointers and "nodes" is encapsulated as read-only, that's great. The program I'm working on is still incomplete, so I still can't benchmark it to compare with all proposed solutions.

@safe:
import std.stdio;
import std.string;

struct Node {
        Node[] block;
        uint num = 0;
};

immutable uint LAST = -1;
Node[] default_nodes = [
        {num:3},
        {block:[{num:4},{num:6},{block:[{num:5},{num:7}]}]},
        // ...
        {num:LAST},
];

class NodeProvider{
        // change to const after constructor
        private Node[] nodes;

        private void parse_file(char[] file_name){
                // initialize nodes from file
                for(auto i=0; i<3; i++){
                        nodes.length++;
                        nodes[$-1].num=i;
                }
                nodes.length++;
                nodes[$-1].num=LAST;
        }

        this(){
                nodes = default_nodes;
        }
        this(char[] file_name){
                parse_file(file_name);
        }

        ref const(Node) get_node(const uint index){
                return nodes[index];
        }
}

string NodetoString(ref const(Node) n){
        string str = format("%u{ ", n.num);
        foreach(b;n.block)
                str ~= NodetoString(b);
        str ~= "} ";
        return str;
}

@system: // for writeln
int main(char[][] args){
        NodeProvider np;
        uint i;

        if(args.length==2)
                np = new NodeProvider(args[1]);
        else
                np = new NodeProvider();

        for(i=0;;i++){
                const(Node) node = np.get_node(i);
                if(node.num==LAST)
                        break;
                writeln(NodetoString(node));
        }
        return 0;
}

Reply via email to