digitalmars.D.learn - How to call function with variable arguments at runtime?
- Mr. Jonse (11/11) Oct 09 2017 I need to store a hetrogeneous array of delegates. How can I do
- bauss (5/16) Oct 10 2017 Not entirely sure what you're wanting to do, but sounds a lot
- Marc =?UTF-8?B?U2Now7x0eg==?= (25/36) Oct 10 2017 Like so?
- Mr. Jonse (12/53) Oct 11 2017 The problem with this is that the function parameters need to be
I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? I have the parameters as Variant[] params and a function/delegate pointer(void* for now). Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. Thanks.
Oct 09 2017
On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? I have the parameters as Variant[] params and a function/delegate pointer(void* for now). Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. Thanks.Not entirely sure what you're wanting to do, but sounds a lot like variadic parameters. https://dlang.org/spec/function.html#variadic mixed with some compile-time terminology.
Oct 10 2017
On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? I have the parameters as Variant[] params and a function/delegate pointer(void* for now). Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. Thanks.Like so? import std.variant; void foo(int a, string b, float c) { import std.stdio; writefln("a = %s, b = %s, c = %s", a, b, c); } auto apply(alias fn)(Variant[] values) { import std.traits : ParameterTypeTuple; import std.conv : emplace; alias Types = ParameterTypeTuple!fn; assert(values.length == Types.length); Types args = void; foreach(i, ref arg; args) { // using emplace instead of assignment here to be fully correct emplace!(typeof(arg))(&arg, values[i].get!(typeof(arg))); } return fn(args); } void main() { Variant[] values = [Variant(1), Variant("Hello world"), Variant(3.14159f)]; apply!foo(values); }
Oct 10 2017
On Tuesday, 10 October 2017 at 08:26:37 UTC, Marc Schütz wrote:On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:The problem with this is that the function parameters need to be known. I do not know them. All I have is a function pointer and the arguments in variants. So, it would work off void bar(int, string, float) { } void* foo = &bar; Variant[] values = [Variant(1), Variant("Hello world"), Variant(3.14159f)]; apply(foo, values); So, it has to get the type from the variant at run time and pass the value's appropriately.I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? I have the parameters as Variant[] params and a function/delegate pointer(void* for now). Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. Thanks.Like so? import std.variant; void foo(int a, string b, float c) { import std.stdio; writefln("a = %s, b = %s, c = %s", a, b, c); } auto apply(alias fn)(Variant[] values) { import std.traits : ParameterTypeTuple; import std.conv : emplace; alias Types = ParameterTypeTuple!fn; assert(values.length == Types.length); Types args = void; foreach(i, ref arg; args) { // using emplace instead of assignment here to be fully correct emplace!(typeof(arg))(&arg, values[i].get!(typeof(arg))); } return fn(args); } void main() { Variant[] values = [Variant(1), Variant("Hello world"), Variant(3.14159f)]; apply!foo(values); }
Oct 11 2017