welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
welder::rods::python Namespace Reference

Namespaces

namespace  detail

Classes

struct  bind_flat_spec
 The stored form of a bind_flat mark (a plain tag — it carries no state). More...
struct  google_style
 Google-style docstring assembly (the default). More...
struct  numpy_style
 NumPy-style docstring assembly (numpydoc). More...
struct  pep8
 PEP 8 naming: CapWords (PascalCase) for classes and enum types, snake_case for everything callable or data — methods, static methods, free functions, data members (properties), namespace variables — and submodules. More...
struct  scanned_trampoline
 The outcome of scanning a base's namespace for its trampoline-annotated subclass. More...
struct  sphinx_style
 Sphinx-style docstring assembly (reStructuredText field lists). More...
struct  trampoline_spec
 The stored form of a trampoline mark (a plain tag — it carries no state). More...

Functions

consteval const char * operator_dunder (std::meta::info f)
 The Python special-method ("dunder") name for a member operator, or nullptr if welder does not expose that operator.
consteval bool bound_flat (std::meta::info entity)
 Does entity (a type or a member function) carry a bind_flat mark?
consteval bool is_trampoline (std::meta::info type)
 Does type carry a trampoline mark?
consteval scanned_trampoline scanned_trampoline_of (std::meta::info base)
 Find the trampoline-annotated class deriving directly from base by scanning base's enclosing namespace.
consteval bool is_overridable_virtual (std::meta::info member)
 Is member an overridable virtual — a virtual member function that welder routes through the trampoline?
consteval std::vector< std::meta::info > overridable_virtuals (std::meta::info type)
 Every overridable virtual slot of type — the ones welder routes through a trampoline — folding in virtuals inherited from any base.
consteval std::meta::info virtual_slot (std::meta::info type, std::string_view name, std::meta::info fn_type)
 The overridable virtual slot of type named name whose function type is fn_type — the hand-written disambiguator for an overloaded virtual.
consteval std::size_t virtual_slot_count (std::meta::info type)
 The number of overridable virtual member functions of type, inherited ones included.
consteval bool has_virtual_methods (std::meta::info type)
 Does type declare or inherit any overridable virtual method?
template<class T>
consteval std::meta::info construction_type_of ()
 The type welder constructs when binding T: its registered/annotated trampoline if one exists, else T itself.
consteval bool declares_override (std::meta::info tramp, std::meta::info vfn)
 Does trampoline declare an override for the virtual method vfn?
consteval bool trampoline_covers (std::meta::info type, std::meta::info tramp)
 Does tramp override every virtual method of type — inherited ones included?

Variables

constexpr bind_flat_spec bind_flat {}
 Mark a virtual entity as deliberately bound non-overridably.
template<class T>
constexpr std::meta::info trampoline_for = std::meta::info{}
 The trampoline subclass registered for T, or a null reflection if none.
constexpr trampoline_spec trampoline {}
 Mark a class as the trampoline for the base it derives from — the annotation form of trampoline_for.

Function Documentation

◆ bound_flat()

bool welder::rods::python::bound_flat ( std::meta::info entity)
consteval

Does entity (a type or a member function) carry a bind_flat mark?

Parameters
entitya reflection of the type or member to test.
Returns
true iff entity opts out of trampoline / override routing.

Definition at line 83 of file trampoline.hpp.

Referenced by is_overridable_virtual(), welder::rods::trampolines::rod::make_class(), and overridable_virtuals().

◆ construction_type_of()

template<class T>
std::meta::info welder::rods::python::construction_type_of ( )
consteval

The type welder constructs when binding T: its registered/annotated trampoline if one exists, else T itself.

A rod exposes this (as construction_type<T>) so the driver decides constructibility against the concrete trampoline rather than T. That matters for an abstract base: std::is_default_constructible_v<T> is false, so the driver would register no constructor and a Python subclass could not be instantiated — but the trampoline is constructible, so binding it keeps the subclass usable. For a concrete T the trampoline is constructible exactly when T is, so the substitution changes nothing.

Template Parameters
Tthe welded type.
Returns
a reflection of the trampoline type (registered via trampoline_for or discovered via the trampoline annotation), or of T if none.

Definition at line 359 of file trampoline.hpp.

References has_virtual_methods(), scanned_trampoline_of(), and trampoline_for.

◆ declares_override()

bool welder::rods::python::declares_override ( std::meta::info tramp,
std::meta::info vfn )
consteval

Does trampoline declare an override for the virtual method vfn?

A trampoline overrides vfn by redeclaring a member function with the same name and the same signature; members_of lists a class's own members (not inherited ones), so an un-overridden virtual is simply absent. Matching is by name plus type_of equality — the reflected function type, which bundles the parameter types, cv-qualification, and ref-qualifier (independent of the declaring class). That distinguishes a real override from an unrelated same-named overload or a const/ref-qualifier mismatch, which name-plus-arity alone would not.

Note
The slot vfn is the most-derived declaration (overridable_virtuals), so for a covariant chain the trampoline redeclares the narrowed signature — which is what a hand-written override must spell anyway.
Parameters
trampa reflection of the trampoline subclass.
vfna reflection of a base virtual member function.
Returns
true iff tramp redeclares vfn with a matching signature.

Definition at line 386 of file trampoline.hpp.

Referenced by trampoline_covers().

◆ has_virtual_methods()

bool welder::rods::python::has_virtual_methods ( std::meta::info type)
consteval

Does type declare or inherit any overridable virtual method?

Parameters
typea reflection of the class type.
Returns
true iff type has at least one overridable virtual slot.

Definition at line 341 of file trampoline.hpp.

References overridable_virtuals().

Referenced by construction_type_of().

◆ is_overridable_virtual()

bool welder::rods::python::is_overridable_virtual ( std::meta::info member)
consteval

Is member an overridable virtual — a virtual member function that welder routes through the trampoline?

Excludes the (virtual) destructor, which is not an overridable slot, and any method marked bind_flat, which is bound as a plain non-overridable method. A per-declaration predicate; the whole-type slot set is overridable_virtuals, which additionally folds inherited virtuals in.

Parameters
membera reflection of a class member.
Returns
true iff member is a virtual method exposed for Python override.

Definition at line 180 of file trampoline.hpp.

References bound_flat().

◆ is_trampoline()

bool welder::rods::python::is_trampoline ( std::meta::info type)
consteval

Does type carry a trampoline mark?

Parameters
typea reflection of the class to test.
Returns
true iff type is annotated as a trampoline.

Definition at line 128 of file trampoline.hpp.

Referenced by scanned_trampoline_of().

◆ operator_dunder()

const char * welder::rods::python::operator_dunder ( std::meta::info f)
consteval

The Python special-method ("dunder") name for a member operator, or nullptr if welder does not expose that operator.

Unary vs binary is told apart by arity (a member operator takes 0 parameters when unary, 1 when binary), disambiguating the operators that have both forms (+, -). In-place compound assignments (operator+=, …) are intentionally not mapped: Python already falls back to the binary form (a += ba = a + b via __add__) with correct value semantics, and binding __iadd__ faithfully would need a reference return policy. Likewise <=>, &&, ||, ++, -- and = have no clean reflection-driven Python mapping yet.

Parameters
fa reflection of the operator function.
Returns
the dunder name (static storage), or nullptr.

Definition at line 39 of file operators.hpp.

References welder::detail::is_unary_operator().

Referenced by welder::rods::nanobind::rod< DocStyle >::add_operator(), and welder::rods::pybind11::rod< DocStyle >::add_operator().

◆ overridable_virtuals()

std::vector< std::meta::info > welder::rods::python::overridable_virtuals ( std::meta::info type)
consteval

Every overridable virtual slot of type — the ones welder routes through a trampoline — folding in virtuals inherited from any base.

Unlike a bare members_of scan this sees a virtual type only inherits (never re-declares), which a trampoline must still cover: a Python subclass of type can override it, and dispatch runs through type's own trampoline, not the base's. A slot is its vtable identity — name + parameter types + cv/ref qualifiers, so a covariant** override is the same slot, kept with its narrowed return type; when a class overrides an inherited virtual, only the most-derived declaration is kept, and its bind_flat mark (not the base's) decides whether the slot is exposed. Protected** virtuals (the NVI hook pattern) are slots like any other — a Python subclass overrides them by plain attribute lookup, no binding involved. Private declarations are excluded: the trampoline's base-class fallback could not name them; a subclass privatizing an inherited virtual thereby withdraws the slot.

Parameters
typea reflection of the class type.
Returns
the most-derived declaration of each exposed overridable virtual.

Definition at line 276 of file trampoline.hpp.

References bound_flat(), and welder::rods::python::detail::collect_virtuals().

Referenced by has_virtual_methods(), welder::rods::trampolines::rod::make_class(), welder::rods::trampolines::render_trampoline(), trampoline_covers(), virtual_slot(), and virtual_slot_count().

◆ scanned_trampoline_of()

scanned_trampoline welder::rods::python::scanned_trampoline_of ( std::meta::info base)
consteval

Find the trampoline-annotated class deriving directly from base by scanning base's enclosing namespace.

The discovery half of the annotation form (trampoline): with no global type enumeration in reflection, a trampoline is reachable from its base only by scanning a known scope — here base's own namespace. Zero matches → a null reflection; two or more → scanned_trampoline::ambiguous (resolve with trampoline_for).

Parameters
basea reflection of the welded base type.
Returns
the scan outcome.

Definition at line 148 of file trampoline.hpp.

References welder::rods::python::scanned_trampoline::ambiguous, is_trampoline(), and welder::rods::python::scanned_trampoline::type.

Referenced by construction_type_of().

◆ trampoline_covers()

bool welder::rods::python::trampoline_covers ( std::meta::info type,
std::meta::info tramp )
consteval

Does tramp override every virtual method of type — inherited ones included?

The coverage guard behind welder's compile-time check: a virtual left un-overridden would bind, but calls to it from C++ would never dispatch into a Python override. Iterates overridable_virtuals, so a virtual type merely inherits* must also be redeclared in tramp (its dispatch runs through type's own trampoline, not the base's). tramp is scanned by declares_override, which lists tramp's own members — so the trampoline is expected to redeclare every override itself, inherited slots included.

Parameters
typea reflection of the welded base type.
trampa reflection of its registered trampoline.
Returns
true iff every overridable virtual of type is redeclared in tramp.

Definition at line 410 of file trampoline.hpp.

References declares_override(), and overridable_virtuals().

◆ virtual_slot()

std::meta::info welder::rods::python::virtual_slot ( std::meta::info type,
std::string_view name,
std::meta::info fn_type )
consteval

The overridable virtual slot of type named name whose function type is fn_type — the hand-written disambiguator for an overloaded virtual.

^^Base::fn is ill-formed when fn names an overload set (P2996 has no overload-set reflection), so WELDER_PY_OVERRIDE(fn) cannot be used inside the override of an overloaded virtual. This finder selects one overload by its exact function type, for the slot-taking macro form:

std::string send(int code) const override {
(welder::rods::python::virtual_slot(^^Robot, "send", ^^std::string(int) const)),
send, code);
}
consteval std::meta::info virtual_slot(std::meta::info type, std::string_view name, std::meta::info fn_type)
The overridable virtual slot of type named name whose function type is fn_type — the hand-written dis...
#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...

(The extra parentheses keep any commas inside the expression out of the preprocessor's argument splitting.) Searches overridable_virtuals, so inherited slots are found too.

Parameters
typea reflection of the welded type.
namethe virtual's identifier.
fn_typea reflection of the overload's full function type, trailing qualifiers included (e.g. ^^int(int) const).
Returns
the matching slot's reflection.
Exceptions
diag::no_matching_virtual_slot(a constant-evaluation error) when no slot matches the name/type pair.

Definition at line 315 of file trampoline.hpp.

References overridable_virtuals().

◆ virtual_slot_count()

std::size_t welder::rods::python::virtual_slot_count ( std::meta::info type)
consteval

The number of overridable virtual member functions of type, inherited ones included.

This is the N in NB_TRAMPOLINE(Base, N) / a trampoline's slot count — the virtuals actually routed through the trampoline, so per-method bind_flat marks (and the destructor) are excluded. Counts inherited virtuals too (see overridable_virtuals), so a subclass whose virtuals all come from a base still reports a non-zero count and gets a correctly sized trampoline.

Parameters
typea reflection of the class type.
Returns
the count of type's overridable virtual member functions.

Definition at line 334 of file trampoline.hpp.

References overridable_virtuals().

Variable Documentation

◆ bind_flat

bind_flat_spec welder::rods::python::bind_flat {}
inlineconstexpr

Mark a virtual entity as deliberately bound non-overridably.

Usage: [[=welder::rods::python::bind_flat]]. Two granularities:

  • On a type: the whole type is bound non-overridably (produced by C++, never subclassed in Python) — no trampoline is required, and none of its virtuals are exposed for Python override.
  • On a member function: only that virtual is bound flat — it stays a plain bound method, drops out of the trampoline's slot count and coverage requirement, while the type's other virtuals remain overridable. Useful to exclude a single virtual (e.g. one returning a reference) from override routing.

Without it, every welded type carrying an overridable virtual must register a trampoline via trampoline_for, or welder's Python rods reject it at compile time.

See also
bind_flat_spec

Definition at line 78 of file trampoline.hpp.

◆ trampoline

trampoline_spec welder::rods::python::trampoline {}
inlineconstexpr

Mark a class as the trampoline for the base it derives from — the annotation form of trampoline_for.

Usage: struct [[=welder::rods::python::trampoline]] PyAnimal : Animal { … };. welder infers the base from the trampoline's own base list and discovers the trampoline by scanning that base's namespace (see scanned_trampoline_of), so no explicit T → trampoline mapping is written. Requires the trampoline to live in the same namespace as its welded base (reflection offers no global type enumeration, so discovery must scan a known scope). For a third-party base, a trampoline kept in a different namespace, or to disambiguate, specialize trampoline_for instead — it wins when both are present.

See also
trampoline_spec

Definition at line 123 of file trampoline.hpp.

◆ trampoline_for

template<class T>
std::meta::info welder::rods::python::trampoline_for = std::meta::info{}
constexpr

The trampoline subclass registered for T, or a null reflection if none.

Specialize this in the binding translation unit — where the concrete, backend-specific trampoline is defined — to tell welder's Python rods to bind class_<T, Trampoline> so Python subclasses can override T's virtual methods:

template <> constexpr std::meta::info
constexpr std::meta::info trampoline_for
The trampoline subclass registered for T, or a null reflection if none.

It is the type-level counterpart of welder::trust_bindable — a hook usable even for third-party types you cannot annotate, and it takes precedence over the annotation form (trampoline).

Template Parameters
Tthe welded type.

Definition at line 104 of file trampoline.hpp.

Referenced by construction_type_of().