New operators opStaticIndex and friends
Q. Schroll
qs.il.paperinik at gmail.com
Tue May 14 15:49:51 UTC 2019
I whish, D has these operators:
opStaticIndex
opStaticIndexAssign
opStaticIndexOpAssign
opStaticSlice
When used, they look the same way as opIndex and friends, but the
stuff between [ and ] would be bound to template parameters
(instead of runtime parameters) and be known at compile time.
Basically, this allows to implement static indexing the same way
it is possible for an AliasSeq.
Furthermore, it is possible to have static and dynamic indexing
next to each other. This is supported by static-size arrays (e.g.
int[3]) only: https://run.dlang.io/is/99g01e
Implementing e.g. tuple-like structures, it would be valuable to
have both. Dynamic indexing would only be present (design by
introspection) if the contents support it.
struct S
{
enum int opStaticIndex(int index) = index + 1;
int opIndex(int index) { return index + 1; }
enum size_t[2] opStaticSlice(size_t i, size_t j) = [ i, j ];
void opStaticIndexAssign(int index)(int value);
void opStaticIndexAssign(int i, int j)(int value);
void opStaticIndexAssign(size_t[2] slice)(int value);
void opStaticIndexOpAssign(string op, int index)(int value);
}
S s;
int i = s[0]; // rewrites to s.opStaticIndex!(0), as 0 can be
used for the template parameter
int j = s[i]; // rewrites to s.opIndex(i), as i cannot be read
at compile-time
The "Static" variants would be preferred when determining which
one to lower to.
s[0] = 1; // rewrites to s.opStaticIndexAssign!(0)(1)
s[0, 2] = 1; // rewrites to s.opStaticIndexAssign!(0, 2)(1)
s[0 .. 2] = 1; // rewrites to
s.opStaticIndexAssign!(s.opStaticSlice!(0, 2))(1)
s[0] += 1; // rewrites to s.opStaticIndexOpAssign!("+", 0)(1)
s[0, 2] += 1; // rewrites to s.opStaticIndexOpAssign!("+", 0,
2)(1)
Currently, there is no way to implement custom compile-time
indexing. Only using alias-this to an AliasSeq can do something,
but is very limited. The alias-this is shadowed by any presence
of opIndex.
An alternative would be a `static` or `enum` storage class for
function runtime parameters that only bind to values known at
compile-time.
These have been proposed years ago and would not only solve this
but also format!"fmt" vs. format(fmt) and friends.
I have no knowledge about the DMD implementation, but I'd
intuitively expect that new operator rewrites would be much less
work to implement.
Do you want it? Do you see problems? Should I clarify something?
Is it worth writing a DIP?
More information about the Digitalmars-d
mailing list