Previously the generated client declared a default-constructed result variable
and passed a reference to it into clientInvoke, requiring the return type to be
default-constructible. Restructure the client return path so the value is
constructed directly in place:
- clientInvoke takes the return type and result Accessor as explicit template
arguments (defaulting to void). It deserializes the result with ReadField
into a ReadDestTemp, so the value is built from constructor arguments without
a default constructor.
- Propagate the value as a prvalue: IterateFieldsHelper::handleChain now returns
decltype(auto), and the movable path uses C++17 guaranteed copy elision to
construct the result in AlignedStorage.
- For non-movable return types (no move or copy constructor), copy the capnp
response to a flat word buffer on the event-loop thread and deserialize it on
the client thread, returning a prvalue via guaranteed copy elision so no move
constructor is ever needed.
Add AlignedStorage<T>, a typed wrapper around an aligned byte buffer with a
ptr() accessor, used immediately by clientInvoke and reused later by TryFinally.
Extend FunctionTraits to all four PMF cv-qualifier combinations so clientInvoke
can derive the capnp Results type from the request method pointer.
The code generator emits clientInvoke<Result, Accessor>(...) for non-void
methods and plain clientInvoke(...) for void methods.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>