digitalmars.D.learn - array depth template
- Saaa (14/14) Jun 11 2009 Is this a good way to get the depth of an array?
- BCS (3/18) Jun 11 2009 I just posted this today
- Jarrett Billingsley (6/20) Jun 11 2009 It's kind of the right idea, but.. it's also kind of weird.
- Saaa (6/11) Jun 11 2009 Ah , that's how you make it do at compile time, using const.
- Saaa (1/1) Jun 11 2009 Also, what's the advantage of explicitly defining it as a template?
- Jarrett Billingsley (10/14) Jun 11 2009 I just tend to prefer template specialization when doing type pattern
- Saaa (6/21) Jun 11 2009 I mean, I was using a function template.
- Jarrett Billingsley (14/30) Jun 11 2009 ead
- Saaa (11/15) Jun 11 2009 things you don't understand. Implicit conversion is necessary in some
- Saaa (4/9) Jun 11 2009 Although I don't fully understand your code, I think I modified it corre...
- Saaa (9/11) Jun 11 2009 ..
- Jarrett Billingsley (5/17) Jun 11 2009 Your template. Types are not values, you cannot declare a constant
- Saaa (35/39) Jun 11 2009 Erm, why did this print corretly?
Is this a good way to get the depth of an array? int getArrayDepth(T)(ref T array) { static if( is(T A:A[]) ) { A arr; return 1 + getArrayDepth(arr); } else { return 0; } return -1; }
Jun 11 2009
Hello Saaa,Is this a good way to get the depth of an array? int getArrayDepth(T)(ref T array) { static if( is(T A:A[]) ) { A arr; return 1 + getArrayDepth(arr); } else { return 0; } return -1; }I just posted this today http://www.dsource.org/projects/scrapple/browser/trunk/Serial/utill.d
Jun 11 2009
On Thu, Jun 11, 2009 at 9:15 PM, Saaa<empty needmail.com> wrote:Is this a good way to get the depth of an array? int getArrayDepth(T)(ref T array) { static if( is(T A:A[]) ) { A arr; return 1 + getArrayDepth(arr); } else { return 0; } return -1; }It's kind of the right idea, but.. it's also kind of weird. template ArrayDepth(T: T[]) { const ArrayDepth = 1 + ArrayDepth!(T); } template ArrayDepth(T) { const ArrayDepth = 0; } This lets you get the depth of any array _type_, like ArrayDepth!(int[][]) gives 2.
Jun 11 2009
It's kind of the right idea, but.. it's also kind of weird. template ArrayDepth(T: T[]) { const ArrayDepth = 1 + ArrayDepth!(T); } template ArrayDepth(T) { const ArrayDepth = 0; } This lets you get the depth of any array _type_, like ArrayDepth!(int[][]) gives 2.Ah , that's how you make it do at compile time, using const. BCS also did it a bit like me (one template that is) I just didn't know you could also just pass the type :D Any advantage to using two? He also does : is( T B ==B[]) iso is( T B:B[] ) Any significant difference there?
Jun 11 2009
Also, what's the advantage of explicitly defining it as a template?
Jun 11 2009
On Thu, Jun 11, 2009 at 11:02 PM, Saaa<empty needmail.com> wrote:Any advantage to using two?I just tend to prefer template specialization when doing type pattern matching. It works out better than is() in some cases.He also does : is( T B ==B[]) iso is( T B:B[] ) Any significant difference there?I'm.. not sure, in this case anyway. Normally == does strict type comparison while : does implicit type conversion, but in this case, is() is being (ab)used to pick apart a type rather than test one. I think it'll always return 'true' in either case if T is an array, so I don't think there's a functional difference.Also, what's the advantage of explicitly defining it as a template?As opposed to what, implicitly defining it as a template? This question doesn't really make sense.
Jun 11 2009
Looks very Haskell like :)Any advantage to using two?I just tend to prefer template specialization when doing type pattern matching. It works out better than is() in some cases.Implicit convertion sounds a bit dangerous, might start using == insteadHe also does : is( T B ==B[]) iso is( T B:B[] ) Any significant difference there?I'm.. not sure, in this case anyway. Normally == does strict type comparison while : does implicit type conversion, but in this case, is() is being (ab)used to pick apart a type rather than test one. I think it'll always return 'true' in either case if T is an array, so I don't think there's a functional difference.I mean, I was using a function template.Also, what's the advantage of explicitly defining it as a template?As opposed to what, implicitly defining it as a template? This question doesn't really make sense.template ArrayDepth(T: T[]) { const ArrayDepth = 1 + ArrayDepth!(T); } template ArrayDepth(T) { const ArrayDepth = 0; }The code looks a bit strange to me: ArrayDepth is both a (const) value and template name and where is the return value ?
Jun 11 2009
On Thu, Jun 11, 2009 at 11:45 PM, Saaa<empty needmail.com> wrote:ead Um, there's no "one's better than the other." Don't overgeneralize on things you don't understand. Implicit conversion is necessary in some cases, and in others, exact comparison is needed.I'm.. not sure, in this case anyway. =A0Normally =3D=3D does strict type comparison while : does implicit type conversion, but in this case, is() is being (ab)used to pick apart a type rather than test one. =A0I think it'll always return 'true' in either case if T is an array, so I don't think there's a functional difference.Implicit convertion sounds a bit dangerous, might start using =3D=3D inst=A function template is just a function in a template. Templates can work just fine on their own. If you're manipulating types, there's really no need to get functions involved.I mean, I was using a function template.Also, what's the advantage of explicitly defining it as a template?As opposed to what, implicitly defining it as a template? =A0This question doesn't really make sense.urntemplate ArrayDepth(T: T[]) { const ArrayDepth =3D 1 + ArrayDepth!(T); } template ArrayDepth(T) =A0 =A0 =A0 { const ArrayDepth =3D 0; }The code looks a bit strange to me: ArrayDepth is both a (const) value and template name and where is the ret=value ?See "Implicit Template Properties" here: http://www.digitalmars.com/d/1.0/template.html When you create a member in a template with the same name as the template, you can access it from the template without explicitly writing ArrayDepth!(int[]).ArrayDepth.
Jun 11 2009
Um, there's no "one's better than the other." Don't overgeneralize onthings you don't understand. Implicit conversion is necessary in some cases, and in others, exact comparison is needed. I didn't mean it like that, don't worry :) I mean, I apparently used implicit when I actually wanted explicit.A function template is just a function in a template. Templates canwork just fine on their own. If you're manipulating types, there's really no need to get functions involved. CheckSee "Implicit Template Properties" here:http://www.digitalmars.com/d/1.0/template.html Reading . .When you create a member in a template with the same name as thetemplate, you can access it from the template without explicitly writing ArrayDepth!(int[]).ArrayDepth.
Jun 11 2009
It's kind of the right idea, but.. it's also kind of weird. template ArrayDepth(T: T[]) { const ArrayDepth = 1 + ArrayDepth!(T); } template ArrayDepth(T) { const ArrayDepth = 0; } This lets you get the depth of any array _type_, like ArrayDepth!(int[][]) gives 2.Although I don't fully understand your code, I think I modified it correctly to get the base type of an array :) template BaseType(T: T[]) { const BaseType = BaseType!(T); } template BaseType(T) {const BaseType = T; }
Jun 11 2009
template BaseType(T: T[]) { const BaseType = BaseType!(T); } template BaseType(T) {const BaseType = T; }.. else static if( std2.traits.isNumeric!( BaseType!(T) ) ) { .. ddata\ddata.d(192): template instance isNumeric!(int) does not match any template declaration ddata\ddata.d(192): Error: expression isNumeric!(int) is not constant or does not evaluate to a bool What am I doing wrong?
Jun 11 2009
On Fri, Jun 12, 2009 at 12:04 AM, Saaa<empty needmail.com> wrote:Your template. Types are not values, you cannot declare a constant that is a type. You have to use alias instead: template BaseType(T: T[]) { alias BaseType!(T) BaseType; } template BaseType(T) { alias T BaseType; }template BaseType(T: T[]) { const BaseType = BaseType!(T); } template BaseType(T) {const BaseType = T; }.. else static if( std2.traits.isNumeric!( BaseType!(T) ) ) { .. ddata\ddata.d(192): template instance isNumeric!(int) does not match any template declaration ddata\ddata.d(192): Error: expression isNumeric!(int) is not constant or does not evaluate to a bool What am I doing wrong?
Jun 11 2009
Your template. Types are not values, you cannot declare a constant that is a type. You have to use alias instead: template BaseType(T: T[]) { alias BaseType!(T) BaseType; } template BaseType(T) { alias T BaseType; }Erm, why did this print corretly? writefln(`BaseType = `, BaseType!(T).stringof ); btw. Thanks for everything !! It's nice to get some comments after a fews days of struggling with them templates :) I can now parse any numeric type (array) till depth 4; still haven't found a way to generalize this part :( private void Parse(T)(ref T parsed) { .. switch( depth ) { case 0: if( temp.length < index[depth] ) temp.length = temp.length * 2; break; static if( is(T A:A[][])) { case 1: if( temp[ index[0] ].length < index[depth] ) temp[index[0]].length = temp[index[0]].length * 2; break; } static if( is(T A:A[][][])) { case 2: if( temp[ index[0] ][ index[1] ].length < index[depth] ) temp[ index[0] ][ index[1] ].length = temp[ index[0] ][ index[1] ].length * 2; break; } default: assert(false); break; } .. }
Jun 11 2009