Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 02, 2014 Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
----- import std.stdio; import std.typetuple; auto Delay(alias arg, size_t idx)() { return arg[idx]; } template expand(alias args, size_t idx = 0) { alias Args = typeof(args); static if (is(Args : C[N], C, size_t N)) { static if (idx < (N - 1)) alias expand = TypeTuple!(Delay!(args, idx), expand!(args, idx + 1)); else alias expand = Delay!(args, N - 1); } } void foo(int a, int b, int c) { writefln("a: %s, b: %s, c: %s", a, b, c); } void main() { int[3] arr = [1, 2, 3]; foo(expand!arr); } ----- |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Wednesday, 2 April 2014 at 19:40:41 UTC, Andrej Mitrovic wrote: > snip Cleaned up version: ----- import std.stdio; import std.traits; import std.typetuple; auto Delay(alias arg, size_t idx)() { return arg[idx]; } template expand(alias array, size_t idx = 0) if (isStaticArray!(typeof(array))) { alias Array = typeof(array); static if (idx + 1 < Array.length) alias expand = TypeTuple!(Delay!(array, idx), expand!(array, idx + 1)); else alias expand = Delay!(array, idx); } void print(int a) { writefln("1: %s", a); } void print(int a, int b) { writefln("2: %s %s", a, b); } void print(int a, int b, int c) { writefln("3: %s %s %s", a, b, c); } void main() { int[1] arr1 = [1]; int[2] arr2 = [1, 2]; int[3] arr3 = [1, 2, 3]; print(expand!arr1); print(expand!arr2); print(expand!arr3); } ----- |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 04/02/2014 09:46 PM, Andrej Mitrovic wrote: > On Wednesday, 2 April 2014 at 19:40:41 UTC, Andrej Mitrovic wrote: >> snip > Nice. > Cleaned up version: >... > auto Delay(alias arg, size_t idx)() { return arg[idx]; } I guess this would be more useful as a ref-returning @property function? |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 4/2/14, Timon Gehr <timon.gehr@gmx.ch> wrote:
> I guess this would be more useful as a ref-returning @property function?
Good point.
|
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
On 4/2/14, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote: > On 4/2/14, Timon Gehr <timon.gehr@gmx.ch> wrote: >> I guess this would be more useful as a ref-returning @property function? > > Good point. It can even be done inside the template: ----- template expand(alias array, size_t idx = 0) if (isStaticArray!(typeof(array))) { static @property ref Delay(alias arg, size_t idx)() { return arg[idx]; } alias Array = typeof(array); static if (idx + 1 < Array.length) alias expand = TypeTuple!(Delay!(array, idx), expand!(array, idx + 1)); else alias expand = Delay!(array, idx); } ----- |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
On 2014-04-02 20:54, Andrej Mitrovic wrote: > On 4/2/14, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote: >> On 4/2/14, Timon Gehr <timon.gehr@gmx.ch> wrote: >>> I guess this would be more useful as a ref-returning @property function? >> >> Good point. > > It can even be done inside the template: > > ----- > template expand(alias array, size_t idx = 0) > if (isStaticArray!(typeof(array))) > { > static @property ref Delay(alias arg, size_t idx)() { return arg[idx]; } > > alias Array = typeof(array); > > static if (idx + 1 < Array.length) > alias expand = TypeTuple!(Delay!(array, idx), > expand!(array, idx + 1)); > else > alias expand = Delay!(array, idx); > } > ----- In fact, it does not even need to have arg and idx explicitly passed, and the alias for Array is redundant: template expand(alias array, size_t idx = 0) if (isStaticArray!(typeof(array))) { @property ref Delay() { return array[idx]; } static if (idx + 1 < array.length) { alias expand = TypeTuple!(Delay, expand!(array, idx + 1)); } else { alias expand = Delay; } } -- Simen |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic: > void foo(int a, int b, int c) > { > writefln("a: %s, b: %s, c: %s", a, b, c); > } > > void main() > { > int[3] arr = [1, 2, 3]; > foo(expand!arr); > } > ----- In Python2 and Haskell it's a built-in feature, as it should be: >>> def foo((x, y, z)): print x, y, z ... >>> foo([1, 2, 3]) 1 2 3 >>> def bar(x, y, z): print x, y, z ... >>> a = [1, 2, 3] >>> bar(*a) 1 2 3 Prelude> let foo [x, y, z] = show x ++ ", " ++ show y ++ ", " ++ show z Prelude> let a = [1, 2, 3] Prelude> foo a "1, 2, 3" Bye, bearophile |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 04/02/14 21:46, Andrej Mitrovic wrote: > auto Delay(alias arg, size_t idx)() { return arg[idx]; } > > template expand(alias array, size_t idx = 0) > if (isStaticArray!(typeof(array))) > { > alias Array = typeof(array); > > static if (idx + 1 < Array.length) > alias expand = TypeTuple!(Delay!(array, idx), > expand!(array, idx + 1)); > else > alias expand = Delay!(array, idx); > } template expand(alias A, alias M=Delay) { mixin(q{alias expand = TypeTuple!(} ~ iota(A.length).map!q{",M!(A,"[!a..$]~text(a)~")"}().join() ~ q{);}); } SCNR. artur |
April 02, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Wednesday, 2 April 2014 at 21:53:57 UTC, Artur Skawina wrote:
> template expand(alias A, alias M=Delay) {
> mixin(q{alias expand = TypeTuple!(}
> ~ iota(A.length).map!q{",M!(A,"[!a..$]~text(a)~")"}().join()
> ~ q{);});
> }
>
> SCNR.
>
> artur
I kind of started this whole topic off from IRC.
...
What have I done!?
|
April 03, 2014 Re: Another interesting hack: expand a static array into parameter arguments | ||||
---|---|---|---|---|
| ||||
On 4/2/14, Artur Skawina <art.08.09@gmail.com> wrote:
> template expand(alias A, alias M=Delay) {
> mixin(q{alias expand = TypeTuple!(}
> ~ iota(A.length).map!q{",M!(A,"[!a..$]~text(a)~")"}().join()
> ~ q{);});
> }
You can always use string mixins for these hacks. But they are terrible to debug, and likely slower to compile. I can barely make out what the above code does even though I deal with mixins and templates every day.
|
Copyright © 1999-2021 by the D Language Foundation