Deciding one member of iteration chain at runtime
H. S. Teoh
hsteoh at qfbox.info
Fri Feb 17 17:44:20 UTC 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".
More information about the Digitalmars-d-learn
mailing list