welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
rod.hpp File Reference

welder sol2 Lua rod (header-only). More...

#include <array>
#include <cstddef>
#include <functional>
#include <meta>
#include <type_traits>
#include <utility>
#include <vector>
#include <welder/welder.hpp>
#include <welder/rods/lua/sol2/metamethods.hpp>
#include <welder/bind_traits.hpp>
#include <sol/sol.hpp>
Include dependency graph for rod.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  welder::rods::sol2::rod
 The sol2 rod: a stateless policy type satisfying welder::rod. More...
struct  welder::rods::sol2::rod::session
 Per-module session: the deferred state for live namespace variables. More...
struct  welder::rods::sol2::rod::_enum_binding< E >
 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...

Namespaces

namespace  welder
namespace  welder::rods
namespace  welder::rods::sol2

Typedefs

template<class T, class... A>
using welder::rods::sol2::ctor_sig = T(A...)
 The alias T(A...) — a constructor call signature, built by substitute (a namespace-scope alias so it can be reflected as ^^ctor_sig).

Detailed Description

welder sol2 Lua rod (header-only).

This is a thin rod: it implements welder's rod contract (<welder/welder.hpp>) for sol2 and hands the traversal/resolution off to welder's generic driver. All the language-agnostic work — deciding which members bind, gating bindability, walking bases and namespaces — lives in the core; only the sol2 emission primitives are here. It targets a loadable Lua C module: Lua's require finds the shared object on package.cpath and enters it through the luaopen_<name> symbol, which welder's entry macro emits; the module registers its types onto a fresh table and returns it. sol2 is used through a sol::state_view over the borrowed lua_State* (welder does not own the interpreter).

Requires the welder vocabulary first (#include <welder/vocabulary.hpp>). This header exposes exactly one thing: the rod type welder::rods::sol2::rod, to plug into welder::welder:

#include <sol/sol.hpp>
extern "C" int luaopen_mymod(lua_State* L) {
sol::state_view lua(L);
sol::table m = lua.create_table();
return sol::stack::push(L, m);
}
welder sol2 Lua rod (header-only).
static auto weld_type(module_type &m, const char *name=nullptr)
Reflect over T and register it on module m.
Definition welder.hpp:111

or, more simply, via the backend-agnostic entry macro (include this directory's module.hpp instead):

WELDER_MODULE(mymod, sol2) {} // welds namespace ^^mymod into luaopen_mymod
#define WELDER_MODULE(ns, rod,...)
Emit a binding module's entry point and weld a namespace into it.
Definition module.hpp:78

How Lua differs from the Python backends

  • Metamethods, not dunders. Member operators bind to Lua metamethods (__add, __eq, …), and Lua's set is smaller and asymmetric: it has no __ne/__gt/__ge — the VM derives ~=, > and >= from __eq, __lt and __le with swapped operands — so those C++ operators map to nothing (they still work in Lua, synthesized). Bitwise metamethods exist only on Lua ≥ 5.3 (not on LuaJIT's 5.1 ABI); they are #if-gated. See welder::rods::sol2::operator_mm.
  • Constructors, all at once. sol2 takes a type's whole constructor set in one sol::constructors<…> — exactly the shape of the driver's single welder::rods::sol2::rod::add_constructors call (the participating constructor reflections plus the default/aggregate flags), turned into one assignment here.
  • Enums are tables. Lua has no enum type; a welded enum becomes a plain name→integer table (an unscoped enum's names are also mirrored onto the enclosing module, like C++).
  • No runtime docstrings. Lua has no __doc__ slot, so [[=welder::doc]] / returns are not surfaced at runtime; their home is a generated LuaCATS (---@meta) stub, a separate emitter (not part of this binding backend).
  • Namespace variables: snapshot or live. A const/constexpr variable binds as a value snapshot at load time; a mutable one binds as a live get/set over the C++ global via a metatable proxy on the module table (__index/__newindex routing absent keys through per-variable getters/setters), so reads see the current value and writes flow back — matching the Python backends.
Note
Overloaded methods, static methods, free functions and operators: sol2 stores one value per name (and per metamethod slot), and the DRIVER hands each name's participating overloads to the rod as one group — registered here as a single sol::overload(…), dispatched among at call time. A same-named member in a derived class still hides the base's (C++ name-hiding), as it did before.

Definition in file rod.hpp.