Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D mixin with factory

Tags:

mixins

factory

d

Consider I have the following classes:

/// File classes.d
class C {
    string type() { return "C"; };
}

class C1 : C {
    override string type() { return "C1"; };
}

class C2 : C {
    override string type() { return "C1"; };
}

Now I want to implement a factory somewhere else, like:

/// File factory.d
module factory;
import std.functional;
import std.stdio;

void main() {
    mixin(import("classes.d"));
    auto c = cast(typeof(mixin("C1"))) Object.factory("C1");
    writeln(c.type());
}

The compiler (dmd 2.058) says me:

factory.d(7): Error argument C1 to typeof is not an expression

I know the following line compiles well:

auto c = cast(C1) Object.factory("classes.C1");

but this requires me to know the type (C1) at compile time. I want to get the type at runtime (like a string).

like image 223
maverik Avatar asked Feb 02 '26 12:02

maverik


1 Answers

mixin(`auto c = cast(typeof(C1)) Object.factory("C1");`)

I don't understand you question, I think: You want to cast dynamically at runtime to a given type? This is not possible in a statically typed language! What you can do is, passing your classes (or whatever) around as void* and using a switch … case to cast it to the needed type (you can also use std.variant, which is maybe the better way, but I've never used it) and then calling different functions (templated functions):

final switch(which_type) {
    case "C1": foo(cast(C1)bar); break;
    case "C2": foo(cast(C2)bar); break;
}

void foo(T)(T a) {
}

You can also generate the switch case at compile-time:

final switch(which_type) {
    foreach(i; TypeTuple("C1", "C2")) {
        case i: foo(mixin(`cast(` ~ i ~ `)bar`); break;
    }
}

If you just wanna get the string of the type typeof(bar).stringof will give you the type of bar as string (but this is already known at compile time).

like image 99
dav1d Avatar answered Feb 05 '26 03:02

dav1d



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!