On 6/18/10, bearophile <bearophileh...@lycos.com> wrote:
> As I have said, you have to use operator overloading of the struct and some
> near-ugly code that uses the offsetof. I don't like this a lot.

D need be no uglier than C. Here's my implementation:


/* @very_unsafe */ struct TailArray(T) {
        T opIndex(size_t idx) {
                T* tmp = cast(T*) (&this) + idx;
                return *tmp;
        }

        T opIndexAssign(T value, size_t idx) {
                T* tmp = cast(T*) (&this) + idx;
                *tmp = value;
                return value;
        }
}

// And this demonstrates how to use it:

import std.contracts;
import std.c.stdlib;

struct MyString {
        size_t size;
        TailArray!(char) data; // same as char data[0]; in C

                // to show how to construct it
        static MyString* make(size_t size) {
                MyString* item = cast(MyString*) malloc(MyString.sizeof + size);
                enforce(item !is null);
                item.size = size;
                return item;
        }

        static void destroy(MyString* s) {
                free(s);
        }
}

import std.stdio;

void main() {
        MyString* str = MyString.make(5);
        scope(exit) MyString.destroy(str);

                 // assigning works same as C
        str.data[0] = 'H';
        str.data[1] = 'e';
        str.data[2] = 'l';
        str.data[3] = 'l';
        str.data[4] = 'o';

                // And so does getting
        for(int a = 0; a < str.size; a++)
                writef("%s", str.data[a]);
        writefln("");
}

Reply via email to