On 9/27/20 11:54 AM, tastyminerals wrote: > I have a collection of functions that all have the same input, a string. > The output however is different and depending on what the function does > it can be ulong, double or bool.
The following approach overcomes the different return type issue by creating delegates that take string and return string:
auto numberOfPunctChars(string text) { return 42; } auto ratioOfDigitsToChars(string text) { return 1.5; } auto hasUnbalancedParens(string text) { return true; } struct FeatureSet { alias TakesString = string delegate(string); TakesString[] features; void register(Func)(Func func) { // Here, we convert from a function returning any type // to a delegate returning string: features ~= (string s) { import std.conv : text; return func(s).text; }; } // Here, we apply all feature delegates and put the outputs // into the provided output range. void apply(O)(ref O outputRange, string s) { import std.format : formattedWrite; import std.algorithm : map; outputRange.formattedWrite!"%-(%s\n%|%)"(features.map!(f => f(s))); } } void main() { auto featureSet = FeatureSet(); featureSet.register(&numberOfPunctChars); featureSet.register(&ratioOfDigitsToChars); featureSet.register(&hasUnbalancedParens); // lockingTextWriter() just makes an output range from // an output stream. import std.stdio; auto output = stdout.lockingTextWriter; featureSet.apply(output, "hello world"); // As another example, you can use an Appender as well: import std.array : Appender; auto app = Appender!(char[])(); featureSet.apply(app, "goodbye moon"); writefln!"Appender's content:\n%s"(app.data); } Ali