digitalmars.D.learn - Custom type creation guidelines
- rumbu (27/27) Jan 06 2016 Let's suppose that I want to implement a custom arithmetic type.
- John Colvin (13/38) Jan 07 2016 It depends, do you want to do it all in one function? It's up to
Let's suppose that I want to implement a custom arithmetic type. Looking through phobos at Complex, BigInt, HalfFloat, Variant, etc, there is no consistent or idiomatic way to implement various operators or functions on custom types. 1) Regarding unary operator overloading, what's the best way to implement them? auto ref opUnary(string op)() if (op == "+") { ... } auto ref opUnary(string op : "+")() if (op == "+") { ... } auto ref opUnary(string op)() { static if (op == "+") { } else ... } 2) Regarding binary operator overloading, question 1 apply also, but there is more: what's the best signature? ref T opBinary(string op, T)(auto const ref T rhs) { ... } inout(T) opBinary(string op, T)(inout(T) rhs) { ... } ref T opBinary(string op, T)(T rhs) { ... } 3) Regarding comparison operators: - is there a way to have the same result for != and == (similar to float nans) - is there a way to return the same result for <, <=, >=, > (similar to float nans) - is there a way to overload float comparison operators? 4) regarding casting: - we have opCast(T) to convert my custom type to type T. Is there any method to overload the casting operation from a built in type, e.g. cast(MyType)(int)? 5) Any other guidelines? Thanks.
Jan 06 2016
On Wednesday, 6 January 2016 at 18:38:50 UTC, rumbu wrote:Let's suppose that I want to implement a custom arithmetic type. Looking through phobos at Complex, BigInt, HalfFloat, Variant, etc, there is no consistent or idiomatic way to implement various operators or functions on custom types. 1) Regarding unary operator overloading, what's the best way to implement them? auto ref opUnary(string op)() if (op == "+") { ... } auto ref opUnary(string op : "+")() if (op == "+") { ... } auto ref opUnary(string op)() { static if (op == "+") { } else ... }It depends, do you want to do it all in one function? It's up to the author to decide. using `:` or `if` doesn't matter here.2) Regarding binary operator overloading, question 1 apply also, but there is more: what's the best signature? ref T opBinary(string op, T)(auto const ref T rhs) { ... } inout(T) opBinary(string op, T)(inout(T) rhs) { ... } ref T opBinary(string op, T)(T rhs) { ... }Whatever works for your particular types and expresses the behaviour you want. I would suggest that returning by ref from opBinary is weird, but maybe you want/need that. Maybe your comparisons require modifying both objects, maybe they don't. There's no straightforward answer here.3) Regarding comparison operators: - is there a way to have the same result for != and == (similar to float nans)That's not how it works: assert ((float.nan != float.nan) == !(float.nan == float.nan));- is there a way to return the same result for <, <=, >=, > (similar to float nans)Hmmm... not sure about that. nans are a pain.- is there a way to overload float comparison operators?I thought those were deprecated?4) regarding casting: - we have opCast(T) to convert my custom type to type T. Is there any method to overload the casting operation from a built in type, e.g. cast(MyType)(int)?Don't think so. Perhaps we need an opCastFrom.
Jan 07 2016