www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Re: dmd 1.057 and 2.041 release

reply bearophile <bearophileHUGS lycos.com> writes:
 2) What's the best way to translate this to the new operator regime?
 
 T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) {
     return s + s;
 }

I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:"+")(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } Bye, bearophile
Mar 08 2010
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 08/03/10 22:03, bearophile wrote:
 2) What's the best way to translate this to the new operator regime?

 T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) {
      return s + s;
 }

I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init):

 T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) {
      return s + s; // line 14
 }

Untested, will the following do what you need? ---- T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } ---- Seems like you may as well test if you can add what you're passed rather than the initial value for the type.
Mar 08 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Clipsham wrote:
 On 08/03/10 22:03, bearophile wrote:
 2) What's the best way to translate this to the new operator regime?

 T foo(T)(T s) if (__traits(hasMember, T, "opAdd")) {
      return s + s;
 }

I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init):

 T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) {
      return s + s; // line 14
 }

Untested, will the following do what you need? ---- T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } ---- Seems like you may as well test if you can add what you're passed rather than the initial value for the type.

What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Andrei
Mar 08 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 What I usually do is:
 T foo(T)(T s) if (is(typeof(s + s))) {
 }

Nice, thank you, I'll use that. (That solution too presents the bug 3903) Bye, bearophile
Mar 08 2010
prev sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 08/03/10 22:53, Andrei Alexandrescu wrote:
 What I usually do is:

 T foo(T)(T s) if (is(typeof(s + s))) {
 }

 Andrei

That's far nicer, I keep forgetting about is(typeof()), thanks :)
Mar 08 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Clipsham wrote:
 On 08/03/10 22:53, Andrei Alexandrescu wrote:
 What I usually do is:

 T foo(T)(T s) if (is(typeof(s + s))) {
 }

 Andrei

That's far nicer, I keep forgetting about is(typeof()), thanks :)

It'll be hard to forget once TDPL will be out there, the idiom is present in several places. Man I can't wait for that book to be out. Andrei
Mar 08 2010
parent Robert Clipsham <robert octarineparrot.com> writes:
On 08/03/10 23:35, Andrei Alexandrescu wrote:
 Man I can't wait for that book to be out.

I suspect you're not the only one, I was filled with excitement when I saw the expected delivery date become earlier a few days ago, I'm eagerly awaiting it so I can start playing with D2 properly rather than just dabbling :)
Mar 08 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Robert Clipsham:
 Untested, will the following do what you need?
 ----
 T foo(T)(T s) if (__traits(compiles, {return s + s;})) {
       return s + s;
 }
 ----
 Seems like you may as well test if you can add what you're passed rather 
 than the initial value for the type.

Oh, nice, I didn't remember you can also use values there and not just types. It becomes like this then: import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:"+")(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug. Bye, bearophile
Mar 08 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
 But now I don't know what's happening, because that trait correctly returns
false, but the compiler generates a compile error at line 14 still. I think
there's a new bug.

I have added a bug: http://d.puremagic.com/issues/show_bug.cgi?id=3903 Bye, bearophile
Mar 08 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Philippe Sigaud:

    writeln(typeid(typeof(a.init))); // prints: int

?! You mean typeof(a) != typeof((typeof(a)).init) ?! Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.init) n times]

http://d.puremagic.com/issues/show_bug.cgi?id=3826 Bye, bearophile
Mar 08 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0015174c455cbe7b650481527e4e
Content-Type: text/plain; charset=ISO-8859-1

    writeln(typeid(typeof(a.init))); // prints: int

?! You mean typeof(a) != typeof((typeof(a)).init) ?! Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.init) n times]
    writeln(foo(a)); // test.d(14): Error: Array operation s + s not
 implemented
 }


 But now I don't know what's happening, because that trait correctly returns
 false, but the compiler generates a compile error at line 14 still. I think
 there's a new bug

I think your bug is this discrepancy between init's type and the original type. That needs a bug report by itself; in a template constraint, any value is at its type .init value, not its runtype value (obvious in retrospect) In your example {return s+s;} becomes {return 0+0;}, since the compiler wrongly infer (int[2]).init to be 0, a regular int. And your __traits return true: auto bar(T)(T t) { return __traits(compiles, {return t+t;});} int[2] a; writeln(bar(a)); // true! Philippe --0015174c455cbe7b650481527e4e Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote"><br><blockquote class=3D"gmail_quote" style=3D"m= argin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); paddin= g-left: 1ex;"><div class=3D"im"> =A0 =A0writeln(typeid(typeof(a.init))); // prints: int<br></div></blockquo= te><div><br>?! You mean typeof(a) !=3D typeof((typeof(a)).init) ?!<br><br>U= gh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.= init) n times]<br> <br>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt= 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div= class=3D"im"> =A0 =A0writeln(foo(a)); // test.d(14): Error: Array operation s + s not im= plemented<br> }<br> <br> <br> </div>But now I don&#39;t know what&#39;s happening, because that trait cor= rectly returns false, but the compiler generates a compile error at line 14= still. I think there&#39;s a new bug</blockquote><div><br>I think your bug= is this discrepancy between init&#39;s type and the original type. That ne= eds a bug report by itself;<br> <br>in a template constraint, any value is at its type .init value, not its= runtype value (obvious in retrospect)<br>In your example {return s+s;} bec= omes {return 0+0;}, since the compiler wrongly infer (int[2]).init to be 0,= a regular int.<br> And your __traits return true:<br><br><br>auto bar(T)(T t) { return __trait= s(compiles, {return t+t;});}<br><br>int[2] a;<br>writeln(bar(a)); // true!<= br><br><br>Philippe<br><br></div></div> --0015174c455cbe7b650481527e4e--
Mar 08 2010