welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
trampoline.hpp
Go to the documentation of this file.
1#pragma once
2#include <cstddef>
3#include <meta>
4#include <string_view>
5#include <vector>
6
7#include <welder/diag.hpp> // the consteval diagnostics (no_matching_virtual_slot)
8#include <welder/virtuals.hpp> // the neutral slot machinery (welder::virtual_slot, ...)
9#include <welder/vocabulary.hpp> // the annotation vocabulary (for structural specs)
10
48
49namespace welder::inline v0::rods::python {
50
51// The backend-neutral slot machinery (bind_flat, overridable_virtuals,
52// virtual_slot, ...) is language-neutral — the C# rod's directors consume the
53// same answers — and lives at welder:: scope in <welder/virtuals.hpp> (spell
54// it [[=welder::bind_flat]], welder::virtual_slot(...), ...).
55
56// --- trampoline registration -------------------------------------------------
57
72template <class T>
73constexpr std::meta::info trampoline_for = std::meta::info{};
74
75// --- trampoline discovery by annotation -------------------------------------
76
80
92inline constexpr trampoline_spec trampoline{};
93
97consteval bool is_trampoline(std::meta::info type) {
98 return !std::meta::annotations_of_with_type(type, ^^trampoline_spec).empty();
99}
100
104 std::meta::info type{};
105 bool ambiguous{false};
106};
107
117consteval scanned_trampoline scanned_trampoline_of(std::meta::info base) {
118 scanned_trampoline result{};
119 for (auto mem : std::meta::members_of(std::meta::parent_of(base),
120 std::meta::access_context::current())) {
121 if (mem == base || !std::meta::is_type(mem) || !is_trampoline(mem))
122 continue;
123 for (auto b :
124 std::meta::bases_of(mem, std::meta::access_context::current())) {
125 if (std::meta::dealias(std::meta::type_of(b)) ==
126 std::meta::dealias(base)) {
127 if (result.type != std::meta::info{})
128 result.ambiguous = true;
129 else
130 result.type = mem;
131 break;
132 }
133 }
134 }
135 return result;
136}
137
151template <class T>
152consteval std::meta::info construction_type_of() {
153 if (trampoline_for<T> != std::meta::info{})
154 return trampoline_for<T>;
155 // Only a virtual type can carry a trampoline — skip the namespace scan otherwise.
156 if (has_virtual_methods(^^T))
157 if (auto scanned{scanned_trampoline_of(^^T)};
158 scanned.type != std::meta::info{})
159 return scanned.type;
160 return ^^T;
161}
162
179consteval bool declares_override(std::meta::info tramp, std::meta::info vfn) {
180 auto name{std::meta::identifier_of(vfn)};
181 auto sig{std::meta::type_of(vfn)};
182 for (auto m :
183 std::meta::members_of(tramp, std::meta::access_context::unchecked())) {
184 if (std::meta::is_function(m) && !std::meta::is_special_member_function(m) &&
185 std::meta::identifier_of(m) == name && std::meta::type_of(m) == sig) {
186 return true;
187 }
188 }
189 return false;
190}
191
203consteval bool trampoline_covers(std::meta::info type, std::meta::info tramp) {
204 for (auto m : overridable_virtuals(type))
205 if (!declares_override(tramp, m))
206 return false;
207 return true;
208}
209
210} // namespace welder::rods::python
welder's consteval diagnostics, collected in one place: every hand-rolled compile-time error the libr...
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 namespac...
consteval bool trampoline_covers(std::meta::info type, std::meta::info tramp)
Does tramp override every virtual method of type — inherited ones included?
constexpr trampoline_spec trampoline
Mark a class as the trampoline for the base it derives from — the annotation form of trampoline_for.
consteval bool declares_override(std::meta::info tramp, std::meta::info vfn)
Does trampoline declare an override for the virtual method vfn?
consteval std::meta::info construction_type_of()
The type welder constructs when binding T: its registered/annotated trampoline if one exists,...
constexpr std::meta::info trampoline_for
The trampoline subclass registered for T, or a null reflection if none.
consteval bool has_virtual_methods(std::meta::info type)
Does type declare or inherit any overridable virtual method?
Definition virtuals.hpp:239
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...
Definition virtuals.hpp:174
The outcome of scanning a base's namespace for its trampoline-annotated subclass.
bool ambiguous
true iff more than one candidate was found.
std::meta::info type
the trampoline, or a null reflection if none found.
The stored form of a trampoline mark (a plain tag — it carries no state).
welder's backend-neutral virtual-slot machinery: which virtual member functions of a type are overrid...
welder's annotation vocabulary — the single header a consuming TU includes to get the markers it atta...