Can opCmp return a 'long' instead of 'int'?
Hello, The call signature for opCmp in a struct is: struct S { int opCmp(ref const S s) const { ... } } int opCmp(ref const S s) const { return _val - s._val; } This works fine if _val is 'int'. However, if _val is 'long' then subtracting 2 longs may not result in an int - and therefore I would have to replace the subtraction above with 2 comparison operators. My question is: Can I rewrite opCmp to return a 'long', like: struct S { long opCmp(ref const S s) const { return _val - s.val; } } This does compile and run correctly, but are there any hidden assumptions or requirements on the return value of opCmp that I should be aware of? Is there any reason that doing this may be not be wise? Thanks, Saurabh
Re: Can opCmp return a 'long' instead of 'int'?
On 02/16/2014 02:59 PM, Saurabh Das wrote: This does compile and run correctly, but are there any hidden assumptions or requirements on the return value of opCmp that I should be aware of? Is there any reason that doing this may be not be wise? No, this is fine.
Re: Can opCmp return a 'long' instead of 'int'?
On 02/16/2014 04:13 PM, Timon Gehr wrote: On 02/16/2014 02:59 PM, Saurabh Das wrote: This does compile and run correctly, but are there any hidden assumptions or requirements on the return value of opCmp that I should be aware of? Is there any reason that doing this may be not be wise? No, this is fine. To be more precise: Returning long is fine. The subtraction trick does not work in general regardless of return type: import std.stdio; struct S{ int d; int opCmp(S r){ return d - r.d; } } void main(){ assert(S(1)S(2)); // passes. ok. assert(S(int.min)S(int.max)); // passes. oops. }
Re: Can opCmp return a 'long' instead of 'int'?
Timon Gehr: assert(S(1)S(2)); // passes. ok. assert(S(int.min)S(int.max)); // passes. oops. A possible solution is to add to Phobos (unless it's already there) a variadic templated funcion cmpBuilder() that accepts an even number of arguments, that are seen as pairs. Usage example: struct Foo { int x, y; string s; int opCmp(in ref Foo r) { return cmpBuilder(x, r.x, y.abs, r.y.abs, s, r.s); } } Is this worth adding to Phobos? Bye, bearophile
Re: Can opCmp return a 'long' instead of 'int'?
On 02/16/2014 04:40 PM, bearophile wrote: Timon Gehr: assert(S(1)S(2)); // passes. ok. assert(S(int.min)S(int.max)); // passes. oops. A possible solution is to add to Phobos (unless it's already there) a variadic templated funcion cmpBuilder() that accepts an even number of arguments, that are seen as pairs. Usage example: struct Foo { int x, y; string s; int opCmp(in ref Foo r) { return cmpBuilder(x, r.x, y.abs, r.y.abs, s, r.s); } } Is this worth adding to Phobos? Bye, bearophile IMO no (lots of repetition), but forwarding opCmp is: struct Foo{ int x,y; string s; private @property order(){ return tuple(x, abs(y), s); } mixin OrderBy!order; } Furthermore, the language should be updated such that the built-in types are not special w.r.t. operators. Eg: 1.opBinary!+(2) 1.opCmp(2) should work. The following should be supported as well: struct Foo{ int x,y; string s; mixin OrderBy!(()=tuple(x, abs(y), s)); } (Currently DMD bans function literals as members.)
Re: Can opCmp return a 'long' instead of 'int'?
On Sunday, 16 February 2014 at 15:19:08 UTC, Timon Gehr wrote: On 02/16/2014 04:13 PM, Timon Gehr wrote: On 02/16/2014 02:59 PM, Saurabh Das wrote: This does compile and run correctly, but are there any hidden assumptions or requirements on the return value of opCmp that I should be aware of? Is there any reason that doing this may be not be wise? No, this is fine. To be more precise: Returning long is fine. The subtraction trick does not work in general regardless of return type: import std.stdio; struct S{ int d; int opCmp(S r){ return d - r.d; } } void main(){ assert(S(1)S(2)); // passes. ok. assert(S(int.min)S(int.max)); // passes. oops. } Right. I didn't expect that! So I shouldn't use it anyway. Thanks! Saurabh