www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Make all functions from std.typecons "Proxy" inout

reply "Namespace" <rswhite4 googlemail.com> writes:
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.
May 08 2012
parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
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
May 08 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
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 ();}
May 08 2012
parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
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
May 09 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
Can you explain me how TemplateThisParameter works? I read in the
manual but a more detail explanation would help me a lot.
May 10 2012
next sibling parent "Kagamin" <spam here.lot> writes:
Looks like it infers the declaring type's modifiers.
May 10 2012
prev sibling parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
On Thursday, 10 May 2012 at 07:32:42 UTC, Namespace wrote:
 Can you explain me how TemplateThisParameter works? I read in 
 the
 manual but a more detail explanation would help me a lot.
Hmm, I have thought following code should work about foo, but doesn't. import std.stdio; struct Proxy { void foo(this T)() { writeln(T.stringof); static assert(is(typeof(this) == T)); // I have thought this should pass with all cases... } void bar(this T)() inout { writeln(T.stringof); //static assert(is(typeof(this) == T)); static assert(is(typeof(this) == inout(Proxy))); } void bar(this T)() shared inout { writeln(T.stringof); //static assert(is(typeof(this) == T)); static assert(is(typeof(this) == shared(inout(Proxy)))); } } void main() { Proxy mp; const Proxy cp; immutable Proxy ip; shared Proxy sp; shared const Proxy scp; mp.foo(); // expects: Proxy -> OK /+ cp.foo(); // expects: const(Proxy) -> NG! ip.foo(); // expects: immutable(Proxy) -> NG! sp.foo(); // expects: shared(Proxy) -> NG! scp.foo(); // expects: shared(const(Proxy)) -> NG! +/ mp.bar(); // expects: Proxy -> OK cp.bar(); // expects: const(Proxy) -> OK ip.bar(); // expects: immutable(Proxy) -> OK sp.bar(); // expects: shared(Proxy) -> OK scp.bar(); // expects: shared(const(Proxy)) -> OK } The spec: http://dlang.org/template#TemplateThisParameter doesn't talk about typeof(this). I think current behavior is less useful than I have thought. And, current std.typecons.Proxy doesn't work as expected for non-mutable objects...
May 10 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 05/11/2012 08:56 AM, Kenji Hara wrote:
 The spec:
 http://dlang.org/template#TemplateThisParameter
 doesn't talk about typeof(this).

 I think current behavior is less useful than I have thought.
What would the current behavior be useful for?
 And, current std.typecons.Proxy doesn't work as expected for non-mutable
 objects...
Until now, I actually thought that template this parameters work the way as you expected them to work.
May 11 2012
prev sibling parent reply sclytrack <sclytrack iq87.fr> writes:
 struct S
 {
 void f() {}
 void f() const{}
 void f() immutable {}
 void f() shared {}
 void f() shared const {}
 }
 struct Proxy(T)
 {
 T o;
I'm new to the concept of "shared const". What is the difference when comparing to "immutable"?
May 11 2012
parent reply sclytrack <sclytrack iq87.fr> writes:
On 05/11/2012 11:51 AM, sclytrack wrote:
 struct S
 {
 void f() {}
 void f() const{}
 void f() immutable {}
 void f() shared {}
 void f() shared const {}
 }
 struct Proxy(T)
 {
 T o;
I'm new to the concept of "shared const". What is the difference when comparing to "immutable"?
And to answer myself. import std.stdio; void test1(shared const float [] p) { writeln("works"); } int main() { writeln("--"); shared(const(int)) a; const(shared(int)) b; immutable int c; writeln(typeof(a).stringof); writeln(typeof(b).stringof); writeln(typeof(c).stringof); writeln("--"); shared(const(int []) []) aa; shared(immutable(int []) []) ab; writeln(typeof(aa).stringof); writeln(typeof(ab).stringof); writeln("--"); const(shared(int []) []) ba; immutable(shared(int []) []) bb; writeln(typeof(ba).stringof); writeln(typeof(bb).stringof); writeln("--"); shared float [] sm = new shared(float[10]); test1(sm); immutable float [] im = new immutable(float[10]); test1(im); return 0; } -- shared(const(int)) shared(const(int)) immutable(int) -- shared(const(int[])[]) shared(immutable(int[])[]) -- const(shared(int[])[]) immutable(int[][]) -- works works
May 11 2012
parent reply sclytrack <sclytrack iq87.fr> writes:
 import std.stdio;

 void test1(shared const float [] p)
 {
 writeln("works");
 }
Nope, "shared const" still doesn't make sense to me. In the above example the p values can still change at any time. Why does "shared const" even exist?
May 11 2012
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 11 May 2012 08:05:33 -0400, sclytrack <sclytrack iq87.fr> wrote:

 import std.stdio;

 void test1(shared const float [] p)
 {
 writeln("works");
 }
Nope, "shared const" still doesn't make sense to me. In the above example the p values can still change at any time. Why does "shared const" even exist?
shared means it can be possibly accessed by other threads const means you can't change it through this reference *but* another reference could change the values it points at. Combine both, and you will realize that it could possibly be changing *as you use it*. Why do you think we don't need it? -Steve
May 11 2012