Qualifier parameters (inout on steroids)
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Thu Sep 29 06:23:55 PDT 2016
On 9/29/16 8:53 AM, Tomer Filiba wrote:
> `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.
Yes, this is a problem -- but not with inout. This is a problem with the
lack of tail modifier syntax.
Observe how this works if Range is really a dynamic array:
@property inout(T)[] items() inout {
return theItems; // a dynamic array
}
Works just fine. What we need is a way to say tailinout(Range), which
means that the table member is mutable, but points at inout data.
> I ended up with
>
> @property items() {
> return Range!false(&this);
> }
> @property items() const {
> return Range!true(&this);
> }
There is a way to make this more DRY, but it is still ugly, and loses
the benefits of inout. You need to use template this parameters:
struct Range(T)
{
T *table;
}
@property items(this T)() {
return Range!T(&this);
}
> 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;
I once thought this would work well, but in practice I think it would be
a disaster. Imagine everyone defining their own set of qualifiers and
how they will work.
It's also a template, and does not protect against modification of
mutable data, or static if to change layout/implementation/etc.
I am working on an article to propose a tail modifier syntax. This would
solve most of these problems.
-Steve
More information about the Digitalmars-d
mailing list