0xDEADBEEF

RSS odkazy english edition

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; }));
  }
}
píše k47 (@kaja47, k47)