|
welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
|
The LuaBridge3 rod: a stateless policy type satisfying welder::rod. More...
#include <welder/rods/lua/luabridge/rod.hpp>
Classes | |
| struct | module_scope |
| A copyable handle to a welded module (or submodule) table: the borrowed Lua state plus the namespace path from the global table. More... | |
| struct | session |
| Per-module session — unused: LuaBridge3 registers namespace variables as live properties eagerly (no deferred batch is needed, unlike sol2's live- variable proxy), so this is empty and open_module/close_module are no-ops. More... | |
| struct | class_handle |
| The class handle threaded from make_class to the add_* hooks: enough to re-open the class (its module, its Lua name) plus the C++ type (via type, recovered by the per-member hooks from decltype). More... | |
| struct | enum_handle |
| The enum handle threaded from make_enum to add_enumerator: the enclosing module, the enum's Lua name (a nested namespace of values) and whether it is scoped (an unscoped enum also mirrors its names onto the module). More... | |
Public Types | |
| using | module_type = module_scope |
| A Lua module is a named table. | |
| template<class T> | |
| using | class_handle_type = class_handle<T> |
| The class / enum handles the per-class / per-enum hooks receive — exactly what make_class / make_enum return (the enum handle carries no type parameter). | |
| template<class> | |
| using | enum_handle_type = enum_handle |
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 class_handle< T > | make_class (module_type &m, const char *name, const char *, std::index_sequence< I... >) |
| Register class T (with its native bases and constructors) and return a re-openable handle. | |
| template<class T, auto Bases, std::size_t... I> | |
| static class_handle< T > | make_nested_class (module_type &, auto &outer, const char *name, const char *, std::index_sequence< I... >) |
| Register a nested member type T under a temporary dotted module key ("Outer.Inner"). | |
| template<class T> | |
| static void | finish_nested_class (module_type &, auto &outer, auto &cls, const char *name) |
| Move the fully-registered nested class table onto the outer's class table (module.Outer.Inner) and drop the temporary dotted module key. | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static void | add_constructors (auto &h) |
| Register T's whole constructor set — exactly what LuaBridge3 wants (one variadic addConstructor for the call form T(…) plus the .new factory set) — built from the driver-passed pieces on the re-opened class. | |
| template<std::meta::info Mem, class Style = ::welder::naming::none> | |
| static void | add_field (auto &h) |
| Bind data member Mem as a class property (read-only if const, else read/write). | |
| template<auto Fns, class Style = ::welder::naming::none> | |
| static void | add_method (auto &h) |
| Bind method overload group Fns as one method (obj:name(…)) via a single variadic addFunction — LuaBridge3 dispatches by arity/type at call time. | |
| template<auto Fns, class Style = ::welder::naming::none> | |
| static void | add_static_method (auto &h) |
| 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 &h) |
| Bind member operator Fn under its Lua metamethod __name. | |
| template<class E> | |
| static enum_handle | make_enum (module_type &m, const char *name, const char *) |
| Create the enum's nested namespace (a Name = value table) on the module (doc ignored) and return a re-openable handle. | |
| template<class E> | |
| static enum_handle | make_nested_enum (module_type &, auto &outer, const char *name, const char *) |
| Create the Name = value table for a nested member enum directly inside the enclosing class's table (module.Outer.Mode, a raw static entry — plain values need no re-open model, so no later move either). | |
| template<std::meta::info Enum, class Style = ::welder::naming::none> | |
| static void | add_enumerator (enum_handle &e) |
| Add enumerator Enum (as its underlying integer) to the enum's table. | |
| 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 (unused; see 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 void | add_function (module_type &m, const char *name=nullptr) |
| Bind free-function overload group Fns as one module-level function (a single variadic addFunction; name from Fns[0]). | |
| template<std::meta::info Var, class Style = ::welder::naming::none> | |
| static void | add_variable (module_type &m, session &, 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 (nested namespace) named name under m. | |
| static void | close_module (module_type &, session &) |
| Close the session (no-op; see session). | |
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 class iff LuaBridge3 does not classify it as needs-registration. | |
Protected Types | |
| template<class H> | |
| using | _class_type = typename std::remove_cvref_t<H>::type |
| The C++ type behind a class_handle<T>& (deduced from the driver's auto&). | |
Static Protected Member Functions | |
| static lb::Namespace | _open_namespace (const module_scope &m) |
| Open the module's namespace chain from the global namespace, returning the innermost luabridge::Namespace. | |
| template<class T> | |
| static auto | _open_class (const module_scope &m, const char *name) |
| Re-open class T under name in module m, returning the live luabridge::Namespace::Class<T> (created by make_class; here re-opened to continue registration). | |
| static void | _push_module_table (const module_scope &m) |
| Push the module's namespace table onto the Lua stack (a raw walk from _G through the path segments); the caller pops it. | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static consteval std::vector< std::vector< std::meta::info > > | _ctor_arg_lists () |
| The set of constructor argument lists to expose for T, built from the pieces the DRIVER hands to add_constructors — the participating constructor reflections plus the default/aggregate flags (aggregates ride C++26 parenthesized aggregate init) — gathered into one place because LuaBridge3 wants the whole set at once. | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static consteval auto | _ctor_sigs_array () |
| The void(A...) constructor-signature reflections (for addConstructor) as a fixed-size, splice-ready static array. | |
| template<class T, auto Ctors, bool HasDefault, bool Aggregate> | |
| static consteval auto | _factory_array () |
| The make_object<T, A...> factory-function reflections (for the .new static function) as a fixed-size, splice-ready static array. | |
| template<auto Sigs, auto Factories, class Cls, std::size_t... I> | |
| static void | _add_constructors (Cls &cls, std::index_sequence< I... >) |
| Register the whole constructor set on the (live) class cls: both the call form T(…) (addConstructor, which sets __call) and the idiomatic T.new(…) (a variadic addStaticFunction over the make_object factories) — matching the two forms sol2 exposes. | |
| template<class T, auto Bases, std::size_t... I> | |
| static void | _make_class (const module_scope &m, const char *name, std::index_sequence< I... >) |
| Create the class registration with its native (welded nearest-ancestor) bases, in one chained expression that then unwinds (constructors are installed by the driver's subsequent add_constructors call, which re-opens the class by path). | |
| template<auto Grp, class Target, std::size_t... I> | |
| static void | _add_function (Target &t, const char *name, std::index_sequence< I... >) |
| Register overload group Grp on target t (a live class or namespace) under name via LuaBridge3's variadic addFunction — one callable when unique, several dispatched by arity/type when overloaded. | |
| template<auto Grp, class Target, std::size_t... I> | |
| static void | _add_static_function (Target &t, const char *name, std::index_sequence< I... >) |
| As _add_function, for a class's static methods (addStaticFunction). | |
Static Protected Attributes | |
| template<class T> | |
| static constexpr bool | _needs_registration |
| Whether LuaBridge3 can only convert T via runtime class registration. | |
The LuaBridge3 rod: a stateless policy type satisfying welder::rod.
Its public static members are the 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 are LuaBridge3 implementation helpers (prefixed _); the operator→metamethod-name map is shared in <welder/rods/lua/metamethods.hpp>.
|
protected |
The C++ type behind a class_handle<T>& (deduced from the driver's auto&).
| using welder::rods::luabridge::rod::class_handle_type = class_handle<T> |
The class / enum handles the per-class / per-enum hooks receive — exactly what make_class / make_enum return (the enum handle carries no type parameter).
Named as associated types so the welder::rod concept can shape-check the per-handle hooks against them.
| using welder::rods::luabridge::rod::enum_handle_type = enum_handle |
|
inlinestaticprotected |
Register the whole constructor set on the (live) class cls: both the call form T(…) (addConstructor, which sets __call) and the idiomatic T.new(…) (a variadic addStaticFunction over the make_object factories) — matching the two forms sol2 exposes.
Cls is the deduced Class<T> handle type.
Definition at line 322 of file rod.hpp.
Referenced by add_constructors().
|
inlinestaticprotected |
Register overload group Grp on target t (a live class or namespace) under name via LuaBridge3's variadic addFunction — one callable when unique, several dispatched by arity/type when overloaded.
Each overload is spliced by its exact reflection. Serves methods, free functions and operators (all register through addFunction; an operator's name is its __slot).
Definition at line 348 of file rod.hpp.
References welder::validate_return_policy().
Referenced by add_function(), add_method(), and add_operator().
|
inlinestaticprotected |
As _add_function, for a class's static methods (addStaticFunction).
Definition at line 361 of file rod.hpp.
References welder::validate_return_policy().
Referenced by add_static_method().
|
inlinestaticconstevalprotected |
The set of constructor argument lists to expose for T, built from the pieces the DRIVER hands to add_constructors — the participating constructor reflections plus the default/aggregate flags (aggregates ride C++26 parenthesized aggregate init) — gathered into one place because LuaBridge3 wants the whole set at once.
Definition at line 264 of file rod.hpp.
References welder::detail::aggregate_fields().
Referenced by _ctor_sigs_array(), and _factory_array().
|
inlinestaticconstevalprotected |
The void(A...) constructor-signature reflections (for addConstructor) as a fixed-size, splice-ready static array.
Definition at line 286 of file rod.hpp.
References _ctor_arg_lists().
Referenced by add_constructors().
|
inlinestaticconstevalprotected |
The make_object<T, A...> factory-function reflections (for the .new static function) as a fixed-size, splice-ready static array.
Definition at line 301 of file rod.hpp.
References _ctor_arg_lists(), and welder::rods::luabridge::make_object().
Referenced by add_constructors().
|
inlinestaticprotected |
Create the class registration with its native (welded nearest-ancestor) bases, in one chained expression that then unwinds (constructors are installed by the driver's subsequent add_constructors call, which re-opens the class by path).
Definition at line 332 of file rod.hpp.
References _open_namespace().
Referenced by make_class(), and make_nested_class().
|
inlinestaticprotected |
Re-open class T under name in module m, returning the live luabridge::Namespace::Class<T> (created by make_class; here re-opened to continue registration).
Destroying the result unwinds the class + namespace + _G. Returned by auto because the class type is a private nested type of luabridge::Namespace.
Definition at line 237 of file rod.hpp.
References _open_namespace().
Referenced by add_constructors(), add_field(), add_method(), add_operator(), and add_static_method().
|
inlinestaticprotected |
Open the module's namespace chain from the global namespace, returning the innermost luabridge::Namespace.
The returned registrar owns the whole chain's Lua stack, so letting it (or a class/temporary derived from it) destruct unwinds everything cleanly — every emission primitive opens like this, registers in one chained expression, and lets it go.
Definition at line 224 of file rod.hpp.
References welder::rods::luabridge::rod::module_scope::L, and welder::rods::luabridge::rod::module_scope::path.
Referenced by _make_class(), _open_class(), add_enumerator(), add_function(), add_submodule(), add_variable(), and make_enum().
|
inlinestaticprotected |
Push the module's namespace table onto the Lua stack (a raw walk from _G through the path segments); the caller pops it.
Nested-type placement goes through the raw C API rather than the fluent registrar: LuaBridge3 has no class-in-class notion, and its class tables carry __index/__newindex guards that raw access legitimately bypasses — a nested type becomes a raw static entry on the outer's table, and Lua resolves a present raw key before any metamethod, so reads Just Work.
Definition at line 249 of file rod.hpp.
References welder::rods::luabridge::rod::module_scope::L, and welder::rods::luabridge::rod::module_scope::path.
Referenced by add_enumerator(), finish_nested_class(), and make_nested_enum().
|
inlinestatic |
Register T's whole constructor set — exactly what LuaBridge3 wants (one variadic addConstructor for the call form T(…) plus the .new factory set) — built from the driver-passed pieces on the re-opened class.
Definition at line 447 of file rod.hpp.
References _add_constructors(), _ctor_sigs_array(), _factory_array(), and _open_class().
|
inlinestatic |
Add enumerator Enum (as its underlying integer) to the enum's table.
An unscoped enum's enumerator is also mirrored onto the enclosing scope — the module, or (for a class-nested enum, whose handle carries the outer's key) the enclosing class's table — the driver's finish_enum role, done incrementally here since the handle carries the scope.
Definition at line 611 of file rod.hpp.
References _open_namespace(), _push_module_table(), welder::rods::luabridge::rod::module_scope::L, welder::rods::luabridge::rod::enum_handle::mod, welder::rods::luabridge::rod::enum_handle::name, welder::name_of(), welder::rods::luabridge::rod::enum_handle::outer_key, and welder::rods::luabridge::rod::enum_handle::scoped.
|
inlinestatic |
Bind data member Mem as a class property (read-only if const, else read/write).
Lua has no property docstring, so a [[=welder::doc]] on the member is not surfaced at runtime (it belongs in a generated stub).
The member pointer is static_cast to Field T::*: a flattened base member splices as Field Base::*, which LuaBridge3's addProperty template deduction (fixed on the class T) will not up-convert on its own — the cast is the derived→base pointer-to-member standard conversion, a no-op for T's own members.
Definition at line 467 of file rod.hpp.
References _open_class(), and welder::name_of().
|
inlinestatic |
Bind free-function overload group Fns as one module-level function (a single variadic addFunction; name from Fns[0]).
A non-null name overrides the resolved name (including any weld_as), used verbatim.
Definition at line 660 of file rod.hpp.
References _add_function(), _open_namespace(), welder::function, language, and welder::name_of_or().
|
inlinestatic |
Bind method overload group Fns as one method (obj:name(…)) via a single variadic addFunction — LuaBridge3 dispatches by arity/type at call time.
The name resolves from Fns[0].
Definition at line 496 of file rod.hpp.
References _add_function(), _open_class(), language, welder::method, and welder::name_of().
|
inlinestatic |
Bind member operator Fn under its Lua metamethod __name.
The specific overload is spliced (unary/binary forms never collide); several overloads mapping to the same slot are gathered into one variadic addFunction.
operator[] is special: it maps to __index, but LuaBridge3 reserves __index for its own member/property resolution and forbids replacing it (an override would shadow every field and method). Instead it is registered as the addIndexMetaMethod fallback. That fallback is consulted first on every index, and must return nil for keys it does not handle so normal member / property lookup proceeds — so the adapter tries to convert the Lua key to the operator's index type, returns the subscript result on success, and a nil LuaRef otherwise (letting obj.field / obj:method() resolve as usual, the "coexists with member access" semantics sol2 gets from __index being a last resort).
A numeric-index operator (operator[](int), the common case) needs one extra care: LuaBridge3's index metamethod runs lua_tostring on the key first, which mutates a number key into a string in place, so obj[0] reaches the fallback as "0" and a strict Stack<int> cast would reject it. For an arithmetic index type the adapter therefore coerces the key with lua_tonumberx (which accepts a numeric string), and only treats a genuinely non-numeric key as a member miss.
Definition at line 541 of file rod.hpp.
References _add_function(), _open_class(), and welder::rods::luabridge::lua_metamethod_name().
|
inlinestatic |
Bind static-method overload group Fns as a class-table function (T.name(…)), grouped as in add_method.
Definition at line 508 of file rod.hpp.
References _add_static_function(), _open_class(), language, welder::name_of(), and welder::static_method.
|
inlinestatic |
Create a submodule (nested namespace) named name under m.
Definition at line 692 of file rod.hpp.
References _open_namespace(), and welder::rods::luabridge::rod::module_scope::path.
|
inlinestatic |
Bind namespace variable Var onto the module.
A const/constexpr variable is copied in as a value snapshot (frozen at load time). A mutable variable becomes a live get/set over the C++ global via LuaBridge3's native property support, so Lua reads see the current value and writes flow back. A non-null name overrides the resolved name.
Definition at line 677 of file rod.hpp.
References _open_namespace(), language, welder::name_of_or(), and welder::variable.
|
inlinestatic |
|
inlinestatic |
No whole-enum finalizer needed (unscoped export is done per-enumerator).
|
inlinestatic |
Move the fully-registered nested class table onto the outer's class table (module.Outer.Inner) and drop the temporary dotted module key.
The carriage calls this after the nested class's whole interior — innermost first, so a deeper nested type has already moved onto this class. Raw table ops make the entry a raw static member of the outer's table, which Lua resolves before LuaBridge3's __index guard.
Definition at line 424 of file rod.hpp.
References _push_module_table().
|
inlinestatic |
Register class T (with its native bases and constructors) and return a re-openable handle.
Bases is the core's nearest welded-ancestor set, which suffices for LuaBridge3's transitive __index chaining. doc has no Lua runtime home and is ignored.
Definition at line 390 of file rod.hpp.
References _make_class().
|
inlinestatic |
Create the enum's nested namespace (a Name = value table) on the module (doc ignored) and return a re-openable handle.
Definition at line 578 of file rod.hpp.
References _open_namespace().
|
inlinestatic |
Register a nested member type T under a temporary dotted module key ("Outer.Inner").
LuaBridge3's fluent registrar has no class-in-class notion, and this rod's re-open-by-path handle model needs the class reachable by its key for every later add_* call — so the class lives at module scope (under a dotted key no sibling identifier can collide with, which also reads well in LuaBridge3 diagnostics) until the interior finishes, when finish_nested_class moves it onto the outer's table.
Definition at line 407 of file rod.hpp.
References _make_class().
|
inlinestatic |
Create the Name = value table for a nested member enum directly inside the enclosing class's table (module.Outer.Mode, a raw static entry — plain values need no re-open model, so no later move either).
The handle records the outer's key: add_enumerator writes through it, and an unscoped nested enum mirrors its names onto the class (Outer.quiet), like C++'s Outer::quiet.
Definition at line 591 of file rod.hpp.
References _push_module_table().
|
inlinestatic |
Open a per-module session (unused; see session).
|
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).
Shared with the sol2 rod.
Definition at line 379 of file rod.hpp.
References welder::rods::luabridge::lua_metamethod_name().
|
staticconstexprprotected |
Whether LuaBridge3 can only convert T via runtime class registration.
LuaBridge3 classifies any type without a dedicated Stack<T> specialization as userdata — a program-defined class it can convert only once registered; scalars, bool, strings and the like have specializations and convert natively. luabridge::detail::IsUserdata<T> reads exactly that. This is the one bindability fact welder's core cannot know; it drives has_native_caster.
Enums are forced into the needs-registration bucket (like sol2): welder binds a welded enum as its table of values and gates enum-typed members on it. The STL-wrapper recursion in bindable.hpp is shared, so containers/optional/… of a native/welded type never reach here. Conservative: it reports whether T needs registration, not whether one exists — the trust_bindable hatch resolves the false positive for a hand-registered type.
|
staticconstexpr |
caster_oracle: T converts without welder registering a class iff LuaBridge3 does not classify it as needs-registration.
| T | the type to classify. |
Definition at line 140 of file rod.hpp.
Referenced by add_function(), add_method(), add_static_method(), and add_variable().