[SPLIT BEFORE MERGING] Implementation of protocol using GCC 16's C++26 reflection#95
[SPLIT BEFORE MERGING] Implementation of protocol using GCC 16's C++26 reflection#95jbcoe wants to merge 9 commits into
Conversation
fcafe99 to
61c971b
Compare
993309d to
1ce2b8b
Compare
…on in the reflection backend.
64301c2 to
0653e76
Compare
…scaping scheme, and clean up several confusing/inconsistent names in protocol_reflection.h.
|
|
||
| template <typename Interface, typename Owner, bool ConstOnly, | ||
| bool ForceConstCall> | ||
| struct named_forwarders { |
There was a problem hiding this comment.
So if I understand correctly, it seems that named_forwarders::type will end up looking something like this:
struct type {
[[no_unique_address]] forwarding_call<...> foo;
[[no_unique_address]] forwarding_call<...> bar;
// etc.
};And then bar will static_cast to void*, then to policy / policy_view.
I believe this approach is technically UB. It assumes that foo, bar, etc. all occupy the same memory address, but no_unique_address does not necessarily guarantee that.
The approach duck uses sidestepped this by making each one the first data member of a base class:
struct wrapper_1 {
[[no_unique_address]] forwarding_call<...> foo;
};
struct wrapper_2 {
[[no_unique_address]] forwarding_call<...> bar;
};
struct type : wrapper_1, wrapper_2 {};Which then allows casting from foo and bar to wrapper_1 and wrapper_2 via void* or reinterpret_cast, and then safely static_cast-ing to policy / policy_view.
But again, this is all really technicalities, and especially since this is a reference implementation, I'm not sure it is a necessary change. I just wanted to mention it here.
There was a problem hiding this comment.
Thanks. We’ve no reason to be different to Duck and should do exactly the same wherever possible. I’ll rework this.
|
|
||
| // Identifier-safe spelling for an operator kind, mirroring the intent of | ||
| // mangle_identifier in scripts/generate_protocol.py. | ||
| consteval std::string_view operator_spelling(std::meta::operators kind) { |
There was a problem hiding this comment.
You should be able to write a simple enum_to_string helper for this now, rather than the big switch-case. You could copy the implementation from the C++26 reflection proposal.
| explicit implementation_candidate_call(SelfPointer self) : self(self) {} | ||
|
|
||
| ReturnType operator()(ParameterTypes... parameters) const { | ||
| return self->[:Candidate:](std::forward<ParameterTypes>(parameters)...); |
There was a problem hiding this comment.
At a glance, I believe this may be discarding reference qualification, so rvalue-qualified members may not be found by overload resolution.
|
While this works, committing it as one large PR feels like a mistake. I'll build it up incrementally in smaller easy-to-digest pieces. |
|
Clarifying question--do lvalue/rvalue qualified interface members hold any significance? I know protocol propagates const, but is the underlying type an lvalue regardless of if protocol is an lvalue or rvalue? |
I'm not sure. We've not thought about this in DRAFT. I think that we should probably treat the underlying type as an rvalue when protocol is an rvalue. This will need some thought and work. |
Got it. For reference, duck does propagate rvalue-ness, but it brings some considerable implementation complexity. I can open an issue if that's helpful. |
Please do. This feels like the right approach. We can incorporate the complexity but it's an extension to what's currently in DRAFT so feels better as follow-up work. |
|
I've had a quick review of this for now, but I think this definitely could do with being broken down into constituent parts instead of being in one big header. Anyone coming to this will have a much easier time if the reflection header is split into files that reduce the scope and indicate the structure of the code. |
I agree. For instance, the generic reflection utilities, the vtable generation, and the wrappers that call into the vtable could all be separate files. There's probably even finer-grained lines that can be drawn if that still produces some monoliths. |
SPLIT BEFORE MERGING
Closes #94
Based on Duck by @RyanJK5
I anticipate that this will need significantly re-writing.
DRAFT.md is not yet updated and will be amended in a follow-up PR.