Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
April 17, 2009 Widening a type | ||||
---|---|---|---|---|
| ||||
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? |
April 17, 2009 Re: Widening a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Doctor J |
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
|
April 17, 2009 Re: Widening a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Doctor J | 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))
|
April 17, 2009 Re: Widening a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 > |
April 17, 2009 Re: Widening a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Doctor J | 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;
|
April 17, 2009 Re: Widening a type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Doctor J | 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 |
Copyright © 1999-2021 by the D Language Foundation