digitalmars.D.learn - Widening a type
- Doctor J (25/25) Apr 16 2009 OK, here's one for you that sounds like it ought to be easy, but I don't...
- Daniel Keep (27/58) Apr 16 2009 The error tells you everything you need to know if you read it.
- BCS (3/9) Apr 16 2009 I known what you are saying but that didn't read right to me: An if as a...
- Jarrett Billingsley (2/7) Apr 16 2009 else *static* if(is(T: double))
- Denis Koroskin (13/40) Apr 17 2009 I would avoid mixin in such situation and use template instead:
- bearophile (22/26) Apr 17 2009 A solution using my dlibs:
OK, here's one for you that sounds like it ought to be easy, but I don't immediately see how to do it in a pretty way. Given a type parameter T of a template: If T is an integral type, I want to declare a variable 'widest' of type ulong; If T is a floating-point type, I want to declare a variable 'widest' of type double. And it has to be prettier than my solution. :) static if (is (T: ulong)) ulong widest = 0; else if (is (T: double)) double widest = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; Now, I thought this sounds like a great job for a mixin: template Widen (T, alias varname) { static if (is (T: ulong)) ulong varname = 0; else if (is (T: double)) double varname = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; } mixin Widen!(T, widest); ...but alas, "Declaration expected, not 'if'". Help?
Apr 16 2009
Doctor J wrote:OK, here's one for you that sounds like it ought to be easy, but I don't immediately see how to do it in a pretty way. Given a type parameter T of a template: If T is an integral type, I want to declare a variable 'widest' of type ulong; If T is a floating-point type, I want to declare a variable 'widest' of type double. And it has to be prettier than my solution. :) static if (is (T: ulong)) ulong widest = 0; else if (is (T: double)) double widest = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; Now, I thought this sounds like a great job for a mixin: template Widen (T, alias varname) { static if (is (T: ulong)) ulong varname = 0; else if (is (T: double)) double varname = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; } mixin Widen!(T, widest); ....but alas, "Declaration expected, not 'if'". Help?The error tells you everything you need to know if you read it. Actually, you have two problems: you're trying to use "if" where you should be using "static if", and you can't alias a symbol name then use it in a declaration. Here's a fixed, expanded version. template Widen (T, char[] varname) { static if (is (T: ulong)) { mixin(`ulong `~varname~` = 0;`); } else { static if (is (T: double)) { mixin(`double `~varname~` = 0.0`); } else { static assert (false, "Unimplmented type " ~ T.stringof); } } } You can remove those braces, I just wanted to point out that putting "static" out the front of an "if" doesn't magically make the "else" branch static as well. -- Daniel
Apr 16 2009
Hello Daniel,You can remove those braces, I just wanted to point out that putting "static" out the front of an "if" doesn't magically make the "else" branch static as well.I known what you are saying but that didn't read right to me: An if as a static if's else clause is not magically a static if.-- Daniel
Apr 16 2009
On Thu, Apr 16, 2009 at 10:11 PM, Doctor J <nobody nowhere.com> wrote:template Widen (T, alias varname) { static if (is (T: ulong)) ulong varname = 0; else if (is (T: double))else *static* if(is(T: double))
Apr 16 2009
On Fri, 17 Apr 2009 06:11:00 +0400, Doctor J <nobody nowhere.com> wrote:OK, here's one for you that sounds like it ought to be easy, but I don't immediately see how to do it in a pretty way. Given a type parameter T of a template: If T is an integral type, I want to declare a variable 'widest' of type ulong; If T is a floating-point type, I want to declare a variable 'widest' of type double. And it has to be prettier than my solution. :) static if (is (T: ulong)) ulong widest = 0; else if (is (T: double)) double widest = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; Now, I thought this sounds like a great job for a mixin: template Widen (T, alias varname) { static if (is (T: ulong)) ulong varname = 0; else if (is (T: double)) double varname = 0.0; else static assert (false, "Unimplemented type " ~ T.stringof) ; } mixin Widen!(T, widest); ...but alas, "Declaration expected, not 'if'". Help?I would avoid mixin in such situation and use template instead: template Widen(T) { static if (is(T : ulong)) { alias ulong Widen; } else static if (is(T : double)) { alias double Widen; } else { static assert (false, "Unimplemented type " ~ T.stringof) ; } } Widen!(T) widest;
Apr 17 2009
Doctor J:Given a type parameter T of a template: If T is an integral type, I want to declare a variable 'widest' of type ulong; If T is a floating-point type, I want to declare a variable 'widest' of type double. And it has to be prettier than my solution. :)A solution using my dlibs: import std.stdio: writefln; import d.templates: IsIntegral, IsType, If; template Widened(T) { alias If!(IsIntegral!(T), ulong, If!(IsType!(T, float, double, real), double, void)) Widened; } void main() { writefln(typeid(Widened!(int))); // prints: ulong writefln(typeid(Widened!(byte))); // prints: ulong writefln(typeid(Widened!(real))); // prints: double writefln(typeid(Widened!(float))); // prints: double writefln(typeid(Widened!(double))); // prints: double writefln(typeid(Widened!(char))); // prints: void writefln(typeid(Widened!(string))); // prints: void } Note that real=>double and char=>void. If you want char=>ulong, then you have to use another isType!(T, ...) instead of IsIntegral!(T). dlibs (soon to be updated again to improve the apply()): http://www.fantascienza.net/leonardo/so/libs_d.zip Bye, bearophile
Apr 17 2009