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









Chris Piker <chris hoopjump.com> 