Are injections supposed to work?
Closed this issue · 3 comments
I get "error: expected injection" in examples and simple tests I've used. Are the injections supposed to be working? Other examples (like interfaces) are working fine.
$class the_future_is_now {
constexpr {
-> { int metaclasses_are_dope = 0; }
}
};
// Hopefully the names of the constructs reflect how excited I am about the proposal. Pun intended.
Looking at the latest version of the proposal, it doesn't seem to have working examples for the injection syntax yet. Multiple examples in chapter three have links to compiling versions on cppx.godbolt.org, but those versions never use the arrow ->
. Here's also an explicit note from that paper :
Note: This example (and quite a few others) will not compile in the prototype compiler yet for a number of incompleteness reasons, but here in particular because this code uses concepts and Clang does not yet have concepts.
Looking at the other issues on this fork, there seem to be some cases where the arrow ->
works like you'll see in the example below.
So basically, the part of injections that seem to work right now are those :
$class mc
{
mc() {/*do something*/}
void f() {/*do something*/}
-> class { int g() { return 0; } }
constexpr {
for... (auto m : $S2.member_variables())
-> [m] class { int declname("get_" m.name())() const; } // current cppx.godbolt.org version
-> class { int idexpr("get_", m.name())() const {return idexpr(m.name());} }; // current master branch version
}
};
You'll notice in the last injection example, there are two important things before the scope which contain the injection : a capture list (issue #29 is meant to make this obsolete) and the keyword class seems to inform the compiler of the context where we want to inject the code.
Here's the current grammar for injections :
injection-statement:
'->' injection-capture_opt injection
'->' constant-expression ';'
injection-capture:
'[' identifier-list ']'
injection:
'do' compound-statement
class-key identifier_opt '{' member-specification_opt '}'
'namespace' identifier_opt '{' namespace-body '}'
compound-statement
Thank you for the clarification. I went through the commits and it seems the currently supported syntax is the following:
-> do { int test; }
-> class C { /* ... */ }
These seem to be represented as lambdas underneath. With captures in the form of
-> [x] do { /* ... */ }
So far my experiments with the injections that rely on class variables have failed.
You can find more examples in the tests that were written for the prototype (clang/test/CXX/meta/).
Good day
edit: It seems I missed your edit :)
There has been a rewrite that was published just yesterday and which changes a few things and improves the code injection mechanism. Here's some example code I just compiled successfully :
$class MyClass
{
constexpr {
for... (auto m : $prototype.member_variables())
-> class { private: int idexpr(m.name()); public: int idexpr("get_", m.name())() const {
return idexpr(m.name());
}
};
}
}
MyClass test
{
int a, b, c;
};
constexpr {
compiler.debug($test);
}
int main() {}
Notice that in order to loop over the members, instead of using $MyClass
, it is now $prototype
.