SListRange, Ranges, costructors

bearophile bearophileHUGS at lycos.com
Sun Apr 11 20:02:14 PDT 2010


To answers a question in D.learn I've written a minimal single-linked list. This is one version (D2 code):


import std.stdio;

struct List(T) {
    static struct Node {
        T data;
        Node* next;
        this(T d, Node* p) {
            data = d;
            next = p;
        }
    }

    Node* lh;

    this(T[] arr) {
        foreach_reverse (el; arr)
            lh = new Node(el, lh);
    }

    Node* p;
    void reset() { p = lh; } // is reset necessary?
    bool empty() { return !p; }
    T front() { return p.data; }
    void popFront() { p = p.next; }

/*
    static struct ListIterable {
        Node* p;
        bool empty() { return !p; }
        T front() { return p.data; }
        void popFront() { p = p.next; }
    }
    ListIterable opSlice() {
        return ListIterable(lh);
    }
*/
}

void main() {
    List!int items = [1, 2, 3];
    items.reset;
    foreach (x; items)
        write(x, " ");
}


This code has suggested me three questions/musings:

1) I've seen that the Node struct inside std.range.SListRange is not a static struct, is it a small bug?

2) In that List(T) I've used the Range protocol. But I've had to add a reset() function too. Isn't it useful for foreach() to call a function similar to reset() (if present) at the begin of the iteration, to set the variables necessary for the iteration? Is something like this already present with another name in the Range protocol?

3) The stack initalization of a struct has some built-in sugar, while to allocate the struct on the stack you need a this() method:

struct Node {
    int data;
    Node* next;
    this(int d, Node* p) {
        data = d;
        next = p;
    }
}
void main() {
    Node n = Node(10, null); // OK
    Node* pn = new Node(10, null); // OK
}


So is it possible to add to D2 a standard costructor for the heap allocation version too, with the same syntax? (Such default costructor must be absent if any other costructor is defined in the struct/union):

struct Node {
    int data;
    Node* next;
}
struct Foo {
    int data;
    Foo* next;
    this(int d, Foo* p) {
        data = d;
        next = p;
    }
}
void main() {
    Node* pn1 = new Node(10); // OK
    Node* pn2 = new Node(10, null); // OK
    Foo* pf = new Foo(10); // Error, standard initializer this(int) is absent.
}

Bye,
bearophile



More information about the Digitalmars-d mailing list