Jump to page: 1 2
Thread overview
Re: dmd 1.057 and 2.041 release
Mar 08, 2010
bearophile
Mar 08, 2010
Robert Clipsham
Mar 08, 2010
bearophile
Mar 08, 2010
Robert Clipsham
Mar 08, 2010
Robert Clipsham
Mar 08, 2010
bearophile
Mar 08, 2010
bearophile
Mar 08, 2010
Philippe Sigaud
Mar 08, 2010
bearophile
March 08, 2010
> 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
March 08, 2010
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):
-snip-
> 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.
March 08, 2010
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):
> -snip-
>> 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
March 08, 2010
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
March 08, 2010
> 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
March 08, 2010
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
March 08, 2010
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 :)
March 08, 2010
>    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


March 08, 2010
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
March 08, 2010
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
« First   ‹ Prev
1 2