data-oriented struct abstraction ?
Michael Coulombe via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun May 31 18:25:41 PDT 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"));
}
More information about the Digitalmars-d-learn
mailing list