Qualifier parameters (inout on steroids)
Tomer Filiba via Digitalmars-d
digitalmars-d at puremagic.com
Thu Sep 29 05:53:47 PDT 2016
`inout` is a useful feature, but it's nearly impossible to
actually use it. Suppose I have
struct MyTable {
@property items() inout {
return Range(&this);
}
static struct Range {
MyTable* table; // can't be inout
}
}
I want my items-range to be const if `this` is const or
modifiable if `this` is modifiable. I ended up with
@property items() {
return Range!false(&this);
}
@property items() const {
return Range!true(&this);
}
static struct Range(bool isConst) {
static if (isConst) {
const(MyTable)* table;
} else {
MyTable* table;
}
}
Also, I can't define the struct inside the `items` method since
it's used in two other methods (`keys` and `values`), only they
hold a different `front`
It would be really nice if I could "capture" the qualifiers and
be parameterized on them as well. For example,
int opApply(qual Q)(scope int delegate(int x) Q dg) Q;
Meaning, my opApply is Q if dg is Q. In other words, I'm
`nothrow` if dg is `nothrow`, I'm `@nogc` if dg is `@nogc`, I'm
`pure` if dg is `pure`, etc. Inout is just a special case of this
feature, e.g.
int opApply(qual Q)(scope int delegate(Q int x) dg) Q;
E.g., I'm const if dg takes a const first parameter. So using my
first example,
@property items(qual Q)() Q {
return Range!Q(&this);
}
static struct Range(qual Q) {
Q(MyTable)* table;
}
Much more elegant and concise. It needn't generate different
object code for instantiations of course, it only needs to be
respected by the frontend and thrown away later.
-tomer
More information about the Digitalmars-d
mailing list