44 s.insert(s.begin(),
char(
'0' + n % 10));
61 if (!std::meta::has_identifier(ent))
63 for (std::meta::info p{std::meta::parent_of(ent)};
64 p != std::meta::info{} && p != ^^::; p = std::meta::parent_of(p))
65 if (!std::meta::has_identifier(p))
75 if (std::meta::has_identifier(ent))
76 tail = std::meta::identifier_of(ent);
77 for (std::meta::info p{std::meta::parent_of(ent)};
78 p != std::meta::info{} && p != ^^:: && std::meta::has_identifier(p);
79 p = std::meta::parent_of(p))
80 tail = std::string{std::meta::identifier_of(p)} +
"::" + tail;
88 if (std::meta::has_identifier(type))
89 s = std::meta::identifier_of(type);
90 for (std::meta::info p{std::meta::parent_of(type)};
91 p != std::meta::info{} && p != ^^:: && std::meta::has_identifier(p);
92 p = std::meta::parent_of(p))
93 s = std::string{std::meta::identifier_of(p)} +
"_" + s;
94 return s +
"_trampoline";
105 std::string s{std::meta::display_string_of(std::meta::type_of(fn))};
106 return s.find(
"...") != std::string::npos;
113 if (std::meta::is_const(fn))
115 if (std::meta::is_volatile(fn))
117 if (std::meta::is_lvalue_reference_qualified(fn))
119 if (std::meta::is_rvalue_reference_qualified(fn))
121 if (std::meta::is_noexcept(fn))
128 "::welder::rods::trampolines::generated"};
141 s +=
"struct " + ident +
" : " + base +
" {\n";
142 s +=
" WELDER_PY_TRAMPOLINE(" + ident +
", " + base +
");\n";
146 const std::string name{std::meta::identifier_of(slot)};
148 s +=
" static_assert(false, \"welder: '" + base +
"::" + name +
149 "' is a C-variadic virtual; C++26 reflection cannot reproduce its "
150 "'...' parameter. Mark it "
151 "[[=welder::bind_flat]] to bind it non-overridably.\");\n";
156 const std::string idx{
"::welder::overridable_virtuals(^^" + base +
158 s +=
" [: ::std::meta::return_type_of(" + idx +
") :] " + name +
"(";
161 for (
auto p : std::meta::parameters_of(slot)) {
168 s +=
"[: ::std::meta::type_of(::std::meta::parameters_of(" + idx +
")[" +
178 idx +
"), " + name + (args.empty() ?
"" :
", " + args) +
"); }\n";
187 return "template <> constexpr ::std::meta::info\n"
188 " ::welder::rods::python::trampoline_for<" +
206 template <std::meta::info Type>
214 static_assert(std::meta::has_identifier(Type),
215 "welder: cannot generate a trampoline for a class-template "
216 "specialization spelled directly (it has no identifier); "
217 "declare a namespace-scope alias — using IntRing = "
218 "Ring<int>; — and weld that instead");
225 "welder: cannot generate a trampoline for a type nested inside a "
226 "class-template specialization (its enclosing scope cannot be "
227 "respelled from reflection). Hand-write the trampoline, spelling "
228 "the base through the welding alias (e.g. `struct PyValve : "
229 "IntSilo::Valve { … }` with a trampoline_for specialization), or "
230 "annotate the type [[=welder::bind_flat]].");
238 out +=
"#pragma once\n";
239 out +=
"// AUTO-GENERATED by welder (welder::rods::trampolines). Do not edit.\n";
241 out +=
"// Include AFTER your welded type headers and the active backend's\n";
242 out +=
"// <welder/rods/python/{pybind11,nanobind}/trampoline.hpp>.\n";
243 out +=
"#include <meta>\n";
244 out +=
"#include <welder/rods/python/trampoline.hpp>\n\n";
245 out +=
"namespace welder::rods::trampolines::generated {\n\n";
247 out +=
"\n} // namespace welder::rods::trampolines::generated\n\n";
consteval std::string cpp_qualified_name(std::meta::info ent)
The fully ::-qualified name of a namespace-scope entity, leading :: included (geometry::Point → "geom...
consteval std::string render_trampoline(std::meta::info type)
Render the trampoline struct for welded virtual type type — one override per overridable virtual,...
consteval bool is_c_variadic(std::meta::info fn)
Is fn a C-style variadic function (R(…, ...))?
consteval bool cpp_spellable(std::meta::info ent)
Is ent spellable as a fully-qualified C++ name — itself and every enclosing scope up to the global na...
consteval std::string int_string(std::size_t n)
Render a non-negative integer as decimal (constexpr std::to_string is not available on gcc-16 in a co...
constexpr const char * generated_namespace
The namespace the generated trampoline structs are emitted into (fully qualified).
consteval std::string render_registration(std::meta::info type)
The trampoline_for<type> specialization pointing at type's generated struct.
consteval std::string trampoline_ident(std::meta::info type)
A collision-free identifier for type's generated trampoline: its qualified name with :: folded to _ (...
consteval std::string qualifier_tokens(std::meta::info fn)
The trailing cv / ref-qualifier / noexcept tokens of a member function fn, in grammatical order (" co...
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 vir...
The growing generated header: the trampoline struct bodies and their trampoline_for registrations,...
std::string structs
Accumulated trampoline struct definitions.
std::string render() const
The finished, self-contained header text.
void add()
Append the generated trampoline + registration for welded virtual Type.
std::string registrations
Accumulated trampoline_for specializations.
Virtual-function overriding support shared by welder's Python backends.