Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 13, 2006 static if with constant value | ||||
---|---|---|---|---|
| ||||
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 |
December 14, 2006 Re: static if with constant value | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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
|
December 14, 2006 Re: static if with constant value | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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
|
December 14, 2006 Re: static if with constant value | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> 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
Yeh, that makes sense. I think I'm going to need both kinds of tests eventually, actually.
--bb
|
Copyright © 1999-2021 by the D Language Foundation