Thread overview | ||||||
---|---|---|---|---|---|---|
|
January 14, 2007 Templates, varargs and static foreach | ||||
---|---|---|---|---|
| ||||
I would like to do the following: void foo() {} void bar(int a) { foo(); } // 1 void bar(int a, int b) { foo(); foo(); } // 2 void bar(int a, int b, int c) { foo(); foo(); foo(); } // 3 void bar(int[] a) { foreach(b; a) foo(); } // 4 The forms 1-3 should be called, when the amount of arguments is known at compile time. Otherwise 4 is called. Ok - this is a major simplification of the design I'm using. I would like to shorten it using templates. I have tried this: void foo() {} void bar(A...)(A a) { foo(); static if (a.length > 1) { bar(a[1..length]); } void bar(A)(A[] a) { foreach(t;a) foo(); } The problem is that the recursion happens on runtime (unless I specify -O -release -inline). Can the compiler guarantee that the recursion is unfolded, when all those optimizations are on or is there a static for/foreach for doing this in a better way. |
January 14, 2007 Re: Templates, varargs and static foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | %u wrote: > I would like to do the following: > > void foo() {} > void bar(int a) { foo(); } // 1 > void bar(int a, int b) { foo(); foo(); } // 2 > void bar(int a, int b, int c) { foo(); foo(); foo(); } // 3 > void bar(int[] a) { foreach(b; a) foo(); } // 4 > > The forms 1-3 should be called, when the amount of arguments is known at compile time. Otherwise > 4 is called. > > Ok - this is a major simplification of the design I'm using. I would like to shorten it using > templates. I have tried this: > > void foo() {} > void bar(A...)(A a) { foo(); static if (a.length > 1) { bar(a[1..length]); } > void bar(A)(A[] a) { foreach(t;a) foo(); } > > The problem is that the recursion happens on runtime (unless I specify -O -release -inline). Can > the compiler guarantee that the recursion is unfolded, when all those optimizations are on or is > there a static for/foreach for doing this in a better way. There is a "static foreach," only you do not use the "static" keyword. void foo() {} void bar(A...)(A a) { foreach(e; a) { foo(); } } You could also do this at runtime, using D's typesafe variadics: void bar(int[] a...) { foreach(e; a) { foo(); } } Both forms of bar are called in exactly the same way, with the caveat that the latter only accepts int arguments, while the former will accept any arguments. bar(1, 2, 3, 4); -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org |
January 14, 2007 Re: Templates, varargs and static foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | >There is a "static foreach," only you do not use >the "static" keyword. > void foo() {} > > void bar(A...)(A a) { > foreach(e; a) { > foo(); > } > } Dear Kirk, I tried this too, but disassembling to code reveals that the foreach generates extra instructions when compared to this (dmd 1.00 linux): void bar(A...)(A a) { static if (a.length>0) foo(); static if (a.length>1) foo(); static if (a.length>2) foo(); static if (a.length>3) foo(); ... } I tried this without any optimizations. I just want to be sure that the compiler guarantees the behaviour at compile time. This function is time critical. |
January 14, 2007 Re: Templates, varargs and static foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | > Dear Kirk, I tried this too, but disassembling to code reveals that the foreach generates extra instructions when compared to this (dmd 1.00 linux): The optimizer eliminates the extra code - not a problem anymore. I just wondered, why doesn't it do it all on compile time. Here's the dumbobj output: static if's: 0: 55 push %ebp 1: 8b ec mov %esp,%ebp 3: e8 fc ff ff ff call 4 <_D2t216__T3abcTiTiTiTiZ3abcFiiiiZv+0x4> 8: e8 fc ff ff ff call 9 <_D2t216__T3abcTiTiTiTiZ3abcFiiiiZv+0x9> d: e8 fc ff ff ff call e <_D2t216__T3abcTiTiTiTiZ3abcFiiiiZv+0xe> 12: e8 fc ff ff ff call 13 <_D2t216__T3abcTiTiTiTiZ3abcFiiiiZv+0x13> 17: 5d pop %ebp 18: c2 0c 00 ret $0xc 1b: 90 nop foreach: 0: 55 push %ebp 1: 8b ec mov %esp,%ebp 3: 83 ec 04 sub $0x4,%esp 6: 53 push %ebx 7: 89 45 fc mov %eax,0xfffffffc(%ebp) a: 8b 4d 10 mov 0x10(%ebp),%ecx d: e8 fc ff ff ff call e <_D2t216__T3bcdTiTiTiTiZ3bcdFiiiiZv+0xe> 12: 8b 45 0c mov 0xc(%ebp),%eax 15: e8 fc ff ff ff call 16 <_D2t216__T3bcdTiTiTiTiZ3bcdFiiiiZv+0x16> 1a: 8b 55 08 mov 0x8(%ebp),%edx 1d: e8 fc ff ff ff call 1e <_D2t216__T3bcdTiTiTiTiZ3bcdFiiiiZv+0x1e> 22: 8b 5d fc mov 0xfffffffc(%ebp),%ebx 25: e8 fc ff ff ff call 26 <_D2t216__T3bcdTiTiTiTiZ3bcdFiiiiZv+0x26> 2a: 5b pop %ebx 2b: c9 leave 2c: c2 0c 00 ret $0xc 2f: 90 nop |
Copyright © 1999-2021 by the D Language Foundation