www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.conv: conversion from ulong to enum

reply "Matej Nanut" <matejnanut gmail.com> writes:
Hi everyone,

I hope I'm not misunderstanding the spec when this won't compile:

---
import std.conv;
enum Test { a = 0 }
void main() {
     ulong l = 0;
     auto t = l.to!Test;
}
---

It doesn't compile due to the template not instantiating.

If l is an int, uint or byte, it compiles fine.  I'm assuming the 
fault lies in the ‘is(S : OriginalType!T)’ constraint.

So, um, is this intended behaviour?  And why are string enums not 
supported? Wouldn't the ‘==’ operator work just fine on them too 
(so the function body would stay the same)?

Thanks,
Matej
Aug 22 2013
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/23/13, Matej Nanut <matejnanut gmail.com> wrote:
 It doesn't compile due to the template not instantiating.

It's likely a bug just like in Issue 6893[1], where this won't compile: ----- import std.stdio; enum E3 : ulong { A, B, C }; void main() { writeln(E3.C); } ----- [1] : http://d.puremagic.com/issues/show_bug.cgi?id=6893
Aug 22 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/22/13 3:48 PM, Matej Nanut wrote:
 Hi everyone,

 I hope I'm not misunderstanding the spec when this won't compile:

 ---
 import std.conv;
 enum Test { a = 0 }
 void main() {
      ulong l = 0;
      auto t = l.to!Test;
 }
 ---

 It doesn't compile due to the template not instantiating.

 If l is an int, uint or byte, it compiles fine.  I'm assuming the fault
 lies in the ‘is(S : OriginalType!T)’ constraint.

 So, um, is this intended behaviour?  And why are string enums not
 supported? Wouldn't the ‘==’ operator work just fine on them too (so the
 function body would stay the same)?

 Thanks,
 Matej

Hrm, that's a bug. Could you please submit to d.puremagic.com/issues? Thanks, Andrei
Aug 22 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/22/13 5:00 PM, Andrei Alexandrescu wrote:
 On 8/22/13 3:48 PM, Matej Nanut wrote:
 Hi everyone,

 I hope I'm not misunderstanding the spec when this won't compile:

 ---
 import std.conv;
 enum Test { a = 0 }
 void main() {
      ulong l = 0;
      auto t = l.to!Test;
 }
 ---

 It doesn't compile due to the template not instantiating.

 If l is an int, uint or byte, it compiles fine.  I'm assuming the fault
 lies in the ‘is(S : OriginalType!T)’ constraint.

 So, um, is this intended behaviour?  And why are string enums not
 supported? Wouldn't the ‘==’ operator work just fine on them too (so the
 function body would stay the same)?

 Thanks,
 Matej

Hrm, that's a bug. Could you please submit to d.puremagic.com/issues? Thanks, Andrei

Never mind, I see we track it already. Andrei
Aug 22 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Aug 22, 2013 at 05:00:38PM -0700, Andrei Alexandrescu wrote:
 On 8/22/13 5:00 PM, Andrei Alexandrescu wrote:
On 8/22/13 3:48 PM, Matej Nanut wrote:
Hi everyone,

I hope I'm not misunderstanding the spec when this won't compile:

---
import std.conv;
enum Test { a = 0 }
void main() {
     ulong l = 0;
     auto t = l.to!Test;
}
---

It doesn't compile due to the template not instantiating.

If l is an int, uint or byte, it compiles fine.  I'm assuming the fault
lies in the ‘is(S : OriginalType!T)’ constraint.

So, um, is this intended behaviour?  And why are string enums not
supported? Wouldn't the ‘==’ operator work just fine on them too (so the
function body would stay the same)?

Thanks,
Matej

Hrm, that's a bug. Could you please submit to d.puremagic.com/issues? Thanks, Andrei

Never mind, I see we track it already.

Actually, I just fixed issue 6893: https://github.com/D-Programming-Language/phobos/pull/1504 but the OP's code still doesn't work. This modified version does, though: import std.conv; enum Test : ulong { a = 0 } void main() { ulong l = 0; auto t = l.to!Test; } The reason is that ulong doesn't implicitly convert to int, which is the default base type of enum. Whether to() *should* attempt the conversion is a different matter, though. I think we should still file a separate bug for this (issue 6893 is a similar bug with the same ulong > int conversion issue, but the fix doesn't address this particular problem). T -- Computers are like a jungle: they have monitor lizards, rams, mice, c-moss, binary trees... and bugs.
Aug 22 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/23/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 to!() is used for save conversions

I meant safe.
Aug 22 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/23/13, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:
 Whether to() *should* attempt the conversion
 is a different matter, though.

to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example: byte x = to!byte(int.max); std.conv.ConvOverflowException conv.d(1335): Conversion positive overflow
Aug 22 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Aug 23, 2013 at 03:37:11AM +0200, Andrej Mitrovic wrote:
 On 8/23/13, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:
 Whether to() *should* attempt the conversion
 is a different matter, though.

to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example: byte x = to!byte(int.max); std.conv.ConvOverflowException conv.d(1335): Conversion positive overflow

Alright, opened a new bug for this: http://d.puremagic.com/issues/show_bug.cgi?id=10874 T -- It is the quality rather than the quantity that matters. -- Lucius Annaeus Seneca
Aug 22 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Aug 22, 2013 at 06:54:45PM -0700, H. S. Teoh wrote:
 On Fri, Aug 23, 2013 at 03:37:11AM +0200, Andrej Mitrovic wrote:
 On 8/23/13, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:
 Whether to() *should* attempt the conversion
 is a different matter, though.

to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example: byte x = to!byte(int.max); std.conv.ConvOverflowException conv.d(1335): Conversion positive overflow

Alright, opened a new bug for this: http://d.puremagic.com/issues/show_bug.cgi?id=10874

And now it's fixed: https://github.com/D-Programming-Language/phobos/pull/1505 Turned out to be another signature constraint wrong-assumption bug. Makes me wonder how many more such bugs lurk in Phobos. This isn't the first time I've seen the signature constraints test for something, then the code uses something else that doesn't necessarily follow from the signature constraints. This is an especially inviting trap to fall into when you have nice syntactic sugar like isIntegral or is(A : B); you start reasoning in the abstract and overlook the concrete details, like ulong not being implicitly convertible to int. T -- The best compiler is between your ears. -- Michael Abrash
Aug 22 2013
prev sibling parent "Matej Nanut" <matejnanut gmail.com> writes:
Well, that was fast! I'm glad it's fixed. :)
Aug 23 2013