View mode: basic / threaded / horizontal-split · Log in · Help
July 16, 2012
Why doesn't to!MyEnumType(42) work
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
July 16, 2012
Re: Why doesn't to!MyEnumType(42) work
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
 }
}
July 16, 2012
Re: Why doesn't to!MyEnumType(42) work
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
July 16, 2012
Re: Why doesn't to!MyEnumType(42) work
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"
July 16, 2012
Re: Why doesn't to!MyEnumType(42) work
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.
July 16, 2012
Re: Why doesn't to!MyEnumType(42) work
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.
July 17, 2012
Re: Why doesn't to!MyEnumType(42) work
"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.
Top | Discussion index | About this forum | D home