Make all functions from std.typecons "Proxy" inout

Kenji Hara k.hara.pg at gmail.com
Wed May 9 19:20:23 PDT 2012


On Wednesday, 9 May 2012 at 06:42:09 UTC, Namespace wrote:
> On Wednesday, 9 May 2012 at 04:49:39 UTC, Kenji Hara wrote:
>> On Tuesday, 8 May 2012 at 22:58:07 UTC, Namespace wrote:
>>> In my development of the Ref / NotNull structure, I came 
>>> across a
>>> problem: All the methods of "Proxy" aren't "inout". Has this a
>>> reason or will change? In my opinion they should all be 
>>> "inout".
>>> I mentioned previous self fixes in my corresponding "Ref /
>>> NotNull" thread already.
>>
>> It is necessary. See following conceptual code:
>>
>> struct S
>> {
>>    void f() {}
>>    void g() {}
>> }
>> struct Proxy(T)
>> {
>>    T o;
>>    void f()() inout { return o.f(); }
>>    void g(this T)() { return o.g(); }
>> }
>> void main()
>> {
>>    Proxy!S p;
>>    //p.f();  // inside Proxy.f, typeof(o) == inout
>>    p.g();
>> }
>>
>> 'Proxy' object should forward its 'this' type to original 
>> object.
>> For the purpose, TemplateThisParameter ('this T') works as 
>> expected.
>>
>> Kenji Hara
>
> I thought, "inout" is evaluated by the compiler and make the 
> method either const or not
> If not, then I understand, "inout" probably not yet complete.
> But in this case you would have to offer just two methods:
> void f () () {return o.f ();}
> void f () () const {return o.f ();}

Yes. *In this case*, we should define two member function 'f' in 
Proxy to forward the call to original object. But, in general 
case, it is not sufficient.

struct S
{
     void f() {}
     void f() const{}
     void f() immutable {}
     void f() shared {}
     void f() shared const {}
}
struct Proxy(T)
{
     T o;

     // forward to original f, need *five* thunks. Terrible!
     void f1()()              { return o.f(); }
     void f1()() const        { return o.f(); }
     void f1()() immutable    { return o.f(); }
     void f1()() shared       { return o.f(); }
     void f1()() shared const { return o.f(); }

     // cannot forward, this calls only S.f() const
     void f2()() inout { return o.f(); }

     // needs only one thunk. Excellent!
     void f3(this T)() { return o.g(); }
}
void main()
{
     Proxy!S p;
     p.f1();  // call mutable f
     p.f2();  // CANNOT call mutable f
     p.f3();  // call mutable f
}

My first version of Proxy had such duplicates, but it was hard 
maintainable.
After that, in review phase, I've discovered the way using 
TemplateThisParameter. It makes code readable and easy 
maintainable.

After all, it is the reason why I use TempalteThisParameter 
instead of inout.

Kenji Hara


More information about the Digitalmars-d-learn mailing list