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".