On Thu, Apr 15, 2021 at 08:56:18PM +0000, mw via Digitalmars-d-learn wrote:
[...]
> of course, one can manually dispatch:
> 
> if      (userInputString == "cat") createCat();
> else if (userInputString == "dog") createDog();
> ...
> 
> but this this tedious.

-------------------
// Disclaimer: this is proof of concept, I didn't actually run this yet
class Animal {}
class Cat : Animal {}
class Dog : Animal {}

alias SupportedTypes = AliasSeq!(Cat, Dog, /* whatever else you want here */);

string userInputString = ...;
Animal result;
SW: switch (userInputString) {
        static foreach (T; SupportedTypes) {
                case T.stringof:
                        result = new T;
                        break SW;
        }
        default:
                throw new Exception("Unknown object type");
}
-------------------


> I have a similar question: how to dynamically use user's input string
> as function name can call it? suppose the function has no argument.

Same idea:

-------------------
// Disclaimer: this is proof of concept, I didn't actually run this yet
struct Dispatcher {
        void bark() { ... }
        void meow() { ... }
        void moo() { ... }
        ... // whatever else you want here
}

Dispatcher disp;
string userInputString = ...;
SW: switch (userInputString) {
        static foreach (fieldName; __traits(allMembers, disp)) {
                static if (is(typeof(__traits(getMember, disp, fieldName))
                        == function)
                {
                        case fieldName:
                                __traits(getMember, disp, fieldName)();
                                break SW;
                }
        }
}
-------------------

Basically, the idea is to obtain a list of types/methods/whatever
somehow (either by explicitly listing instances, or via compile-time
introspection), then statically generate switch cases from it.  You can
eliminate many kinds of boilerplate using this little trick.


T

-- 
Береги платье снову, а здоровье смолоду. 

Reply via email to