digitalmars.D.learn - static if with constant value
- Bill Baxter (64/64) Dec 13 2006 I can't understand why the little program below outputs what it does.
- Bill Baxter (11/86) Dec 13 2006 Doh, I figured out why it does what it does now. I had assumed that
- Sean Kelly (8/20) Dec 13 2006 You can probably just do:
- Bill Baxter (4/28) Dec 13 2006 Yeh, that makes sense. I think I'm going to need both kinds of tests
I can't understand why the little program below outputs what it does.
It seems like static if (constant) works in some cases but not others.
Is this just a bug?
----
import std.stdio : writef, writefln;
template is_complex(T)
{
static if (is(typeof(T.init.re)) && is(typeof(T.init.im))) {
const bool is_complex = true;
} else {
const bool is_complex = false;
}
}
template float_for_type(T)
{
static if ( is_complex!(T) ) {
alias typeof(T.init.re) float_for_type;
} else {
alias T float_for_type;
}
}
void print_complex(T)(T* arg)
{
static const bool cplx = is_complex!(T);
writefln("print_complex: Type: %s, is_complex? ", typeid(T), cplx);
static if ( is_complex!(T) ) {
writefln("print_complex: static if is_complex? true");
} else {
writefln("print_complex: static if is_complex? false");
}
}
void main()
{
float f;
cfloat c;
double d;
cdouble z;
writefln("main: %s made from %s", typeid(typeof(f)),
typeid(float_for_type!(typeof(f)))); print_complex(&f);
writefln("main: %s made from %s", typeid(typeof(c)),
typeid(float_for_type!(typeof(c)))); print_complex(&c);
writefln("main: %s made from %s", typeid(typeof(d)),
typeid(float_for_type!(typeof(d)))); print_complex(&d);
writefln("main: %s made from %s", typeid(typeof(z)),
typeid(float_for_type!(typeof(z)))); print_complex(&z);
}
----
Here's what it outputs for me with DMD:
main: float made from float
print_complex: Type: float, is_complex? true
print_complex: static if is_complex? true
main: cfloat made from float
print_complex: Type: cfloat, is_complex? true
print_complex: static if is_complex? true
main: double made from double
print_complex: Type: double, is_complex? true
print_complex: static if is_complex? true
main: cdouble made from double
print_complex: Type: cdouble, is_complex? true
print_complex: static if is_complex? true
In float_for_type!(T), is_complex!(T) works, but in print_complex it
does not for some reason (it always evaluates to true). Can anyone
explain this behavior?
--bb
Dec 13 2006
Doh, I figured out why it does what it does now. I had assumed that
floats and doubles didn't have .re and .im properties, so that that
would cause the is() check to fail.
So what's a better way to check for complexity of a type?
I'd rather not have to list every complex type explicitly. It's ugly
for one, but more importantly it precludes recognizing user types as
complex-like.
Maybe this is close enough?
static if( is(T:cfloat) || is(T:cdouble) || is(T:creal) ) {...}
--bb
Bill Baxter wrote:
I can't understand why the little program below outputs what it does.
It seems like static if (constant) works in some cases but not others.
Is this just a bug?
----
import std.stdio : writef, writefln;
template is_complex(T)
{
static if (is(typeof(T.init.re)) && is(typeof(T.init.im))) {
const bool is_complex = true;
} else {
const bool is_complex = false;
}
}
template float_for_type(T)
{
static if ( is_complex!(T) ) {
alias typeof(T.init.re) float_for_type;
} else {
alias T float_for_type;
}
}
void print_complex(T)(T* arg)
{
static const bool cplx = is_complex!(T);
writefln("print_complex: Type: %s, is_complex? ", typeid(T), cplx);
static if ( is_complex!(T) ) {
writefln("print_complex: static if is_complex? true");
} else {
writefln("print_complex: static if is_complex? false");
}
}
void main()
{
float f;
cfloat c;
double d;
cdouble z;
writefln("main: %s made from %s", typeid(typeof(f)),
typeid(float_for_type!(typeof(f)))); print_complex(&f);
writefln("main: %s made from %s", typeid(typeof(c)),
typeid(float_for_type!(typeof(c)))); print_complex(&c);
writefln("main: %s made from %s", typeid(typeof(d)),
typeid(float_for_type!(typeof(d)))); print_complex(&d);
writefln("main: %s made from %s", typeid(typeof(z)),
typeid(float_for_type!(typeof(z)))); print_complex(&z);
}
----
Here's what it outputs for me with DMD:
main: float made from float
print_complex: Type: float, is_complex? true
print_complex: static if is_complex? true
main: cfloat made from float
print_complex: Type: cfloat, is_complex? true
print_complex: static if is_complex? true
main: double made from double
print_complex: Type: double, is_complex? true
print_complex: static if is_complex? true
main: cdouble made from double
print_complex: Type: cdouble, is_complex? true
print_complex: static if is_complex? true
In float_for_type!(T), is_complex!(T) works, but in print_complex it
does not for some reason (it always evaluates to true). Can anyone
explain this behavior?
--bb
Dec 13 2006
Bill Baxter wrote:
Doh, I figured out why it does what it does now. I had assumed that
floats and doubles didn't have .re and .im properties, so that that
would cause the is() check to fail.
So what's a better way to check for complexity of a type?
I'd rather not have to list every complex type explicitly. It's ugly
for one, but more importantly it precludes recognizing user types as
complex-like.
Maybe this is close enough?
static if( is(T:cfloat) || is(T:cdouble) || is(T:creal) ) {...}
You can probably just do:
static if( is(T:creal) ) { ... }
As far as I know, cfloat and cdouble are convertible to creal, so that
should work. I personally chose to list types in the traits templates I
created, but that is because I want to be sure that they're exactly that
type. I generally don't want UDTs filtering through as well.
Sean
Dec 13 2006
Sean Kelly wrote:Bill Baxter wrote:Yeh, that makes sense. I think I'm going to need both kinds of tests eventually, actually. --bbDoh, I figured out why it does what it does now. I had assumed that floats and doubles didn't have .re and .im properties, so that that would cause the is() check to fail. So what's a better way to check for complexity of a type? I'd rather not have to list every complex type explicitly. It's ugly for one, but more importantly it precludes recognizing user types as complex-like. Maybe this is close enough? static if( is(T:cfloat) || is(T:cdouble) || is(T:creal) ) {...}You can probably just do: static if( is(T:creal) ) { ... } As far as I know, cfloat and cdouble are convertible to creal, so that should work. I personally chose to list types in the traits templates I created, but that is because I want to be sure that they're exactly that type. I generally don't want UDTs filtering through as well. Sean
Dec 13 2006








Bill Baxter <dnewsgroup billbaxter.com>