June 01, 2015
On Saturday, 30 May 2015 at 15:06:16 UTC, short2cave wrote:
> Yes, kind of. The template should be able to generate the accessors using the fields of the struct passed as template argument. But also a special accessor wich returns all the items accessors, in a structured way:
>
>
> ---
> struct Model
> {
>    uint a, b;
> }
>
> template Structured(T)
> {
>     alias Structured = ...;
> }
> ---
>
> allowing things like:
> ---
> Structured!Model sm;
>
> sm[0].a = 0;
> sm[0].b = 0;
> auto item = sm[0];
> sm.a = 0;
> sm.pushBack;
> auto item = sm.back;
> sm.length += 1,
> ---
> etc.

Proof of concept:

import std.stdio, std.string, std.typetuple, std.traits, std.container;
private auto genIndexerCode(string[] memberNames) {
    enum f = `@property auto ref %s() { return __parent.members[%s][__index]; }`;
    string s = "";
    foreach(i, member ; memberNames) {
        s ~= format(f, member, i);
    }
    return s;
}
class ArrayOf(S) if (is(S == struct) && !isNested!S) {
private:
    alias memberNames = FieldNameTuple!S;
    alias memberTypes = FieldTypeTuple!S;
    staticMap!(Array, memberTypes) members;
    static struct Indexer {
    private:
        ArrayOf!S __parent;
        size_t __index;
    public:
        S __get() {
            S copy;
            foreach(member ; memberNames) {
                mixin(`copy.%s = this.%s;`.format(member,member));
            }
            return copy;
        }
        alias __get this;
        void opAssign(S src) {
            foreach(member ; memberNames) {
                mixin(`this.%s = src.%s;`.format(member,member));
            }
        }
        mixin(genIndexerCode([memberNames]));
    }
public:
    this() {}
    auto opIndex(size_t i) {
        return Indexer(this, i);
    }
    void insertBack(S s) {
        foreach(i, mem ; memberNames) {
            mixin(`members[%s].insertBack(s.%s);`.format(i, mem));
        }
    }
}
struct Test {
    int x;
    string y;
}
unittest {
    auto aos = new ArrayOf!Test();
    aos.insertBack(Test(5, "hi"));
    aos[0].x = -7;
    aos.insertBack(Test.init);
    aos[1] = Test(11,"boo");
    assert(aos[0] == Test(-7,"hi"));
    assert(aos[1] == Test(11,"boo"));
}
June 01, 2015
Justin Whear pretty much nailed it, I think. What I would really like to see is some benchmarks.
1 2
Next ›   Last »