Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 15, 2019 Manipulating alias sequences | ||||
---|---|---|---|---|
| ||||
I have written a simple function that can call another function over integral types with random arguments: auto rnd = Random(42); auto rand_integral(T)() { return uniform(T.min, T.max, rnd); } auto call_with_rand(alias fun)() { fun(staticMap!(get_rand_integral, Parameters!fun)); } Now I want to extend it so that a caller can specify the values of only some of the parameters. I tried using a static foreach instead of the staticMap function. But I can't modify AliasSeq values. alias args = AliasSeq!(0, 0); static foreach (idx, val; args) { static if (user_defined_function_exists_for_arg!(idx)) { args[idx] = user_defined_function(); // cannot modify tuple } else { args[idx] = gen_rand_integral!(typeof(val)); // cannot modify tuple } } How do I build up an argument tuple at compile time where some values are randomly generated and others are given through some user defined function (most likely automatically discovered by a naming convention)? |
July 15, 2019 Re: Manipulating alias sequences | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Ogles | On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote:
> I have written a simple function that can call another function over integral types with random arguments:
>
> [...]
You cannot. meta-programming and compile-time evaluation are supposed to be deterministic,
and hence cannot take random values.
|
July 15, 2019 Re: Manipulating alias sequences | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Monday, 15 July 2019 at 14:15:41 UTC, Stefan Koch wrote: > On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote: >> I have written a simple function that can call another function over integral types with random arguments: >> >> [...] > > You cannot. meta-programming and compile-time evaluation are supposed to be deterministic, > and hence cannot take random values. Sorry, I wasn't clear. The code I wrote does not actually _produce_ the random values at compile time. It is just a template that evaluates to a function call where each argument is given as `gen_rand_integral()`. So if I call call_with_rand!(add)(); It will expand to add(gen_rand_integral!(int)(), gen_rand_integral!(int)()); But I want a way to expand this to add(gen_rand_integral!(int)(), user_defined_generator!(int)()); |
July 15, 2019 Re: Manipulating alias sequences | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Ogles | On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote: > Now I want to extend it so that a caller can specify the values of only some of the parameters. I tried using a static foreach instead of the staticMap function. But I can't modify AliasSeq values. > > alias args = AliasSeq!(0, 0); > static foreach (idx, val; args) { > static if (user_defined_function_exists_for_arg!(idx)) { > args[idx] = user_defined_function(); // cannot modify tuple > } else { > args[idx] = gen_rand_integral!(typeof(val)); // cannot modify tuple > } > } > > How do I build up an argument tuple at compile time where some values are randomly generated and others are given through some user defined function (most likely automatically discovered by a naming convention)? Use a run-time Tuple instead of an AliasSeq: import std.typecons; auto args = tuple(0, 0); static foreach (idx, val; args) { static if (user_defined_function_exists_for_arg!idx) { args[idx] = user_defined_function(); } else { args[idx] = gen_random_integral!(typeof(val)); } } Then use `fun(args.expand)` to pass the members of the tuple as separate arguments to `fun`. |
July 15, 2019 Re: Manipulating alias sequences | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Monday, 15 July 2019 at 14:50:20 UTC, Paul Backus wrote:
> Use a run-time Tuple instead of an AliasSeq:
>
> import std.typecons;
> auto args = tuple(0, 0);
> static foreach (idx, val; args) {
> static if (user_defined_function_exists_for_arg!idx) {
> args[idx] = user_defined_function();
> } else {
> args[idx] = gen_random_integral!(typeof(val));
> }
> }
>
> Then use `fun(args.expand)` to pass the members of the tuple as separate arguments to `fun`.
Amazing, this works great! Thanks.
|
Copyright © 1999-2021 by the D Language Foundation