91#include <LuaBridge/LuaBridge.h>
101struct Stack<E, std::enable_if_t<std::is_enum_v<E>>> : Enum<E> {};
124template <
class T,
class... A>
126 return T(std::move(args)...);
150 lua_State*
L{
nullptr};
151 std::vector<std::string>
path{};
212 std::is_enum_v<std::remove_cvref_t<T>> ||
213 lb::detail::IsUserdata<std::remove_cvref_t<T>>::value;
225 lb::Namespace ns{lb::getGlobalNamespace(m.
L)};
226 for (
const auto& seg : m.
path)
227 ns = ns.beginNamespace(seg.c_str());
250 lua_pushglobaltable(m.
L);
251 for (
const auto& seg : m.
path) {
252 lua_pushlstring(m.
L, seg.data(), seg.size());
263 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
265 std::vector<std::vector<std::meta::info>> lists;
268 for (
auto c : Ctors) {
269 std::vector<std::meta::info> args;
270 for (
auto p : std::meta::parameters_of(c))
271 args.push_back(std::meta::type_of(p));
272 lists.push_back(args);
275 std::vector<std::meta::info> args;
277 args.push_back(std::meta::type_of(fld));
278 lists.push_back(args);
285 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
287 constexpr std::size_t n{
289 std::array<std::meta::info, n> out{};
290 if constexpr (n != 0) {
292 for (std::size_t i{0}; i < n; ++i)
293 out[i] = std::meta::dealias(std::meta::substitute(^^
ctor_sig, lists[i]));
300 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
302 constexpr std::size_t n{
304 std::array<std::meta::info, n> out{};
305 if constexpr (n != 0) {
307 for (std::size_t i{0}; i < n; ++i) {
308 std::vector<std::meta::info> targs{^^T};
309 for (
auto a : lists[i])
311 out[i] = std::meta::substitute(^^
make_object, targs);
321 template <
auto Sigs,
auto Factories,
class Cls, std::size_t... I>
323 cls.template addConstructor<
typename [:Sigs[I]:]...>();
324 cls.addStaticFunction(
"new", &[:Factories[I]:]...);
331 template <
class T,
auto Bases, std::size_t... I>
333 std::index_sequence<I...>) {
334 if constexpr (
sizeof...(I) == 0) {
338 .template deriveClass<T,
typename [:Bases[I]:]...>(name)};
347 template <
auto Grp,
class Target, std::size_t... I>
349 std::index_sequence<I...>) {
356 t.addFunction(name, &[:Grp[I]:]...);
360 template <
auto Grp,
class Target, std::size_t... I>
362 std::index_sequence<I...>) {
364 t.addStaticFunction(name, &[:Grp[I]:]...);
389 template <
class T,
auto Bases, std::size_t... I>
392 std::index_sequence<I...> ) {
406 template <
class T,
auto Bases, std::size_t... I>
408 const char* name,
const char* ,
409 std::index_sequence<I...> ) {
410 std::string temp{outer.name +
"." + name};
412 std::make_index_sequence<Bases.size()>{});
426 lua_State* L{cls.mod.L};
428 lua_pushlstring(L, cls.name.data(), cls.name.size());
430 lua_pushlstring(L, outer.name.data(), outer.name.size());
432 lua_pushstring(L, name);
433 lua_pushvalue(L, -3);
436 lua_pushlstring(L, cls.name.data(), cls.name.size());
446 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
450 if constexpr (sigs.size() != 0) {
453 cls, std::make_index_sequence<sigs.size()>{});
466 template <std::meta::info Mem,
class Style = ::welder::naming::none>
469 constexpr const char* name{
472 if constexpr (!std::meta::is_public(Mem)) {
478 if constexpr (std::meta::is_const_type(std::meta::type_of(Mem)))
479 cls.addProperty(name, &fa::get);
481 cls.addProperty(name, &fa::get, &fa::set);
483 using Field =
typename [:std::meta::type_of(Mem):];
484 constexpr Field T::* mp{&[:Mem:]};
485 if constexpr (std::meta::is_const_type(std::meta::type_of(Mem)))
486 cls.addProperty(name, mp);
488 cls.addProperty(name, mp, mp);
495 template <auto Fns,
class Style = ::welder::naming::none>
502 std::make_index_sequence<Fns.size()>{});
507 template <auto Fns,
class Style = ::welder::naming::none>
515 std::make_index_sequence<Fns.size()>{});
543 constexpr auto Fn{Fns[0]};
546 if constexpr (std::meta::operator_of(Fn) ==
547 std::meta::operators::op_square_brackets) {
548 using Key = std::remove_cvref_t<
typename [:std::meta::type_of(
549 std::meta::parameters_of(Fn)[0]):]>;
550 cls.addIndexMetaMethod(
551 +[](T& self,
const lb::LuaRef& key, lua_State* L) -> lb::LuaRef {
552 if constexpr (std::is_arithmetic_v<Key>) {
555 const lua_Number n{lua_tonumberx(L, -1, &is_num)};
558 return lb::LuaRef(L);
559 return lb::LuaRef(L, self[
static_cast<Key
>(n)]);
561 if (
auto k = key.template cast<Key>())
562 return lb::LuaRef(L, self[*k]);
563 return lb::LuaRef(L);
581 return enum_handle{m, std::string{name}, std::is_scoped_enum_v<E>};
592 const char* name,
const char* ) {
593 lua_State* L{outer.mod.L};
595 lua_pushlstring(L, outer.name.data(), outer.name.size());
597 lua_pushstring(L, name);
601 return enum_handle{outer.mod, std::string{name}, std::is_scoped_enum_v<E>,
610 template <std::meta::info Enum,
class Style = ::welder::naming::none>
612 constexpr const char* name{
614 const lua_Integer value{
static_cast<lua_Integer
>(std::to_underlying([:Enum:]))};
622 lua_State* L{e.
mod.
L};
626 lua_pushlstring(L, e.
name.data(), e.
name.size());
628 lua_pushstring(L, name);
629 lua_pushinteger(L, value);
633 lua_pushstring(L, name);
634 lua_pushinteger(L, value);
659 template <auto Fns,
class Style = ::welder::naming::none>
666 std::make_index_sequence<Fns.size()>{});
676 template <std::meta::info Var,
class Style = ::welder::naming::none>
678 const char* name =
nullptr) {
682 if constexpr (std::meta::is_const_type(std::meta::type_of(Var))) {
683 ns.addVariable(key, [:Var:]);
685 using VT =
typename [:std::meta::type_of(Var):];
687 key, +[]() -> VT {
return [:Var:]; }, +[](VT v) { [:Var:] = v; });
695 sub.
path.emplace_back(name);
703static_assert(::welder::rod<rod>,
704 "welder::rods::luabridge::rod must satisfy welder::rod");
Backend-agnostic selection layer: the reflection predicates and selectors that decide what participat...
The contract a rod (a welder backend, welder::rods::…::rod) must satisfy to plug into the generic dri...
consteval auto aggregate_fields()
The fields an aggregate is initialized from: its non-static data members in declaration order (all pu...
consteval const char * lua_metamethod_name(std::meta::info f)
Map a member operator to its Lua metamethod __name, or nullptr if welder does not expose it (which al...
T make_object(A... args)
A factory that constructs T from the constructor arguments (works for normal constructors and,...
consteval const char * lua_metamethod_name(std::meta::info f)
Map a member operator to its Lua metamethod __name, or nullptr if welder does not expose it (which al...
void(A...) ctor_sig
The alias void(A...) — a LuaBridge3 constructor signature (a function type whose parameters are the c...
lang
The target languages welder ships rods for — but not the whole value space.
@ lua
Lua (via the sol2 and LuaBridge3 backends).
@ static_method
a static member function → transform_static_method.
@ function
a free function → transform_function.
@ variable
a namespace variable → transform_variable.
@ method
a member function → transform_method.
consteval void validate_return_policy()
Reject a return_policy on Fn (for language L) that contradicts Fn's return type.
constexpr const char * name_of_or(const char *override_)
Resolve a bound name with a call-site override: override_ wins verbatim, nullptr falls back to name_o...
consteval const char * name_of()
The final bound name of Ent (a K-kind entity) for language L under name style Style.
Splice-based accessors for data member Mem — the pointer-to-member-free route the rods bind a protect...
The class handle threaded from make_class to the add_* hooks: enough to re-open the class (its module...
std::string name
The class's Lua name.
T type
The C++ class type.
module_scope mod
The enclosing module.
The enum handle threaded from make_enum to add_enumerator: the enclosing module, the enum's Lua name ...
A copyable handle to a welded module (or submodule) table: the borrowed Lua state plus the namespace ...
lua_State * L
The borrowed Lua state.
std::vector< std::string > path
Namespace segments under _G.
Per-module session — unused: LuaBridge3 registers namespace variables as live properties eagerly (no ...
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 express...
static consteval auto _factory_array()
The make_object<T, A...> factory-function reflections (for the .new static function) as a fixed-size,...
static void add_operator(auto &h)
Bind member operator Fn under its Lua metamethod __name.
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 constexpr lang language
welder::lang::lua.
static module_type add_submodule(module_type &m, const char *name)
Create a submodule (nested namespace) named name under m.
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...
static consteval auto _ctor_sigs_array()
The void(A...) constructor-signature reflections (for addConstructor) as a fixed-size,...
static void add_field(auto &h)
Bind data member Mem as a class property (read-only if const, else read/write).
module_scope module_type
A Lua module is a named table.
static constexpr bool _needs_registration
Whether LuaBridge3 can only convert T via runtime class registration.
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").
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 (m...
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_...
enum_handle enum_handle_type
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); ...
typename std::remove_cvref_t< H >::type _class_type
The C++ type behind a class_handle<T>& (deduced from the driver's auto&).
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...
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; na...
static void add_variable(module_type &m, session &, const char *name=nullptr)
Bind namespace variable Var onto the module.
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.
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,...
static void add_method(auto &h)
Bind method overload group Fns as one method (obj:name(…)) via a single variadic addFunction — LuaBri...
static consteval const char * special_method_name(std::meta::info op_fn)
Map a member operator to its Lua metamethod name (nullptr = not exposed).
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 varia...
static void close_module(module_type &, session &)
Close the session (no-op; see session).
static void finish_enum(auto &)
No whole-enum finalizer needed (unscoped export is done per-enumerator).
static constexpr bool has_native_caster
caster_oracle: T converts without welder registering a class iff LuaBridge3 does not classify it as n...
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....
class_handle< T > class_handle_type
The class / enum handles the per-class / per-enum hooks receive — exactly what make_class / make_enum...
static lb::Namespace _open_namespace(const module_scope &m)
Open the module's namespace chain from the global namespace, returning the innermost luabridge::Names...
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...
static void set_module_doc(module_type &, const char *)
No runtime module docstring in Lua (its home is a generated stub).
static session open_module(module_type &)
Open a per-module session (unused; see session).
static void add_enumerator(enum_handle &e)
Add enumerator Enum (as its underlying integer) to the enum's table.
static void add_constructors(auto &h)
Register T's whole constructor set — exactly what LuaBridge3 wants (one variadic addConstructor for t...
welder's binding entry point: the welder::welder struct.