digitalmars.D.learn - Deciding one member of iteration chain at runtime
- Chris Piker (44/44) Feb 17 2023 Hi D
- H. S. Teoh (37/54) Feb 17 2023 [...]
- Chris Piker (5/8) Feb 17 2023 Thanks, this was helpful.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (18/20) Feb 17 2023 std.range.choose may be useful but I think it requires creating two
- Chris Piker (4/10) Feb 17 2023 Now that's a handy construct.
Hi D I have a main "loop" for a data processing program that looks much as follows: ```d sourceRange .operatorA .operatorB .operatorC .operatorD .operatorE .operatorF .operatorG .operatorH .copy(destination); ``` Where all `operator` items above are InputRange structs that take an upstream range, and the pipeline really is 9 operations deep. In order to handle new functionality it turns out that operatorG needs to be of one of two different types at runtime. How would I do something like the following: ```d auto virtualG; // <-- probably invalid code, illustrating the idea if(runtime_condition) virtualG = operatorG1; else virtualG = operatorG2; sourceRange .operatorA .operatorB .operatorC .operatorD .operatorE .operatorF .virtualG .operatorH .copy(destination); ``` ? I've tried various usages of `range.InputRangeObject` but haven't been able to get the syntax right. Any suggestions on the best way to proceed? Maybe the whole chain should be wrapped in InputRangeObject classes, I don't know. Thanks,
Feb 17 2023
On Fri, Feb 17, 2023 at 05:30:40PM +0000, Chris Piker via Digitalmars-d-learn wrote: [...]In order to handle new functionality it turns out that operatorG needs to be of one of two different types at runtime. How would I do something like the following: ```d auto virtualG; // <-- probably invalid code, illustrating the idea if(runtime_condition) virtualG = operatorG1; else virtualG = operatorG2;[...]``` ? I've tried various usages of `range.InputRangeObject` but haven't been able to get the syntax right. Any suggestions on the best way to proceed? Maybe the whole chain should be wrapped in InputRangeObject classes, I don't know.[...] Here's an actual function taken from my own code, that returns a different range type depending on a runtime condition, maybe this will help you? ```d /** * Expands ' '-directives in a range of strings. * * Returns: A range of strings with lines that begin with ' ' * substituted with the contents of the file named by the rest of the * line. */ auto expandFileDirectives(File = std.stdio.File, R)(R args) if (isInputRange!R && is(ElementType!R : const(char)[])) { import std.algorithm.iteration : joiner, map; import std.algorithm.searching : startsWith; import std.range : only; import std.range.interfaces : InputRange, inputRangeObject; import std.typecons : No; return args.map!(arg => arg.startsWith(' ') ? cast(InputRange!string) inputRangeObject( File(arg[1 .. $]).byLineCopy(No.keepTerminator)) : cast(InputRange!string) inputRangeObject(only(arg))) .joiner; } ``` Note that the cast is to a common base class of the two different subclasses returned by inputRangeObject(). This function is used in the rest of the code as part of a UFCS chain of ranges. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
Feb 17 2023
On Friday, 17 February 2023 at 17:44:20 UTC, H. S. Teoh wrote:Here's an actual function taken from my own code, that returns a different range type depending on a runtime condition, maybe this will help you?Thanks, this was helpful. I keep forgetting to expand my horizons on what can be returned from an auto function. I'm still unlearning C & Java. Cheers,
Feb 17 2023
On 2/17/23 09:30, Chris Piker wrote:operatorG needs to be of one of two different types at runtimestd.range.choose may be useful but I think it requires creating two variables like g1 and g2 below: import std.range; import std.algorithm; void main(string[] args) { const condition = (args.length > 1); // The first part of the algorithm auto r = iota(10) .filter!(n => n % 2); // Two different steps auto g1 = r.map!((int n) => n * n); auto g2 = r.map!((int n) => n * 10); // The rest of the algoritm auto result = choose(condition, g1, g2) .array; } Ali
Feb 17 2023
On Friday, 17 February 2023 at 17:42:19 UTC, Ali Çehreli wrote:// Two different steps auto g1 = r.map!((int n) => n * n); auto g2 = r.map!((int n) => n * 10); // The rest of the algoritm auto result = choose(condition, g1, g2) .array;Now that's a handy construct. There's many little goodies in phobos I've yet to learn, thanks for the tip!
Feb 17 2023