Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
September 27, 2007 static if and templates | ||||
---|---|---|---|---|
| ||||
Hi, in the function isMatrix I would like to access the function isArray. Unfortunately, this does not work, even though if I use the definition of isArray directly it does work. How could I write the code using isArray? Thanks for any hints. Oliver ------------------ import std.stdio; bool isArray(T)(T expr){ return (expr.mangleof)[0] == 'A'; } bool isMatrix(T)(T expr){ static if ( (expr.mangleof)[0] == 'A' ) // works //static if ( isArray(expr) ) // does NOT work return (expr.mangleof)[1] == 'A'; else return false; } void main () { double s = 1.; double[] v = [1.,2.]; double[][] m = [[1.,2.]]; writefln("s: ", isArray(s), " ", isMatrix(s) ); writefln("v: ", isArray(v), " ", isMatrix(v) ); writefln("m: ", isArray(m), " ", isMatrix(m) ); } |
September 27, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oliver | Oliver wrote:
> bool isArray(T)(T expr){
> return (expr.mangleof)[0] == 'A';
> }
>
> bool isMatrix(T)(T expr){
> static if ( (expr.mangleof)[0] == 'A' ) // works
> //static if ( isArray(expr) ) // does NOT work
> return (expr.mangleof)[1] == 'A';
> else
> return false;
> }
Static if requires the condition to be evaluated at compile time, but expr is a run time construct. You can make these two compile-time evaluateable by switching to templates:
---
import std.stdio;
template isArray(T){
const isArray = (T.mangleof)[0] == 'A';
}
template isMatrix(T){
static if ( isArray!(T) )
const isMatrix = (T.mangleof)[1] == 'A';
else
const isMatrix = false;
}
void main () {
double s = 1.;
double[] v = [1.,2.];
double[][] m = [[1.,2.]];
writefln("s: ", isArray!(typeof(s)), " ", isMatrix!(typeof(s)) );
writefln("v: ", isArray!(typeof(v)), " ", isMatrix!(typeof(v)) );
writefln("m: ", isArray!(typeof(m)), " ", isMatrix!(typeof(m)) );
}
|
September 27, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Kamm | Christian, thank you for your reply and your code. > Static if requires the condition to be evaluated at compile time, but expr is a run time construct. You can make these two compile-time evaluateable by switching to templates: what i do not understand is the following: if expr is a runtime construct, how come expr.mangleof works? for this to work (in my beginner thinking) the compiler takes, say m, from main and inserts it into expr.mangleof. Now, why is it not possible for the compile to insert the expr into isArray? I think there is some fundamental thing i don't understand. Any wisdom you can share? Oliver > > --- > import std.stdio; > > template isArray(T){ > const isArray = (T.mangleof)[0] == 'A'; > } > > template isMatrix(T){ > static if ( isArray!(T) ) > const isMatrix = (T.mangleof)[1] == 'A'; > else > const isMatrix = false; > } > > void main () { > double s = 1.; > double[] v = [1.,2.]; > double[][] m = [[1.,2.]]; > > writefln("s: ", isArray!(typeof(s)), " ", isMatrix!(typeof(s)) ); > writefln("v: ", isArray!(typeof(v)), " ", isMatrix!(typeof(v)) ); > writefln("m: ", isArray!(typeof(m)), " ", isMatrix!(typeof(m)) ); > } > |
September 27, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oliver | > what i do not understand is the following: if expr is a runtime construct, how come expr.mangleof works? for this to work (in my beginner thinking) the compiler takes, say m, from main and inserts it into expr.mangleof. Now, why is it not possible for the compile to insert the expr into isArray? I think there is some fundamental thing i don't understand. Any wisdom you can share?
Well, I'm pretty sure expr.mangleof becomes typeof(expr).mangleof, so
---
class A {}
class B : A {}
A a = new B;
writefln(a.mangleof);
---
Would give you the mangled name of A (compile time type) and not of B.
By the way, a more conventional way of writing your isArray and isMatrix functions would be
---
template isArray(T){
static if(is(T U : U[]))
const isArray = true;
else
const isArray = false;
}
template isMatrix(T){
static if(is(T U : U[][]))
const isMatrix = true;
else
const isMatrix = false;
}
---
And finally, I don't recommend using T[][] as a matrix type: it's literally an array of arrays, so each row mat[i] does not even need to have the same length and you won't get very good performance.
So, unless that's what you want, I recommend looking through the projects at dsource for implementations of vectors and matrices - I think there are several.
Cheers,
Christian
|
September 27, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Kamm | Christian Kamm wrote:
>> what i do not understand is the following: if expr is a runtime construct,
>> how come expr.mangleof works? for this to work (in my beginner thinking)
>> the compiler takes, say m, from main and inserts it into expr.mangleof.
>> Now, why is it not possible for the compile to insert the expr into
>> isArray? I think there is some fundamental thing i don't understand. Any
>> wisdom you can share?
>
> Well, I'm pretty sure expr.mangleof becomes typeof(expr).mangleof, so
>
> ---
> class A {}
> class B : A {}
>
> A a = new B;
> writefln(a.mangleof);
> ---
>
> Would give you the mangled name of A (compile time type) and not of B.
>
> By the way, a more conventional way of writing your isArray and isMatrix
> functions would be
>
> ---
> template isArray(T){
> static if(is(T U : U[]))
> const isArray = true;
> else
> const isArray = false;
> }
If you use:
static if (is(typeof(T[0]))
it will work for user-defined types.
|
September 27, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | Don Clugston wrote:
>> template isArray(T){
>> static if(is(T U : U[]))
>> const isArray = true;
>> else
>> const isArray = false;
>> }
>
> If you use:
> static if (is(typeof(T[0]))
> it will work for user-defined types.
Indeed that will accept anything that provides opIndex. You can check for opSlice and the rest in a similar way, if your code requires them to be available. With these checks, you can even skip the static if:
template hasIndexAndSlice(T) {
const bool hasIndexAndSlice = is(typeof(T[0])) && is(typeof(T[0..0]));
}
|
September 28, 2007 Re: static if and templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Kamm | Christian and Don, thanks for you help. Here is what i do now. 1) it is modular 2) is dose not need the clumsy yx!() notation. thanks again, oliver ----------- import std.stdio; bool isIndexed(T)(T) { return is( typeof(T[0]) ); } bool isDoubleIndexed(T)(T) { return is( typeof(T[0][0]) ); } bool isSliced(T)(T) { return is( typeof(T[0..0]) ); } bool isArray(T)(T expr) { return isIndexed(expr); } bool isMatrix(T)(T expr) { return isIndexed(expr) && isDoubleIndexed(expr); } bool isBlubb(T)(T expr) { return !isMatrix(expr); } void main () { double s = 1.; double[] v = [1.,2.]; double[][] m = [[1.,2.]]; writefln("s: ", isArray(s), " ", isMatrix(s) ); writefln("v: ", isArray(v), " ", isMatrix(v) ); writefln("m: ", isArray(m), " ", isMatrix(m) ); writefln("b: ", isBlubb(v), " ", isBlubb(m) ); } |
Copyright © 1999-2021 by the D Language Foundation