How to hide a function return type in order to wrap several functions into an associated array?

Ali Çehreli acehreli at yahoo.com
Sun Sep 27 22:55:14 UTC 2020


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



More information about the Digitalmars-d-learn mailing list