digitalmars.D.learn - Defining type coercion
- Peter Lundgren (8/8) Feb 27 2011 I'd like to define a type Ordinal which behaves like an int (using a str...
- Bekenn (14/22) Feb 27 2011 I haven't tried anything like this yet (I'm still pretty new to D), but
- Jonathan M Davis (25/36) Feb 27 2011 You can use opCast, but it's only for _explicit_ casting. You can use al...
- Simen kjaeraas (16/28) Feb 27 2011 The D Programming Language (the book by Andrei) mentions that multiple
- Jonathan M Davis (4/36) Feb 27 2011 Would "alias getChar this" really be legal? I thought that this had to b...
- Simen kjaeraas (4/16) Feb 28 2011 Alias function this; works.
I'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.
Feb 27 2011
On 2/27/2011 12:10 PM, Peter Lundgren wrote:I'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.I haven't tried anything like this yet (I'm still pretty new to D), but I think something like this is the best you'll be able to do: struct Ordinal { this(int value) { m_Value = value; } this(dchar ch) { m_Value = ch - 'a' + 1; } // add range checks as appropriate alias this m_Value; T opCast(T)() if (T is dchar) { return m_Value + 'a' - 1; } // add more operators as appropriate private: int m_Value; }
Feb 27 2011
On Sunday 27 February 2011 12:10:43 Peter Lundgren wrote:I'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.You can use opCast, but it's only for _explicit_ casting. You can use alias this for implicit casting, but that's not going to work very well with primitive types, because you can't derive from them and therefore can't override their behavior. Also, you can't currently have more than one alias this per type (though you're supposed to be able to eventually). So, you could easily create a type which holds an integral value of some kind and only allows the values 1 - 26, inclusive. You can make it so that functions on it take ints or chars or whatever. You can define opCast to cast to whatever types you want. But you _can't_ make it implicitly convertible to or from primitive types and have _any_ control over the conversion (since alias this with a primitive type gives you no control over it). But then again, you can't convert implicitly between chars and ints either unless value range propogation tells the compiler that the conversion that you're trying to do will fit, and that's generally restricted to literals in local context. As soon as you do anything like pass a variable to function, that information is lost and you're going to have to cast explicitly. So, while you _can_ implicitly cast from a char to an int, you can't generally do so from an int to a char, so your type would be just as implicitly castable as chars and ints except that you wouldn't be able to cast from it to an int implicitly. D really isn't designed with allowing you to define a type which acts like other types without casts (unless you're dealing with polymorphism). C++ allows all kinds of implicit conversions that D explicitly disallows in order to avoid bugs. - Jonathan M Davis
Feb 27 2011
Peter Lundgren <lundgrpb rose-hulman.edu> wrote:I'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.The D Programming Language (the book by Andrei) mentions that multiple alias this be a possibility. Sadly, it has not yet found its way its way into the actual implementation of the language. With it, one would define what you ask for, approximately like this: struct Ordinal { private int representation; char getChar( ) { return representation + 'a'-1; } alias representation this; alias getChar this; } But like I said, it currently does not work. -- Simen
Feb 27 2011
On Sunday 27 February 2011 21:57:26 Simen kjaeraas wrote:Peter Lundgren <lundgrpb rose-hulman.edu> wrote:Would "alias getChar this" really be legal? I thought that this had to be aliased to a type. - Jonathan M DavisI'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.The D Programming Language (the book by Andrei) mentions that multiple alias this be a possibility. Sadly, it has not yet found its way its way into the actual implementation of the language. With it, one would define what you ask for, approximately like this: struct Ordinal { private int representation; char getChar( ) { return representation + 'a'-1; } alias representation this; alias getChar this; } But like I said, it currently does not work.
Feb 27 2011
Jonathan M Davis <jmdavisProg gmx.com> wrote:Alias function this; works. -- Simenstruct Ordinal { private int representation; char getChar( ) { return representation + 'a'-1; } alias representation this; alias getChar this; } But like I said, it currently does not work.Would "alias getChar this" really be legal? I thought that this had to be aliased to a type.
Feb 28 2011