opIndexMember

claptrap clap at trap.com
Sun Dec 27 14:46:43 UTC 2020


In some cases a structure of arrays is more desirable than an 
array of structs, usually for performance reasons, but maybe you 
want tight packing or something else, so I have been thinking a 
while about proposing the following...

auto opIndexMember!(string what)(size_t idx);

So basically if opIndexMember is defined for Foo then...

foo[i].x

Is rewritten to..

foo.opIndexMember!("x")(i);

So you can do stuff like this....

struct Vector { float x,y,z; }

struct VecArray
{
      float[] _x;
      float[] _y;
      float[] _z;

     auto opIndexMember(string what)(size_t idx)
     {
         static if (what = "x") return _x[idx];
         else static if (what = "y") return _y[idx];
         else static if (what = "z") return _z[idx];
         else static if (what = "magitude") return
             sqrt(sqr(_x[idx])+sqr(_y[idx])+sqr(_z[idx]));
         else static if (what = "") return Vector(_x{idx], 
_y[idx], _z[idx]);

         static assert(0);
     }
}

So you can use that either as a structure of arrays, or an array 
of structs. And with introspection and UDAs you could probably 
have an array class that automatically enumerates members of the 
struct, stores as SOA internally, but provides a AOS API.

Im thinking maybe disallow having both opIndex and opIndexMember 
defined, if you use array op but with no trailing member it just 
passes an empty string. Might reduce ambiguity?







More information about the Digitalmars-d mailing list