StructOfArrays.d
2. 4. 2021 #kód
import std.traits; import std.conv; import std.string : replace; struct StructOfArrays(T) if (is(T == struct)) { private static forEachField(string code) { string res; static foreach (field; FieldNameTuple!T) { res ~= code.replace("$f", field); } return res; } mixin(forEachField(q{ typeof(T.$f)[] $f; })); struct FakeItem { ulong i; StructOfArrays* soa; mixin(forEachField(q{ auto $f() { return soa.$f[i]; } })); string toString() { string res = fullyQualifiedName!T ~ "("; mixin(forEachField(q{ res ~= $f.to!string ~ ", "; })); return res[0 .. $-2] ~ ")"; } T convertToT() { T res; mixin(forEachField(q{ res.$f = $f; })); return res; } alias convertToT this; } ulong length() { return mixin((FieldNameTuple!T)[0]).length; } void reserve(ulong l) { mixin(forEachField(q{ $f.reserve(l); })); } void length(ulong l) { mixin(forEachField(q{ $f.length = l; })); } auto opIndex(ulong i) { return FakeItem(i, &this); } auto opIndexAssign(U)(U x, ulong i) if (is(U == T) || is(U == FakeItem)) { mixin(forEachField(q{ $f[i] = x.$f; })); } auto opOpAssign(alias op)(T x) if (op == "~") { mixin(forEachField(q{ $f ~= x.$f; })); } }