welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
trampoline.hpp File Reference

nanobind's half of welder's virtual-override support: the reflection-driven dispatch helper that replaces NB_OVERRIDE / NB_OVERRIDE_PURE, and the WELDER_PY_TRAMPOLINE / WELDER_PY_OVERRIDE authoring macros. More...

#include <cstddef>
#include <meta>
#include <type_traits>
#include <utility>
#include <welder/rods/python/trampoline.hpp>
#include <nanobind/nanobind.h>
#include <nanobind/trampoline.h>
Include dependency graph for trampoline.hpp:

Go to the source code of this file.

Namespaces

namespace  welder
namespace  welder::rods
namespace  welder::rods::nanobind

Macros

#define WELDER_PY_TRAMPOLINE(BASE)
 Declare a class a nanobind trampoline for BASE.
#define WELDER_PY_OVERRIDE_AS(SLOT, FUNC, ...)
 Body of a single virtual override in a WELDER_PY_TRAMPOLINE class, keyed on an explicit slot reflection.
#define WELDER_PY_OVERRIDE(FUNC, ...)
 Body of a single virtual override in a WELDER_PY_TRAMPOLINE class.

Functions

template<auto Fn, std::size_t N, typename BaseCall, typename... Args>
decltype(auto) welder::rods::nanobind::override_dispatch (const nb::detail::trampoline< N > &tr, BaseCall &&base_call, Args &&... args)
 Dispatch a captured virtual call to its Python override, else to the C++ base.

Detailed Description

nanobind's half of welder's virtual-override support: the reflection-driven dispatch helper that replaces NB_OVERRIDE / NB_OVERRIDE_PURE, and the WELDER_PY_TRAMPOLINE / WELDER_PY_OVERRIDE authoring macros.

The backend-neutral machinery (slot count, the trampoline_for registration hook, the coverage check) lives in <welder/rods/python/trampoline.hpp>. This header only adds what is specific to nanobind's runtime: its detail::trampoline storage and detail::ticket lookup. The macros are spelled the same as pybind11's (a translation unit includes exactly one Python rod), so a single trampoline definition compiles under either backend.

Include this from a nanobind binding translation unit before the header that defines your trampoline subclass.

Definition in file trampoline.hpp.

Macro Definition Documentation

◆ WELDER_PY_OVERRIDE

#define WELDER_PY_OVERRIDE ( FUNC,
... )
Value:
WELDER_PY_OVERRIDE_AS(^^welder_py_base::FUNC, FUNC __VA_OPT__(, ) __VA_ARGS__)
#define WELDER_PY_OVERRIDE_AS(SLOT, FUNC,...)
Body of a single virtual override in a WELDER_PY_TRAMPOLINE class, keyed on an explicit slot reflecti...

Body of a single virtual override in a WELDER_PY_TRAMPOLINE class.

Use as the whole override body: int legs() const override { WELDER_PY_OVERRIDE(legs); }. Forwards to the Python override of FUNC if present, else to BASE::FUNC. Extra arguments are the method's parameters, forwarded to both paths. FUNC must name a single* virtual — for an overloaded one use WELDER_PY_OVERRIDE_AS with a welder::rods::python::virtual_slot selection. Neutral name: each Python rod defines it against its own dispatch.

Definition at line 125 of file trampoline.hpp.

◆ WELDER_PY_OVERRIDE_AS

#define WELDER_PY_OVERRIDE_AS ( SLOT,
FUNC,
... )
Value:
return ::welder::rods::nanobind::override_dispatch<(SLOT)>( \
this->welder_nb_trampoline, \
[&](auto&&... _welder_a) -> decltype(auto) { \
return welder_py_base::FUNC( \
static_cast<decltype(_welder_a)&&>(_welder_a)...); \
} __VA_OPT__(, ) __VA_ARGS__)

Body of a single virtual override in a WELDER_PY_TRAMPOLINE class, keyed on an explicit slot reflection.

The general form behind WELDER_PY_OVERRIDE, for the case the plain macro cannot spell: an overloaded virtual, where ^^welder_py_base::FUNC would name an overload set (ill-formed — P2996 has no overload-set reflection). SLOT is a reflection of the one base virtual this override implements — select it with welder::rods::python::virtual_slot — and drives the dispatch (name, return type, pureness); the textual FUNC only spells the qualified base-class fallback call, where ordinary overload resolution picks the right overload from the forwarded parameters. Parenthesize SLOT if the expression contains commas. welder's generated trampolines use this form for every override.

Definition at line 109 of file trampoline.hpp.

◆ WELDER_PY_TRAMPOLINE

#define WELDER_PY_TRAMPOLINE ( BASE)
Value:
using welder_py_base = BASE; \
using welder_py_base::welder_py_base; \
::nanobind::detail::trampoline< \
::welder::rods::python::virtual_slot_count(^^BASE)> \
welder_nb_trampoline{this}

Declare a class a nanobind trampoline for BASE.

Place at the top of a trampoline subclass body. Introduces the welder_py_base alias the override macro keys off, inherits BASE's constructors, and adds the nanobind trampoline storage sized by reflection — the N in the slot count never drifts from BASE's virtuals. Neutral name: pybind11's rod defines the same macro without a storage member.

Definition at line 90 of file trampoline.hpp.