www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why doesn't to!MyEnumType(42) work

reply "Tommi" <tommitissari hotmail.com> writes:
According to the docs, std.conv.to uses cast operator under the 
hood, and since the following works:

enum MyEnumType {a}
auto val = cast(MyEnumType) 42;

...it seems natural that to!MyEnumType(42) should work as well. 
But currently it gives error:
template instance std.conv.to!(MyEnumType).to!(int) error 
instantiating
Jul 16 2012
next sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Monday, 16 July 2012 at 17:35:33 UTC, Tommi wrote:
 According to the docs, std.conv.to uses cast operator under the 
 hood, and since the following works:

 enum MyEnumType {a}
 auto val = cast(MyEnumType) 42;

 ...it seems natural that to!MyEnumType(42) should work as well. 
 But currently it gives error:
 template instance std.conv.to!(MyEnumType).to!(int) error 
 instantiating

You can convert a enum to an int, but not the other way around. Enums are not a 'range', rather a bunch of const values with a tag stating it's type. Let's check against your example with a little modification. enum MyEnumType { none, a = 100 } //so far so good int i = MyEnumType.a; //success MyEnumType x = MyEnumType.a; //success, so far so good. MyEnumType y = cast(MyEnumType) 42; //Error: wtf is 42 anyways? MyEnumType z = cast(MyEnumType) 100; //Error: an int is not an enum! (Even if it's a valid match) // although... assert(x == 100); //enum converts to int. assert(x == i); assert(x == MyenumType.a); These may seem like strict rules, and there may be cases where a combination of flags are valid, but setting an invalid state in a fixed range of 'const' values doesn't work. I suppose the same thing could be compared to an enum being a set of car keys, and every proper enum value is a car key, but when you give something that's not a car key (Say, a brick) then it isn't going to fit, not matter how hard you try to force it into the key hole. Enums with fixed values (and a number of them) are good for flags and limited ID types. It also allows you as TDPL gives an example where you can make a statement that handles ALL possible values. with(MyEnumType) { final switch(x) { //of type MyEnumType. ALL possibilities MUST be present case none: //something case a: //something else //no possible 42 value here, no matter how hard you try; //and since we handle all cases, default should not be used } }
Jul 16 2012
parent travert phare.normalesup.org (Christophe Travert) writes:
"Era Scarecrow" , dans le message (digitalmars.D:172568), a écrit :
 On Monday, 16 July 2012 at 21:59:17 UTC, Tommi wrote:
 On Monday, 16 July 2012 at 20:22:12 UTC, Era Scarecrow wrote:
 MyEnumType y = cast(MyEnumType) 42; //Error: wtf is 42 anyways?

Like the previous fellow said, it's not an error.

I had the impression it was illegal by the compiler; Logically forcing an enum to an invalid state is probably undefined and unstable (but casting with compile-time constant that's provably correct would be different). Also I've never tried force casting the enums, so.. Hmmm... I suppose 'use at your own risk' applies here.

For what it's worth, I think cast should be at your own risk, and to!MyEnumType should assert the enum is valid.
Jul 17 2012
prev sibling next sibling parent "cal" <callumenator gmail.com> writes:
On Monday, 16 July 2012 at 20:22:12 UTC, Era Scarecrow wrote:
  You can convert a enum to an int, but not the other way around.

  MyEnumType z = cast(MyEnumType) 100; //Error: an int is not an 
 enum! (Even if it's a valid match)

I do this all the time.... enum E { A = 100, B = 200 } E e = cast(E) 100 ; // works fine... Maybe I misunderstood? The problem is that here int is not _implicitly_ convertible to the enum. For example, if you write your own template without any constraints: T to(T, S)(S i) { return cast(T)i; } then: E e = to!E(100); // works, but is not safe
Jul 16 2012
prev sibling next sibling parent "cal" <callumenator gmail.com> writes:
On Monday, 16 July 2012 at 21:00:00 UTC, cal wrote:
 On Monday, 16 July 2012 at 20:22:12 UTC, Era Scarecrow wrote:
 You can convert a enum to an int, but not the other way around.

 MyEnumType z = cast(MyEnumType) 100; //Error: an int is not an 
 enum! (Even if it's a valid match)

I do this all the time.... enum E { A = 100, B = 200 } E e = cast(E) 100 ; // works fine... Maybe I misunderstood? The problem is that here int is not _implicitly_ convertible to the enum. For example, if you write your own template without any constraints: T to(T, S)(S i) { return cast(T)i; } then: E e = to!E(100); // works, but is not safe

actually ignore that bit about implicit conversion, that's probably not "the problem"
Jul 16 2012
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
On Monday, 16 July 2012 at 20:22:12 UTC, Era Scarecrow wrote:
  MyEnumType y = cast(MyEnumType) 42; //Error: wtf is 42 anyways?

Like the previous fellow said, it's not an error. To me that line of code says: "let's assign to MyEnumType variable y some value that's not valid (as type MyEnumType defines the word valid)". I think it's very useful to be able to assign values which are unambiguously invalid, like NaN to float, 0xFF to char or some undefined value to enum. Sadly, with integral types there's no such value that could be seen as invalid. And to reiterate my point: If the call: to!MyEnum(42) ...is supposed to be (and this I gather from the docs) under the hood the same as: cast(MyEnum) 42 ...which works, then, logically, to!MyEnum(42) should also work.
Jul 16 2012
prev sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Monday, 16 July 2012 at 21:59:17 UTC, Tommi wrote:
 On Monday, 16 July 2012 at 20:22:12 UTC, Era Scarecrow wrote:
 MyEnumType y = cast(MyEnumType) 42; //Error: wtf is 42 anyways?

Like the previous fellow said, it's not an error.

I had the impression it was illegal by the compiler; Logically forcing an enum to an invalid state is probably undefined and unstable (but casting with compile-time constant that's provably correct would be different). Also I've never tried force casting the enums, so.. Hmmm... I suppose 'use at your own risk' applies here.
Jul 16 2012