|
welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
|
The sol2 rod: a stateless policy type satisfying welder::rod. More...
#include <welder/rods/lua/sol2/rod.hpp>
Classes | |
| struct | session |
| Per-module session: the deferred state for live namespace variables. More... | |
| struct | _enum_binding |
| A welded enum's binding: the name→value table, how to mirror a name onto the enclosing scope, and whether the enum is scoped (an unscoped enum also mirrors its names onto the enclosing scope, like C++). More... | |
Public Types | |
| using | module_type = ::sol::table |
| A Lua module is a table. | |
| template<class T> | |
| using | class_handle_type = ::sol::usertype<T> |
| The class / enum handles the per-class / per-enum hooks operate on — exactly what make_class / make_enum return. | |
| template<class E> | |
| using | enum_handle_type = _enum_binding<E> |
Static Public Member Functions | |
| static consteval const char * | special_method_name (std::meta::info op_fn) |
| Map a member operator to its Lua metamethod name (nullptr = not exposed). | |
| template<class T, auto Bases, std::size_t... I> | |
| static auto | make_class (module_type &m, const char *name, const char *, std::index_sequence< I... >) |
| Create the sol::usertype<T> handle (constructors are installed by the driver's subsequent add_constructors call; doc has no Lua runtime home and is ignored). | |
| template<class T, auto Bases, std::size_t... I> | |
| static auto | make_nested_class (module_type &m, auto &outer, const char *name, const char *doc, std::index_sequence< I... > seq) |
| Create the sol::usertype<T> for a nested member type, placed on the enclosing type's usertype table (module.Outer.Inner) instead of the module. | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static void | add_constructors (::sol::usertype< T > &ut) |
| Install T's whole constructor set — exactly what sol2 wants (one sol::constructors<…> assignment covering the call form T(…) and the idiomatic T.new(…)), built from the driver-passed pieces. | |
| template<std::meta::info Mem, class Style = ::welder::naming::none> | |
| static void | add_field (auto &ut) |
| Bind data member Mem as a usertype property. | |
| template<auto Fns, class Style = ::welder::naming::none> | |
| static void | add_method (auto &ut) |
| Bind method overload group Fns as one method (obj:name(…)) — a single callable when unique, one sol::overload(…) when several (sol2 stores one value per table key). | |
| template<auto Fns, class Style = ::welder::naming::none> | |
| static void | add_static_method (auto &ut) |
| Bind static-method overload group Fns as a class-table function (T.name(…)), grouped as in add_method. | |
| template<auto Fns> | |
| static void | add_operator (auto &ut) |
| Bind operator overload group Fns under its Lua metamethod (one operator + arity per group; each overload is spliced, several same-slot overloads become one sol::overload(…)). | |
| template<class E> | |
| static auto | make_enum (module_type &m, const char *name, const char *) |
| Create the enum's Name = value table on the module (doc ignored). | |
| template<class E> | |
| static auto | make_nested_enum (module_type &m, auto &outer, const char *name, const char *) |
| Create the Name = value table for a nested member enum, placed on the enclosing type's usertype (module.Outer.Mode). | |
| template<std::meta::info Enum, class Style = ::welder::naming::none> | |
| static void | add_enumerator (auto &e) |
| Add enumerator Enum (as its underlying integer). | |
| template<class> | |
| static void | finish_enum (auto &) |
| No whole-enum finalizer needed (unscoped export is done per-enumerator). | |
| static session | open_module (module_type &) |
| Open a per-module session. | |
| static void | set_module_doc (module_type &, const char *) |
| No runtime module docstring in Lua (its home is a generated stub). | |
| template<auto Fns, class Style = ::welder::naming::none> | |
| static sol::object | add_function (module_type &m, const char *name=nullptr) |
| Bind free-function overload group Fns as one module-level function (a single callable, or one sol::overload(…); name from Fns[0]). | |
| template<std::meta::info Var, class Style = ::welder::naming::none> | |
| static void | add_variable (module_type &m, session &s, const char *name=nullptr) |
| Bind namespace variable Var onto the module. | |
| static module_type | add_submodule (module_type &m, const char *name) |
| Create a submodule table named name under m. | |
| static void | close_module (module_type &m, session &s) |
| Close the session: install the live-variable metatable proxy, if any mutable variable was welded onto m. | |
Static Public Attributes | |
| static constexpr lang | language {lang::lua} |
| welder::lang::lua. | |
| template<class T> | |
| static constexpr bool | has_native_caster = !_needs_registration<T> |
| caster_oracle: T converts without welder registering a usertype iff sol2 does not classify it as needs-registration. | |
Static Protected Member Functions | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static consteval std::vector< std::meta::info > | _ctor_signatures () |
| The set of sol::constructors<…> signatures to expose for T, as function- type reflections T(A...). | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static consteval auto | _ctor_sigs_array () |
| _ctor_signatures<T, …>() as a fixed-size, splice-ready static array. | |
| template<class T, auto Sigs, std::size_t... I> | |
| static void | _set_constructors (::sol::usertype< T > &ut, std::index_sequence< I... >) |
| Register T's constructor set on the usertype from the reflected signatures. | |
| template<class T, auto Bases, std::size_t... I> | |
| static auto | _make_usertype (::sol::table &m, const char *name, std::index_sequence< I... >) |
| Create m.new_usertype<T, Bases…>(name) with sol2's base-class linkage. | |
| static consteval void | _collect_welded_bases (std::meta::info type, lang L, std::vector< std::meta::info > &out) |
| Collect all welded ancestors of type (transitively), deduplicated. | |
| template<class T> | |
| static consteval auto | _welded_bases_array () |
| _collect_welded_bases for T as a fixed-size, splice-ready static array. | |
| template<auto Grp, class Target, std::size_t... I> | |
| static void | _register_named (Target &t, const char *name, std::index_sequence< I... >) |
| Register overload group Grp on target t under the (already name-styled) name — a single callable when unique, a sol::overload(…) when several. | |
| template<auto Grp, class Target, std::size_t... I> | |
| static void | _register_operator (Target &t, std::index_sequence< I... >) |
| Register operator group Grp under its Lua metamethod slot (a single callable, or a sol::overload(…) for several same-slot overloads). | |
| ::sol::object | _prev_index (::sol::this_state ts, const ::sol::object &prev, const ::sol::table &self, const ::sol::object &key) |
| Route a missing-key read on the module to a captured previous __index (function or table form), or nil when there was none. | |
| static void | _prev_newindex (const ::sol::object &prev, ::sol::table self, const ::sol::object &key, const ::sol::object &value) |
| Route a missing-key write on the module to a captured previous __newindex (function or table form); with none, do a raw set — the normal new-key assignment, raw so it does not recurse back through this metamethod. | |
| static void | _install_live_variables (module_type &m, ::sol::table getters, ::sol::table setters) |
| Install (or extend) the module table's metatable so absent keys in getters / setters read and write the underlying C++ globals live. | |
Static Protected Attributes | |
| template<class T> | |
| static constexpr bool | _needs_registration |
| Whether sol2 can only convert T via runtime usertype registration. | |
The sol2 rod: a stateless policy type satisfying welder::rod.
Its public static members are the sol2 emission primitives welder's driver calls; the driver supplies all the reflection-derived decisions. Each implements the correspondingly-named hook of the welder::rod contract (and welder::caster_oracle) — every one carries a @see back to it, where the shared parameter and return-value semantics are documented once rather than repeated on each backend's mirror. The protected members below are sol2-specific implementation helpers (prefixed _), not part of the contract; the operator→metamethod map lives in metamethods.hpp.
| using welder::rods::sol2::rod::class_handle_type = ::sol::usertype<T> |
The class / enum handles the per-class / per-enum hooks operate on — exactly what make_class / make_enum return.
Named as associated types so the welder::rod concept can shape-check the per-handle hooks against them (sol2's _enum_binding is an internal type, exposed here only through this alias).
| using welder::rods::sol2::rod::enum_handle_type = _enum_binding<E> |
| using welder::rods::sol2::rod::module_type = ::sol::table |
|
inlinestaticconstevalprotected |
Collect all welded ancestors of type (transitively), deduplicated.
sol2 differs from pybind11 here: sol::bases<…> must list every base class a usertype should upcast to / inherit members from, including indirect ones — it does not chain through an intermediate usertype's own bases. So where welder's core (native_base_types) collects only the nearest welded ancestors (enough for pybind11, which links each level to its own base), this walks past welded bases too, gathering the full closure. Non-welded bases are still descended through (their members are flattened by the driver); a virtual diamond reaches a shared base by several paths, so the list is deduplicated.
| type | a reflection of the derived type. | |
| L | the target language. | |
| [out] | out | accumulates the deduplicated welded-ancestor reflections. |
Definition at line 281 of file rod.hpp.
References _collect_welded_bases(), welder::public_bases(), and welder::welded_for().
Referenced by _collect_welded_bases(), and _welded_bases_array().
|
inlinestaticconstevalprotected |
The set of sol::constructors<…> signatures to expose for T, as function- type reflections T(A...).
Built from the pieces the DRIVER hands to add_constructors — the participating constructor reflections plus the default/aggregate flags — because sol2 wants the whole set in one assignment (aggregates ride C++26 parenthesized aggregate init). Each signature is a substituted, dealiased ctor_sig<T, Params…>.
| T | the class type. |
| Ctors | the participating constructor reflections. |
| HasDefault | whether the default constructor is exposed. |
| Aggregate | whether the synthesized field constructor is exposed. |
Definition at line 188 of file rod.hpp.
References welder::detail::aggregate_fields().
Referenced by _ctor_sigs_array().
|
inlinestaticconstevalprotected |
_ctor_signatures<T, …>() as a fixed-size, splice-ready static array.
Definition at line 212 of file rod.hpp.
References _ctor_signatures().
Referenced by add_constructors().
|
inlinestaticprotected |
Install (or extend) the module table's metatable so absent keys in getters / setters read and write the underlying C++ globals live.
Only absent keys trigger a metamethod, so this coexists with the module's ordinary entries (types, functions, snapshots, enum names) untouched — they are present keys and never reach here. Any metatable already on m (e.g. a prior live-variable install from another weld_* onto the same table) is chained: its __index/__newindex become the fallback, so earlier live variables keep working. A live key is deliberately never rawset, so it stays routed through the proxy across repeated reads and writes.
Definition at line 403 of file rod.hpp.
References _prev_index(), and _prev_newindex().
Referenced by close_module().
|
inlinestaticprotected |
Create m.new_usertype<T, Bases…>(name) with sol2's base-class linkage.
sol::no_constructor suppresses sol2's implicit constructor; the real set is installed by _register_constructors(). The base list is passed only when non-empty (sol2 accepts several bases, so multiple inheritance binds here).
| T | the class type. |
| Bases | the static array of native (welded) base type reflections. |
| I | the base index pack. |
| m | the module table. |
| name | the Lua type name. |
Definition at line 253 of file rod.hpp.
Referenced by make_class().
|
inlinestaticprotected |
Route a missing-key read on the module to a captured previous __index (function or table form), or nil when there was none.
Used as the fallback when the requested key is not one of our live getters.
Definition at line 368 of file rod.hpp.
Referenced by _install_live_variables().
|
inlinestaticprotected |
Route a missing-key write on the module to a captured previous __newindex (function or table form); with none, do a raw set — the normal new-key assignment, raw so it does not recurse back through this metamethod.
Definition at line 380 of file rod.hpp.
Referenced by _install_live_variables().
|
inlinestaticprotected |
Register overload group Grp on target t under the (already name-styled) name — a single callable when unique, a sol::overload(…) when several.
Each overload is spliced by its specific reflection, so &[:Grp[i]:] is the exact overload (no &C::f ambiguity). Serves methods, static methods and free functions alike (sol2 registers all three as a table entry). The caller passes the resolved name (via welder::name_of), since it varies by entity kind.
| Grp | the overload group (a static array of reflections). |
| Target | the sol2 usertype/table type to register onto. |
| I | the group index pack. |
| t | the usertype or module table to register onto. |
| name | the resolved target name (weld_as / style already applied). |
Definition at line 333 of file rod.hpp.
References welder::validate_return_policy().
Referenced by add_function(), add_method(), and add_static_method().
|
inlinestaticprotected |
Register operator group Grp under its Lua metamethod slot (a single callable, or a sol::overload(…) for several same-slot overloads).
| Grp | the operator overload group (a static array of reflections). |
| Target | the sol2 usertype type to register onto. |
| I | the group index pack. |
| t | the usertype to register the metamethod onto. |
Definition at line 354 of file rod.hpp.
References welder::rods::sol2::metamethod::fn, welder::rods::sol2::operator_mm(), and welder::validate_return_policy().
Referenced by add_operator().
|
inlinestaticprotected |
Register T's constructor set on the usertype from the reflected signatures.
| T | the class type. |
| Sigs | the static array of ctor_sig<T, …> reflections. |
| I | the signature index pack. |
| ut | the usertype to install the constructors on. |
Definition at line 233 of file rod.hpp.
Referenced by add_constructors().
|
inlinestaticconstevalprotected |
_collect_welded_bases for T as a fixed-size, splice-ready static array.
| T | the derived class type. |
Definition at line 304 of file rod.hpp.
References _collect_welded_bases(), and welder::lua.
Referenced by make_class().
|
inlinestatic |
Install T's whole constructor set — exactly what sol2 wants (one sol::constructors<…> assignment covering the call form T(…) and the idiomatic T.new(…)), built from the driver-passed pieces.
Definition at line 506 of file rod.hpp.
References _ctor_sigs_array(), and _set_constructors().
|
inlinestatic |
Add enumerator Enum (as its underlying integer).
An unscoped enum's enumerator is also mirrored onto the enclosing scope (the module, or a nested enum's outer class), unqualified — the driver's finish_enum role, done incrementally here since the handle carries the mirror.
Definition at line 608 of file rod.hpp.
References welder::name_of().
|
inlinestatic |
Bind data member Mem as a usertype property.
A mutable member becomes read/write; a const member is wrapped in sol::readonly (its setter would not compile). Lua has no property docstring, so a [[=welder::doc]] on the member is not surfaced at runtime (it belongs in a generated stub).
Definition at line 519 of file rod.hpp.
References welder::name_of().
|
inlinestatic |
Bind free-function overload group Fns as one module-level function (a single callable, or one sol::overload(…); name from Fns[0]).
A non-null name overrides the resolved name (including any weld_as), used verbatim; nullptr falls back to the styled/weld_as name.
Definition at line 641 of file rod.hpp.
References _register_named(), welder::function, language, and welder::name_of_or().
|
inlinestatic |
Bind method overload group Fns as one method (obj:name(…)) — a single callable when unique, one sol::overload(…) when several (sol2 stores one value per table key).
The name resolves from Fns[0].
Definition at line 543 of file rod.hpp.
References _register_named(), language, welder::method, and welder::name_of().
|
inlinestatic |
Bind operator overload group Fns under its Lua metamethod (one operator + arity per group; each overload is spliced, several same-slot overloads become one sol::overload(…)).
Definition at line 565 of file rod.hpp.
References _register_operator().
|
inlinestatic |
Bind static-method overload group Fns as a class-table function (T.name(…)), grouped as in add_method.
Definition at line 553 of file rod.hpp.
References _register_named(), language, welder::name_of(), and welder::static_method.
|
inlinestatic |
Create a submodule table named name under m.
|
inlinestatic |
Bind namespace variable Var onto the module.
A const/constexpr variable becomes a value snapshot — a plain table entry frozen at load time (it can never change, so the snapshot is exact). A mutable variable becomes a live get/set over the C++ global: its getter/setter closures are accumulated in s and close_module wires them into a metatable proxy, so Lua reads see the current C++ value and Lua writes flow back to it (matching the Python backends). To keep the key routed through the proxy it is deliberately not stored on the table (a present key would bypass __index).
A non-null name overrides the resolved name (including any weld_as), used verbatim; nullptr falls back to the styled/weld_as name.
Definition at line 661 of file rod.hpp.
References welder::rods::sol2::rod::session::getters, welder::rods::sol2::rod::session::has_live, language, welder::name_of_or(), welder::rods::sol2::rod::session::setters, and welder::variable.
|
inlinestatic |
Close the session: install the live-variable metatable proxy, if any mutable variable was welded onto m.
Definition at line 689 of file rod.hpp.
References _install_live_variables(), welder::rods::sol2::rod::session::getters, welder::rods::sol2::rod::session::has_live, and welder::rods::sol2::rod::session::setters.
|
inlinestatic |
No whole-enum finalizer needed (unscoped export is done per-enumerator).
|
inlinestatic |
Create the sol::usertype<T> handle (constructors are installed by the driver's subsequent add_constructors call; doc has no Lua runtime home and is ignored).
The driver's Bases is welder's nearest welded-ancestor set; sol2 needs the full transitive closure (see _collect_welded_bases), so this recomputes it from T and ignores the passed-in Bases.
Definition at line 474 of file rod.hpp.
References _make_usertype(), and _welded_bases_array().
Referenced by make_nested_class().
|
inlinestatic |
Create the enum's Name = value table on the module (doc ignored).
|
inlinestatic |
Create the sol::usertype<T> for a nested member type, placed on the enclosing type's usertype table (module.Outer.Inner) instead of the module.
sol2 has no scoped registration, so the usertype is created through the module table (which registers T's metatables in the Lua registry — the conversion machinery is name-independent), moved onto outer as a static entry, and the temporary module key cleared. The handle is a direct reference, so later member registration is unaffected by the move.
Definition at line 492 of file rod.hpp.
References welder::doc(), and make_class().
|
inlinestatic |
Create the Name = value table for a nested member enum, placed on the enclosing type's usertype (module.Outer.Mode).
The handle's mirror writes onto the OUTER, so an unscoped nested enum mirrors its names onto the class (Outer.quiet), like C++'s Outer::quiet.
|
inlinestatic |
Open a per-module session.
The live-variable registry tables are created lazily (on the first mutable variable), so a plain type/function module never allocates them.
|
inlinestatic |
No runtime module docstring in Lua (its home is a generated stub).
|
inlinestaticconsteval |
Map a member operator to its Lua metamethod name (nullptr = not exposed).
Definition at line 459 of file rod.hpp.
References welder::rods::sol2::metamethod::name, and welder::rods::sol2::operator_mm().
|
staticconstexprprotected |
Whether sol2 can only convert T via runtime usertype registration.
sol2 classifies every type at compile time via sol::lua_type_of<T>; a value that maps to sol::type::userdata is a program-defined class sol2 can convert only once a sol::usertype has been registered for it. Scalars, bool, strings and the sol2 wrapper types (sol::object, sol::table, …) map to number/string/table/poly/… and convert natively. This is the one bindability fact welder's core cannot know; it drives has_native_caster below.
Enums are forced into the needs-registration bucket even though sol2 would convert them as plain numbers: welder wants a welded enum registered (as its name→value table, for named access) and its enum-typed members gated on that, matching the Python backends. The STL-wrapper recursion in bindable.hpp is shared, so containers/optional/variant/smart-pointers of a native/welded type are handled without reaching here.
Like the Python backends' counterparts this is conservative: it reads T's static classification, so it reports whether T needs registration, never whether one exists at runtime. A type hand-registered out-of-band still reads true; that false positive is resolved by the deferred trust_bindable escape hatch.
| T | the type whose sol2 classification to read. |
|
staticconstexpr |
caster_oracle: T converts without welder registering a usertype iff sol2 does not classify it as needs-registration.
| T | the type to classify. |
Definition at line 104 of file rod.hpp.
Referenced by add_function(), add_method(), add_static_method(), and add_variable().