digitalmars.D - Need runtime reflection?
- lijie <cpunion gmail.com> Jul 16 2012
- "David Piepgrass" <qwertie256 gmail.com> Jul 17 2012
- Jacob Carlborg <doob me.com> Jul 17 2012
- Jacob Carlborg <doob me.com> Jul 18 2012
- Jacob Carlborg <doob me.com> Jul 18 2012
- lijie <cpunion gmail.com> Jul 17 2012
- "Paulo Pinto" <pjmlp progtools.org> Jul 17 2012
- lijie <cpunion gmail.com> Jul 18 2012
- lijie <cpunion gmail.com> Jul 18 2012
--bcaec54ee70648411304c4f5aeef Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I want to imitate golang's interface in D, to study D's template. I wrote some code: https://gist.github.com/3123593 Now we can write code like golang: -- interface IFoo { void foo(int a, string b, float c); } struct Foo { void foo(int a, string b, float c) { writeln("Foo.foo: ", a, ", ", b, ", ", c); } } struct FooFoo { void foo(int a, string b, float c) { writeln("FooFoo.foo: ", a, ", ", b, ", ", c); } } GoInterface!(IFoo) f =3D new Foo; f.foo(3, "abc", 2.2); f =3D new FooFoo; f.foo(5, "def", 7.7); -- It is also very naive, does not support some features, like out/ref parameters, free functions *[1]* and so on. The biggest problem is downcast not supported. In golang, we can write code like*[2]*: -- var p IWriter =3D NewB(10) p2, ok :=3D p.(IReadWriter) -- Seems [p.(IReadWriter)] dynamically build a virtual table *[3]*=EF=BC=8Cbec= ause the type of "p" is IWriter, it is *smaller* than IReadWriter, the cast operation must search methods and build vtbl at run time. In D, GoInterface(T).opAssign!(V)(V v) can build a rich runtime information to *V* if we need. But if *V* is interface or base class, the type information not complete. So, seems like I need runtime reflection? and how can I do this in D? I did not find any useful information in the TypeInfo*. ------ [1] free functions support, e.g. -- interface IFoo { void foo(int a, string b, float c); } void foo(int self, int a, string b, float c) { writefln("..."); } GoInterface!(int) p =3D 1; p.foo(4, "ccc", 6.6); -- In theory no problem. [2] example from https://github.com/xushiwei/gobook/blob/master/dive-into/interface/03/inter= face.go [3] /path/of/go/src/pkg/runtime/iface.c: static Itab* itab(InterfaceType *inter, Type *type, int32 canfail) Best regards, -- Li Jie --bcaec54ee70648411304c4f5aeef Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I want to imitate golang's interface in D, to study D's template. I= wrote some code: <a href=3D"https://gist.github.com/3123593">https://gist.= github.com/3123593</a><div><br></div><div>Now we can write code like golang= :</div> --<br><div>interface IFoo {</div><div>=C2=A0 =C2=A0 void foo(int a, string = b, float c);</div><div>}</div><div><br></div><div>struct Foo {</div><div>= =C2=A0 =C2=A0 void foo(int a, string b, float c) {</div><div>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 writeln("Foo.foo: ", a, ", ", b, ", = ", c);</div> <div>=C2=A0 =C2=A0 }</div><div>}</div><div><br></div><div>struct FooFoo {</= div><div>=C2=A0 =C2=A0 void foo(int a, string b, float c) {</div><div>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 writeln("FooFoo.foo: ", a, ", "= ;, b, ", ", c);</div><div>=C2=A0 =C2=A0 }</div> <div>}</div><div><br></div><div>GoInterface!(IFoo) f =3D new Foo;</div><div=f.foo(3, "abc", 2.2);</div><div><br></div><div>f =3D new FooFoo;=
very naive, does not support some features, like out/ref parameters, free f= unctions <b>[1]</b> and so on. The biggest problem is downcast not supporte= d. In golang, we can write code like<b>[2]</b>:=C2=A0</div> <div>--<br>var p IWriter =3D NewB(10)<br>p2, ok :=3D p.(IReadWriter)<br>--<= div><br>Seems [p.(IReadWriter)] dynamically build a virtual table=C2=A0<b>[= 3]</b>=EF=BC=8Cbecause the type of "p" is IWriter, it is *smaller= * than IReadWriter, the cast operation must search methods and build vtbl a= t run time.<br> <br>In D, GoInterface(T).opAssign!(V)(V v) can build a rich runtime informa= tion to *V* if we need. But if *V* is interface or base class, the type inf= ormation not complete. So, seems like I need runtime reflection? and how ca= n I do this in D? I did not find any useful information in the TypeInfo*.</= div> <div><br></div><div>------</div><div>[1] free functions support, e.g.</div>= <div>--</div><div><div>interface IFoo {</div><div>=C2=A0 =C2=A0 void foo(in= t a, string b, float c);</div><div>}</div></div><div>void foo(int self, int= a, string b, float c) {</div> <div>=C2=A0 =C2=A0 writefln("...");</div><div>}</div><div><br></d= iv><div>GoInterface!(int) p =3D 1;</div><div>p.foo(4, "ccc", 6.6)= ;</div><div>--</div><div><span style=3D"font-family:Arial;font-size:12px;wh= ite-space:pre-wrap">In theory no problem.</span></div> <div><br></div><div>[2] example=C2=A0from <a href=3D"https://github.com/xus= hiwei/gobook/blob/master/dive-into/interface/03/interface.go">https://githu= b.com/xushiwei/gobook/blob/master/dive-into/interface/03/interface.go</a></= div> <div>[3] /path/of/go/src/pkg/runtime/iface.c:=C2=A0static Itab*=C2=A0itab(I= nterfaceType *inter, Type *type, int32 canfail)</div></div></div><div><br><= /div><div><br></div><div>Best regards,</div><div><br></div><div>-- Li Jie</= div> --bcaec54ee70648411304c4f5aeef--
Jul 16 2012
I want to imitate golang's interface in D, to study D's template. I wrote some code: https://gist.github.com/3123593 Now we can write code like golang: -- interface IFoo { void foo(int a, string b, float c); } struct Foo { void foo(int a, string b, float c) { writeln("Foo.foo: ", a, ", ", b, ", ", c); } } struct FooFoo { void foo(int a, string b, float c) { writeln("FooFoo.foo: ", a, ", ", b, ", ", c); } } GoInterface!(IFoo) f = new Foo; f.foo(3, "abc", 2.2); f = new FooFoo; f.foo(5, "def", 7.7); -- It is also very naive, does not support some features, like out/ref parameters, free functions *[1]* and so on. The biggest problem is downcast not supported. In golang, we can write code like*[2]*: -- var p IWriter = NewB(10) p2, ok := p.(IReadWriter) -- Seems [p.(IReadWriter)] dynamically build a virtual table *[3]*,because the type of "p" is IWriter, it is *smaller* than IReadWriter, the cast operation must search methods and build vtbl at run time. In D, GoInterface(T).opAssign!(V)(V v) can build a rich runtime information to *V* if we need. But if *V* is interface or base class, the type information not complete. So, seems like I need runtime reflection? and how can I do this in D? I did not find any useful information in the TypeInfo*. ------ [1] free functions support, e.g. -- interface IFoo { void foo(int a, string b, float c); } void foo(int self, int a, string b, float c) { writefln("..."); } GoInterface!(int) p = 1; p.foo(4, "ccc", 6.6); -- In theory no problem.
I, too, was enamored with Go Interfaces and implemented them for .NET: http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language And I wasn't the only one; later, someone else published another library for .NET with the exact same goal. This is definitely a feature I would want to see in D, preferably as a first-class feature, although sadly that would break any code that relies on ISomething being pointer-sized; Go uses fat pointers, and we use a thin-pointer implementation in .NET but it's inefficient (as every cast creates a heap-allocated wrapper, and double-indirection is needed to reach the real method.) Anyway, they say it's possible to build runtime reflection in D but I've no idea how... has it never been done before? Of course, runtime template instantiation won't be possible. Therefore, run-time casting will have to be more limited than compile-time casting. Reflection to free functions would be really nice, but it might be less capable at run-time. Consider if you there is a class A in third-party module MA that you want to cast to interface I, but class A is missing a function F() from I. So in your module (module MB) you define a free function F(B) and now you can do the cast. I guess realistically this can only happen at compile-time, since a run-time cast would naturally only look in module MA, not MB, for functions it could use to perform the cast. Presumably, it also requires that MA requested a run-time reflection table to be built, and is it possible to build a reflection table for a module over which you have no control?
Jul 17 2012
On 2012-07-18 06:10, lijie wrote:Free functions support is hard, with runtime cast, I just think compile time.
It's possibly to implement runtime reflection by loading the running executable and inspecting the symbol table. It's an ugly hack but it should work. http://flectioned.kuehne.cn/I am trying to support free functions at compile time, is also hard, since the generator in gointerface module, but other modules are only visible in the module that used these modules. I have an ugly implementation used compile time string mixin, trying to simplify it. Fighting.
I think you can pass a module to a template via an alias parameter. Then the template should be able to inspect all free functions using something like __traits(allMembers). -- /Jacob Carlborg
Jul 17 2012
On 2012-07-18 09:26, lijie wrote:It is an optional way. I want to do all thing in D code.
You can do this in D. -- /Jacob Carlborg
Jul 18 2012
On 2012-07-18 17:10, lijie wrote:On Wed, Jul 18, 2012 at 2:59 PM, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: I think you can pass a module to a template via an alias parameter. Then the template should be able to inspect all free functions using something like __traits(allMembers). Have a problem. -- // file: A.d module A; // functions and classes -- -- // file: testtraits.d import std.stdio; import A; void main() { writeln(__traits(allMembers, A)); } -- There is a compilation error: testtraits.d(6): Error: import A has no members If module is under a package name, it is OK, is that a bug?
Seems like it. http://d.puremagic.com/issues/ -- /Jacob Carlborg
Jul 18 2012
--14dae9cdc821784a3904c512d885 Content-Type: text/plain; charset=UTF-8 On Tue, Jul 17, 2012 at 11:08 PM, David Piepgrass <qwertie256 gmail.com>wrote:I, too, was enamored with Go Interfaces and implemented them for .NET: http://www.codeproject.com/**Articles/87991/Dynamic-** interfaces-in-any-NET-language<http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language>
Interesting, good article and project, thanks. And I wasn't the only one; later, someone else published another libraryfor .NET with the exact same goal. This is definitely a feature I would want to see in D, preferably as a first-class feature, although sadly that would break any code that relies on ISomething being pointer-sized; Go uses fat pointers, and we use a thin-pointer implementation in .NET but it's inefficient (as every cast creates a heap-allocated wrapper, and double-indirection is needed to reach the real method.)
D has powerful template and CTFE, seems we have more choices, fat pointer or thin pointer. I didn't think seriously about the performance differences. About every cast creates a heap-allocated wrapper, I think we can try to use lower cost way in D. In my code: -- void opAssign(V)(GoInterface!(V) v) if (is(V == interface)) { //pragma(msg, "assign for GoInterface"); static if (isImplicitlyConvertible!(V, T)) { //pragma(msg, V.stringof ~ " can implicitly convert to " ~ T.stringof); m_impl = v.m_impl; } else static if (isImplicitlyConvertible!(T, V)) { //pragma(msg, T.stringof ~ " can implicitly convert to " ~ V.stringof ~ ", try dynamic cast"); if (v.m_impl is null) { m_impl = null; } else { m_impl = cast(T)(v.m_impl); if (m_impl is null) { // dynamic cast failed, try dynamic proxy m_impl = buildDynamicProxy!(V)(v); } } } else { //pragma(msg, "cannot implicitly between " ~ V.stringof ~ " and " ~ T.stringof); static if (isInterfaceConvertible!(V, T)) { //pragma(msg, "generate static proxy to convert " ~ V.stringof ~ " to " ~ T.stringof); m_impl = new StaticProxy!(V)(v.m_impl); } else { //pragma(msg, V.stringof ~ " not compatible " ~ T.stringof ~ ", must dynamic build call proxy"); m_impl = buildDynamicProxy!(V)(v); } } } -- Some cases we can directly do assignment, it also can be optimized to reduce heap allocation.Anyway, they say it's possible to build runtime reflection in D but I've no idea how... has it never been done before?
Of course, runtime template instantiation won't be possible. Therefore, run-time casting will have to be more limited than compile-time casting. Reflection to free functions would be really nice, but it might be less capable at run-time. Consider if you there is a class A in third-party module MA that you want to cast to interface I, but class A is missing a function F() from I. So in your module (module MB) you define a free function F(B) and now you can do the cast. I guess realistically this can only happen at compile-time, since a run-time cast would naturally only look in module MA, not MB, for functions it could use to perform the cast. Presumably, it also requires that MA requested a run-time reflection table to be built, and is it possible to build a reflection table for a module over which you have no control?
Free functions support is hard, with runtime cast, I just think compile time. I am trying to support free functions at compile time, is also hard, since the generator in gointerface module, but other modules are only visible in the module that used these modules. I have an ugly implementation used compile time string mixin, trying to simplify it. Fighting. --14dae9cdc821784a3904c512d885 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Tue, Jul 17, 2012 at 11:08 PM, David Piepgras= s <span dir=3D"ltr"><<a href=3D"mailto:qwertie256 gmail.com" target=3D"_= blank">qwertie256 gmail.com</a>></span> wrote:<blockquote class=3D"gmail= _quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:= 1ex"> I, too, was enamored with Go Interfaces and implemented them for .NET:<br> <br> <a href=3D"http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-= any-NET-language" target=3D"_blank">http://www.codeproject.com/<u></u>Artic= les/87991/Dynamic-<u></u>interfaces-in-any-NET-language</a></blockquote><di= v> <br></div><div>Interesting, good article and project, thanks.</div><div><br=</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
someone else published another library for .NET with the exact same goal. = This is definitely a feature I would want to see in D, preferably as a firs= t-class feature, although sadly that would break any code that relies on IS= omething being pointer-sized; Go uses fat pointers, and we use a thin-point= er implementation in .NET but it's inefficient (as every cast creates a= heap-allocated wrapper, and double-indirection is needed to reach the real= method.)<br> </blockquote><div>=C2=A0</div>D has powerful template and CTFE, seems we ha= ve more choices, fat pointer or thin pointer. I didn't think seriously = about the performance differences.</div><div class=3D"gmail_quote"><br></di= v><div class=3D"gmail_quote"> About every cast creates a heap-allocated wrapper, I think we can try to us= e lower cost way in D. In my code:</div><div class=3D"gmail_quote"><br></di= v><div class=3D"gmail_quote">--</div><div class=3D"gmail_quote"><pre style= =3D"margin-top:0px;margin-bottom:0px;padding-top:0px;padding-right:0px;padd= ing-bottom:0px;padding-left:0px;font-family:'Bitstream Vera Sans Mono&#= 39;,Courier,monospace;font-size:12px;line-height:16px;text-align:left"> <div class=3D"line" id=3D"LC206" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0<spa= n class=3D"kt" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;m= argin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding= -left:0px;line-height:1.4em;color:rgb(68,85,136);font-weight:bold">void</sp= an> <span class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-botto= m:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;= padding-left:0px;line-height:1.4em">opAssign</span><span class=3D"p" style= =3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;paddi= ng-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-heigh= t:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0px= ;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddin= g-bottom:0px;padding-left:0px;line-height:1.4em">V</span><span class=3D"p" = style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;= padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-= height:1.4em">)(</span><span class=3D"n" style=3D"margin-top:0px;margin-rig= ht:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;= padding-bottom:0px;padding-left:0px;line-height:1.4em">GoInterface</span><s= pan class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;= margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddin= g-left:0px;line-height:1.4em">!(</span><span class=3D"n" style=3D"margin-to= p:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;pa= dding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">V</s= pan><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-botto= m:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;= padding-left:0px;line-height:1.4em">)</span> <span class=3D"n" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">v</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin= -bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-botto= m:0px;padding-left:0px;line-height:1.4em">)</span> <span class=3D"k" style= =3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;paddi= ng-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-heigh= t:1.4em;font-weight:bold">if</span> <span class=3D"p" style=3D"margin-top:0= px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;paddi= ng-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">(</span=<span class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0=
ding-left:0px;line-height:1.4em;font-weight:bold">is</span><span class=3D"p= " style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0p= x;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;lin= e-height:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;margin-ri= ght:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px= ;padding-bottom:0px;padding-left:0px;line-height:1.4em">V</span> <span clas= s=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-l= eft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0= px;line-height:1.4em">=3D=3D</span> <span class=3D"k" style=3D"margin-top:0= px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;paddi= ng-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em;font-wei= ght:bold">interface</span><span class=3D"p" style=3D"margin-top:0px;margin-= right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0= px;padding-bottom:0px;padding-left:0px;line-height:1.4em">))</span> <span c= lass=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margi= n-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-lef= t:0px;line-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC207" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"c1" style=3D"margin-top:0px;margin-righ= t:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;p= adding-bottom:0px;padding-left:0px;line-height:1.4em;color:rgb(153,153,136)= ;font-style:italic">//pragma(msg, "assign for GoInterface");</spa= n></div> <div class=3D"line" id=3D"LC208" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em;font-weight:bold">stati= c</span> <span class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-= bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom= :0px;padding-left:0px;line-height:1.4em;font-weight:bold">if</span> <span c= lass=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margi= n-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-lef= t:0px;line-height:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;= margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-= right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">isImplicit= lyConvertible</span><span class=3D"p" style=3D"margin-top:0px;margin-right:= 0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pad= ding-bottom:0px;padding-left:0px;line-height:1.4em">!(</span><span class=3D= "n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:= 0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;l= ine-height:1.4em">V</span><span class=3D"p" style=3D"margin-top:0px;margin-= right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0= px;padding-bottom:0px;padding-left:0px;line-height:1.4em">,</span> <span cl= ass=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin= -left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left= :0px;line-height:1.4em">T</span><span class=3D"p" style=3D"margin-top:0px;m= argin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-r= ight:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">))</span> <= span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px= ;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddi= ng-left:0px;line-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC209" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"c1" style=3D"ma= rgin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top= :0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4e= m;color:rgb(153,153,136);font-style:italic">//pragma(msg, V.stringof ~ &quo= t; can implicitly convert to " ~ T.stringof);</span></div> <div class=3D"line" id=3D"LC210" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"n" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">m_impl</span> <span class=3D"p" style=3D"margin-top:0px;margin-right:0px;= margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding= -bottom:0px;padding-left:0px;line-height:1.4em">=3D</span> <span class=3D"n= " style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0p= x;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;lin= e-height:1.4em">v</span><span class=3D"p" style=3D"margin-top:0px;margin-ri= ght:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px= ;padding-bottom:0px;padding-left:0px;line-height:1.4em">.</span><span class= =3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-le= ft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0p= x;line-height:1.4em">m_impl</span><span class=3D"p" style=3D"margin-top:0px= ;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding= -right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">;</span><= /div> <div class=3D"line" id=3D"LC211" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em">}</span></div> <div class=3D"line" id=3D"LC212" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em;font-weight:bold">else<= /span> <span class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-bo= ttom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0= px;padding-left:0px;line-height:1.4em;font-weight:bold">static</span> <span= class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;mar= gin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-l= eft:0px;line-height:1.4em;font-weight:bold">if</span> <span class=3D"p" sty= le=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;pad= ding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-hei= ght:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0= px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padd= ing-bottom:0px;padding-left:0px;line-height:1.4em">isImplicitlyConvertible<= /span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bot= tom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0p= x;padding-left:0px;line-height:1.4em">!(</span><span class=3D"n" style=3D"m= argin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-to= p:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4= em">T</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;marg= in-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bot= tom:0px;padding-left:0px;line-height:1.4em">,</span> <span class=3D"n" styl= e=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padd= ing-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-heig= ht:1.4em">V</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0p= x;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddi= ng-bottom:0px;padding-left:0px;line-height:1.4em">))</span> <span class=3D"= p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0= px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;li= ne-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC213" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"c1" style=3D"ma= rgin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top= :0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4e= m;color:rgb(153,153,136);font-style:italic">//pragma(msg, T.stringof ~ &quo= t; can implicitly convert to " ~ V.stringof ~ ", try dynamic cast= ");</span></div> <div class=3D"line" id=3D"LC214" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ;font-weight:bold">if</span> <span class=3D"p" style=3D"margin-top:0px;marg= in-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-righ= t:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">(</span><span = class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">v</span><span class=3D"p" style=3D"margin-top:0px= ;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding= -right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">.</span><= span class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px= ;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddi= ng-left:0px;line-height:1.4em">m_impl</span> <span class=3D"k" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ;font-weight:bold">is</span> <span class=3D"kc" style=3D"margin-top:0px;mar= gin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-rig= ht:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em;font-weight:bo= ld">null</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:0px;line-height:1.4em">)</span> <span class=3D"p" s= tyle=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;p= adding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-h= eight:1.4em">{</span></div> <div class=3D"line" id=3D"LC215" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">m_impl</span> <span class=3D"p" style=3D"margin-t= op:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;p= adding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">=3D= </span> <span class=3D"kc" style=3D"margin-top:0px;margin-right:0px;margin-= bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom= :0px;padding-left:0px;line-height:1.4em;font-weight:bold">null</span><span = class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">;</span></div> <div class=3D"line" id=3D"LC216" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">}</span></div> <div class=3D"line" id=3D"LC217" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ;font-weight:bold">else</span> <span class=3D"p" style=3D"margin-top:0px;ma= rgin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-ri= ght:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">{</span></di= v> <div class=3D"line" id=3D"LC218" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">m_impl</span> <span class=3D"p" style=3D"margin-t= op:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;p= adding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">=3D= </span> <span class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-b= ottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:= 0px;padding-left:0px;line-height:1.4em;font-weight:bold">cast</span><span c= lass=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margi= n-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-lef= t:0px;line-height:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;= margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-= right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">T</span><s= pan class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;= margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;paddin= g-left:0px;line-height:1.4em">)(</span><span class=3D"n" style=3D"margin-to= p:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;pa= dding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">v</s= pan><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-botto= m:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;= padding-left:0px;line-height:1.4em">.</span><span class=3D"n" style=3D"marg= in-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0= px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em"=m_impl</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;ma=
ottom:0px;padding-left:0px;line-height:1.4em">);</span></div> <div class=3D"line" id=3D"LC219" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em;font-weight:bold">if</span> <span class=3D"p" styl= e=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padd= ing-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-heig= ht:1.4em">(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0p= x;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddi= ng-bottom:0px;padding-left:0px;line-height:1.4em">m_impl</span> <span class= =3D"k" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-le= ft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0p= x;line-height:1.4em;font-weight:bold">is</span> <span class=3D"kc" style=3D= "margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-= top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1= .4em;font-weight:bold">null</span><span class=3D"p" style=3D"margin-top:0px= ;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding= -right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">)</span> = <span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0p= x;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padd= ing-left:0px;line-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC220" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0<span class=3D"c1" style=3D"margin-top:0px;margin-right:0= px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padd= ing-bottom:0px;padding-left:0px;line-height:1.4em;color:rgb(153,153,136);fo= nt-style:italic">// dynamic cast failed, try dynamic proxy</span></div> <div class=3D"line" id=3D"LC221" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0<span class=3D"n" style=3D"margin-top:0px;margin-right:0p= x;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddi= ng-bottom:0px;padding-left:0px;line-height:1.4em">m_impl</span> <span class= =3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-le= ft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0p= x;line-height:1.4em">=3D</span> <span class=3D"n" style=3D"margin-top:0px;m= argin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-r= ight:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">buildDynami= cProxy</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0px;mar= gin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bo= ttom:0px;padding-left:0px;line-height:1.4em">!(</span><span class=3D"n" sty= le=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;pad= ding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-hei= ght:1.4em">V</span><span class=3D"p" style=3D"margin-top:0px;margin-right:0= px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padd= ing-bottom:0px;padding-left:0px;line-height:1.4em">)(</span><span class=3D"= n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0= px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;li= ne-height:1.4em">v</span><span class=3D"p" style=3D"margin-top:0px;margin-r= ight:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0p= x;padding-bottom:0px;padding-left:0px;line-height:1.4em">);</span></div> <div class=3D"line" id=3D"LC222" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">}</span></div> <div class=3D"line" id=3D"LC223" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">}</span> </div> <div class=3D"line" id=3D"LC224" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em">}</span></div> <div class=3D"line" id=3D"LC225" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em;font-weight:bold">else<= /span> <span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bo= ttom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0= px;padding-left:0px;line-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC226" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"c1" style=3D"ma= rgin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top= :0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4e= m;color:rgb(153,153,136);font-style:italic">//pragma(msg, "cannot impl= icitly between " ~ V.stringof ~ " and " ~ T.stringof);</span=</div>
argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ;font-weight:bold">static</span> <span class=3D"k" style=3D"margin-top:0px;= margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-= right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em;font-weight= :bold">if</span> <span class=3D"p" style=3D"margin-top:0px;margin-right:0px= ;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;paddin= g-bottom:0px;padding-left:0px;line-height:1.4em">(</span><span class=3D"n" = style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;= padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-= height:1.4em">isInterfaceConvertible</span><span class=3D"p" style=3D"margi= n-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0p= x;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">= !(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-= bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom= :0px;padding-left:0px;line-height:1.4em">V</span><span class=3D"p" style=3D= "margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-= top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1= .4em">,</span> <span class=3D"n" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:0px;line-height:1.4em">T</span><span class=3D"p" st= yle=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;pa= dding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-he= ight:1.4em">))</span> <span class=3D"p" style=3D"margin-top:0px;margin-righ= t:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;p= adding-bottom:0px;padding-left:0px;line-height:1.4em">{</span></div> <div class=3D"line" id=3D"LC228" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"c1" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;mar= gin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-l= eft:0px;line-height:1.4em;color:rgb(153,153,136);font-style:italic">//pragm= a(msg, "generate static proxy to convert " ~ V.stringof ~ " = to " ~ T.stringof);</span></div> <div class=3D"line" id=3D"LC229" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">m_impl</span> <span class=3D"p" style=3D"margin-t= op:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;p= adding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">=3D= </span> <span class=3D"k" style=3D"margin-top:0px;margin-right:0px;margin-b= ottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:= 0px;padding-left:0px;line-height:1.4em;font-weight:bold">new</span> <span c= lass=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margi= n-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-lef= t:0px;line-height:1.4em">StaticProxy</span><span class=3D"p" style=3D"margi= n-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0p= x;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">= !(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-= bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom= :0px;padding-left:0px;line-height:1.4em">V</span><span class=3D"p" style=3D= "margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-= top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1= .4em">)(</span><span class=3D"n" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:0px;line-height:1.4em">v</span><span class=3D"p" st= yle=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;pa= dding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-he= ight:1.4em">.</span><span class=3D"n" style=3D"margin-top:0px;margin-right:= 0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pad= ding-bottom:0px;padding-left:0px;line-height:1.4em">m_impl</span><span clas= s=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-l= eft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0= px;line-height:1.4em">);</span></div> <div class=3D"line" id=3D"LC230" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">}</span></div> <div class=3D"line" id=3D"LC231" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"k" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ;font-weight:bold">else</span> <span class=3D"p" style=3D"margin-top:0px;ma= rgin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-ri= ght:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">{</span></di= v> <div class=3D"line" id=3D"LC232" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"c1" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;mar= gin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-l= eft:0px;line-height:1.4em;color:rgb(153,153,136);font-style:italic">//pragm= a(msg, V.stringof ~ " not compatible " ~ T.stringof ~ ", mus= t dynamic build call proxy");</span></div> <div class=3D"line" id=3D"LC233" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span = class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;marg= in-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-le= ft:0px;line-height:1.4em">m_impl</span> <span class=3D"p" style=3D"margin-t= op:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;p= adding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">=3D= </span> <span class=3D"n" style=3D"margin-top:0px;margin-right:0px;margin-b= ottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:= 0px;padding-left:0px;line-height:1.4em">buildDynamicProxy</span><span class= =3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;margin-le= ft:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0p= x;line-height:1.4em">!(</span><span class=3D"n" style=3D"margin-top:0px;mar= gin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-rig= ht:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">V</span><span= class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;mar= gin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-l= eft:0px;line-height:1.4em">)(</span><span class=3D"n" style=3D"margin-top:0= px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;paddi= ng-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em">v</span=<span class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0=
ding-left:0px;line-height:1.4em">);</span></div> <div class=3D"line" id=3D"LC234" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"mar= gin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:= 0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:1.4em= ">}</span></div> <div class=3D"line" id=3D"LC235" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0<span class=3D"p" style=3D"margin-top:0px;margin-right= :0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;pa= dding-bottom:0px;padding-left:0px;line-height:1.4em">}</span></div> <div class=3D"line" id=3D"LC236" style=3D"margin-top:0px;margin-right:0px;m= argin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-= bottom:0px;padding-left:1em;line-height:1.4em">=C2=A0=C2=A0=C2=A0=C2=A0<spa= n class=3D"p" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px;ma= rgin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-= left:0px;line-height:1.4em">}</span></div> </pre></div><div class=3D"gmail_quote">--</div><div class=3D"gmail_quote"><= br></div>Some cases we can directly do assignment, it also can be optimized= to reduce heap allocation.<div class=3D"gmail_quote"><div>=C2=A0</div><blo= ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c= cc solid;padding-left:1ex"> <br> Anyway, they say it's possible to build runtime reflection in D but I&#= 39;ve no idea how... has it never been done before?=C2=A0</blockquote><bloc= kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc= c solid;padding-left:1ex"> <br> Of course, runtime template instantiation won't be possible. Therefore,= run-time casting will have to be more limited than compile-time casting.<b= r> <br> Reflection to free functions would be really nice, but it might be less cap= able at run-time. Consider if you there is a class A in third-party module = MA that you want to cast to interface I, but class A is missing a function = F() from I. So in your module (module MB) you define a free function F(B) a= nd now you can do the cast. I guess realistically this can only happen at c= ompile-time, since a run-time cast would naturally only look in module MA, = not MB, for functions it could use to perform the cast. Presumably, it also= requires that MA requested a run-time reflection table to be built, and is= it possible to build a reflection table for a module over which you have n= o control?<br> </blockquote><div><br></div><div>Free functions support is hard, with runti= me cast, I just think compile time.</div><div><br></div><div>I am trying to= =C2=A0support free functions at=C2=A0compile time, is also hard, since the = generator in gointerface module, but other modules are only visible in the = module that used these modules. I have an ugly implementation used compile = time string mixin, trying to simplify it. Fighting.</div> <div><br></div></div> --14dae9cdc821784a3904c512d885--
Jul 17 2012
On Tuesday, 17 July 2012 at 15:08:18 UTC, David Piepgrass wrote:I want to imitate golang's interface in D, to study D's template. I wrote some code: https://gist.github.com/3123593 Now we can write code like golang: -- interface IFoo { void foo(int a, string b, float c); } struct Foo { void foo(int a, string b, float c) { writeln("Foo.foo: ", a, ", ", b, ", ", c); } } struct FooFoo { void foo(int a, string b, float c) { writeln("FooFoo.foo: ", a, ", ", b, ", ", c); } } GoInterface!(IFoo) f = new Foo; f.foo(3, "abc", 2.2); f = new FooFoo; f.foo(5, "def", 7.7); -- It is also very naive, does not support some features, like out/ref parameters, free functions *[1]* and so on. The biggest problem is downcast not supported. In golang, we can write code like*[2]*: -- var p IWriter = NewB(10) p2, ok := p.(IReadWriter) -- Seems [p.(IReadWriter)] dynamically build a virtual table *[3]*,because the type of "p" is IWriter, it is *smaller* than IReadWriter, the cast operation must search methods and build vtbl at run time. In D, GoInterface(T).opAssign!(V)(V v) can build a rich runtime information to *V* if we need. But if *V* is interface or base class, the type information not complete. So, seems like I need runtime reflection? and how can I do this in D? I did not find any useful information in the TypeInfo*. ------ [1] free functions support, e.g. -- interface IFoo { void foo(int a, string b, float c); } void foo(int self, int a, string b, float c) { writefln("..."); } GoInterface!(int) p = 1; p.foo(4, "ccc", 6.6); -- In theory no problem.
I, too, was enamored with Go Interfaces and implemented them for .NET: http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language
Interesting article, but why not just make use of "dynamic" interfaces? -- Paulo
Jul 17 2012
--bcaec54ee706c76bcc04c5159387 Content-Type: text/plain; charset=UTF-8 On Wed, Jul 18, 2012 at 2:59 PM, Jacob Carlborg <doob me.com> wrote:On 2012-07-18 06:10, lijie wrote: Free functions support is hard, with runtime cast, I just think compiletime.
It's possibly to implement runtime reflection by loading the running executable and inspecting the symbol table. It's an ugly hack but it should work. http://flectioned.kuehne.cn/
It is an optional way. I want to do all thing in D code.I am trying to support free functions at compile time, is also hard,since the generator in gointerface module, but other modules are only visible in the module that used these modules. I have an ugly implementation used compile time string mixin, trying to simplify it. Fighting.
I think you can pass a module to a template via an alias parameter. Then the template should be able to inspect all free functions using something like __traits(allMembers).
I didn't know this usage, I will try it. Thanks. --bcaec54ee706c76bcc04c5159387 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wed, Jul 18, 2012 at 2:59 PM, Jacob Carlborg <span dir=3D"ltr"><<a hr= ef=3D"mailto:doob me.com" target=3D"_blank">doob me.com</a>></span> wrot= e:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D= "margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div class=3D"im">On 2012-07-18 06:10, lijie wrote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Free functions support is hard, with runtime cast, I just think compile<br> time.<br> </blockquote> <br></div> It's possibly to implement runtime reflection by loading the running ex= ecutable and inspecting the symbol table. It's an ugly hack but it shou= ld work.<br> <br> <a href=3D"http://flectioned.kuehne.cn/" target=3D"_blank">http://flectione= d.kuehne.cn/</a></blockquote><div><br></div><div>It is an optional way. I w= ant to do all thing in D code.</div><div>=C2=A0</div><blockquote class=3D"g= mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l= eft:1ex"> <div class=3D"im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I am trying to support free functions at compile time, is also hard,<br> since the generator in gointerface module, but other modules are only<br> visible in the module that used these modules. I have an ugly<br> implementation used compile time string mixin, trying to simplify it.<br> Fighting.<br> </blockquote> <br></div> I think you can pass a module to a template via an alias parameter. Then th= e template should be able to inspect all free functions using something lik= e __traits(allMembers).</blockquote><div><br></div><div>I didn't know t= his usage, I will try it. Thanks.</div> </div><br> --bcaec54ee706c76bcc04c5159387--
Jul 18 2012
--14dae9cdc821c7402404c51c1196 Content-Type: text/plain; charset=UTF-8 On Wed, Jul 18, 2012 at 2:59 PM, Jacob Carlborg <doob me.com> wrote:I think you can pass a module to a template via an alias parameter. Then the template should be able to inspect all free functions using something like __traits(allMembers).
-- // file: A.d module A; // functions and classes -- -- // file: testtraits.d import std.stdio; import A; void main() { writeln(__traits(allMembers, A)); } -- There is a compilation error: testtraits.d(6): Error: import A has no members If module is under a package name, it is OK, is that a bug? --14dae9cdc821c7402404c51c1196 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wed, Jul 18, 2012 at 2:59 PM, Jacob Carlborg <span dir=3D"ltr"><<a hr= ef=3D"mailto:doob me.com" target=3D"_blank">doob me.com</a>></span> wrot= e:<div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar= gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I think you can pass a module to a template via an alias parameter. Then th= e template should be able to inspect all free functions using something lik= e __traits(allMembers).<br><span class=3D"HOEnZb"><font color=3D"#888888"><= br> </font></span></blockquote><div><br></div><div>Have a problem.</div><div><b= r></div><div>--</div><div>// file: A.d</div><div><br></div><div>module A;</= div><div><br></div><div>// functions and classes</div><div>--</div><div> <br></div><div>--</div><div>// file: testtraits.d=C2=A0</div><div><br></div=<div>import std.stdio;</div><div>import A;</div></div><div><br></div><div>=
}</div> <div>--</div><div><br></div><div>There is a compilation error:</div><div><d= iv>testtraits.d(6): Error: import A has no members</div></div><div><br></di= v><div>If module is under a package name, it is OK, is that a bug?=C2=A0</d= iv> <div><br></div> --14dae9cdc821c7402404c51c1196--
Jul 18 2012









Jacob Carlborg <doob me.com> 