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

pybind11's half of welder's virtual-override support: the reflection-driven dispatch helper that replaces PYBIND11_OVERRIDE / PYBIND11_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 <pybind11/pybind11.h>
Include dependency graph for trampoline.hpp:

Go to the source code of this file.

Namespaces

namespace  welder
namespace  welder::rods
namespace  welder::rods::pybind11

Macros

#define WELDER_PY_TRAMPOLINE(BASE)
 Declare a class a pybind11 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, typename Self, typename BaseCall, typename... Args>
decltype(auto) welder::rods::pybind11::override_dispatch (const Self &self, BaseCall &&base_call, Args &&... args)
 Dispatch a captured virtual call to its Python override, else to the C++ base.

Detailed Description

pybind11's half of welder's virtual-override support: the reflection-driven dispatch helper that replaces PYBIND11_OVERRIDE / PYBIND11_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 pybind11: get_override lookup and cast_safe. Unlike nanobind, pybind11 keeps no per-instance trampoline storage — the override is found from the C++ this pointer — so WELDER_PY_TRAMPOLINE injects only the base alias and inherited constructors. The macros are spelled the same as nanobind's (a translation unit includes exactly one Python rod), so a single trampoline definition compiles under either backend.

Include this from a pybind11 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 130 of file trampoline.hpp.

◆ WELDER_PY_OVERRIDE_AS

#define WELDER_PY_OVERRIDE_AS ( SLOT,
FUNC,
... )
Value:
return ::welder::rods::pybind11::override_dispatch<(SLOT)>( \
static_cast<const welder_py_base&>(*this), \
[&](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 114 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

Declare a class a pybind11 trampoline for BASE.

Place at the top of a trampoline subclass body. Introduces the welder_py_base alias the override macro keys off and inherits BASE's constructors. pybind11 needs no per-instance storage (the override is found from this), so — unlike the nanobind spelling — this adds no data member. Neutral name across the Python rods.

Definition at line 98 of file trampoline.hpp.