digitalmars.D.learn - Function hijack on selective import
- rumbu (32/32) Dec 26 2017 Is there anyway to extend an existing function to accept custom
- Adam D. Ruppe (12/12) Dec 26 2017 The mistake you're making is using a constraint when you should
- rumbu (14/26) Dec 26 2017 "Custom" is a templated struct. I cannot imagine all the
- Adam D. Ruppe (4/7) Dec 26 2017 You can specialize on templated structs generically.
- rumbu (2/9) Dec 26 2017 Thank you, Adam.
- rumbu (14/21) Jan 16 2018 Even specialized, now I have another problem:
- H. S. Teoh (8/42) Jan 16 2018 Arguably, this is a defect in Phobos. Looking at the definition of
- rumbu (3/33) Jan 16 2018 Thank you for the pull request, but the list is longer :)
Is there anyway to extend an existing function to accept custom data types? **************** Option 1 - global import of std.math import std.math; struct Custom {} int signbit(T)(T x) if (is(T == Custom)) { return 0; } Custom c; assert(signbit(c) == 0); assert(signbit(-1.0) == 1); Error: template main.signbit cannot deduce function from argument types !()(double), candidates are: main.signbit(T)(T x) if (is(T == Custom)) ******************* Option 2 - selective import of std.math import std.math : signbit; struct Custom {} int signbit(T)(T x) if (is(T == Custom)) { return 0; } Custom c; assert(signbit(c) == 0); assert(signbit(-1.0) == 1); main.signbit called with argument types (Custom) matches both: \..\src\phobos\std\math.d(5721): std.math.signbit!(Custom).signbit(Custom x) and: main.signbit!(Custom).signbit(Custom x)
Dec 26 2017
The mistake you're making is using a constraint when you should try a specialization: int signbit(T:Custom)(T x) { return 0; } That means to use this specialized function when T is Custom. Now, you just need to merge the overload sets: import std.math; alias signbit = std.math.signbit; // this merges local signbit with std.math.signbit and boom it should compile and call your version.
Dec 26 2017
On Tuesday, 26 December 2017 at 16:15:55 UTC, Adam D. Ruppe wrote:The mistake you're making is using a constraint when you should try a specialization: int signbit(T:Custom)(T x) { return 0; } That means to use this specialized function when T is Custom. Now, you just need to merge the overload sets: import std.math; alias signbit = std.math.signbit; // this merges local signbit with std.math.signbit and boom it should compile and call your version."Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them. My opinion is that the mistake is in std.math, because std.math.signbit accepts any type instead to be constrained to float types. Actually, calling std.math.signbit with any other type than float will result in compiler error because signbit expects some float traits for the provided type: int signbit(X)(X x) nogc trusted pure nothrow { alias F = floatTraits!(X); return ((cast(ubyte *)&x)[F.SIGNPOS_BYTE] & 0x80) != 0; }
Dec 26 2017
On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:"Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y)
Dec 26 2017
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:Thank you, Adam."Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y)
Dec 26 2017
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:Even specialized, now I have another problem: std.math: int signbit(X)(X x) { ... } mylibrary: int signbit(D: Decimal!bits, int bits) { ... } ============= end user: import std.math; import mylibrary; Decimal!32 d; float f; auto y = signbit(f); //ok, call to std.math.signbit auto x = signbit(d); //error, also calls std.math.signbit"Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y)
Jan 16 2018
On Tue, Jan 16, 2018 at 07:14:00PM +0000, rumbu via Digitalmars-d-learn wrote:On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:Arguably, this is a defect in Phobos. Looking at the definition of std.math.signbit, it's obvious that it's only meant to handle built-in floating-point types, yet there are no sig constraints to that effect. Fix: https://github.com/dlang/phobos/pull/6040 T -- The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:Even specialized, now I have another problem: std.math: int signbit(X)(X x) { ... } mylibrary: int signbit(D: Decimal!bits, int bits) { ... } ============= end user: import std.math; import mylibrary; Decimal!32 d; float f; auto y = signbit(f); //ok, call to std.math.signbit auto x = signbit(d); //error, also calls std.math.signbit"Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y)
Jan 16 2018
On Tuesday, 16 January 2018 at 20:30:43 UTC, H. S. Teoh wrote:On Tue, Jan 16, 2018 at 07:14:00PM +0000, rumbu viaThank you for the pull request, but the list is longer :) https://issues.dlang.org/show_bug.cgi?id=18244Even specialized, now I have another problem: std.math: int signbit(X)(X x) { ... } mylibrary: int signbit(D: Decimal!bits, int bits) { ... } ============= end user: import std.math; import mylibrary; Decimal!32 d; float f; auto y = signbit(f); //ok, call to std.math.signbit auto x = signbit(d); //error, also calls std.math.signbitArguably, this is a defect in Phobos. Looking at the definition of std.math.signbit, it's obvious that it's only meant to handle built-in floating-point types, yet there are no sig constraints to that effect. Fix: https://github.com/dlang/phobos/pull/6040 T
Jan 16 2018