Implementation of protocol using GCC 16's C++26 reflection#95
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.
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.