81namespace welder::inline v0::rods::sol2 {
89template <
class T,
class... A>
152 std::is_enum_v<std::remove_cvref_t<T>> ||
153 ::sol::lua_type_of<std::remove_cvref_t<T>>::value == ::sol::type::userdata;
166 std::function<void(
const char*, lua_Integer)>
187 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
189 std::vector<std::meta::info> sigs;
190 auto sig = [](std::vector<std::meta::info> targs) {
191 return std::meta::dealias(std::meta::substitute(^^
ctor_sig, targs));
194 sigs.push_back(sig({^^T}));
195 for (
auto c : Ctors) {
196 std::vector<std::meta::info> targs{^^T};
197 for (
auto p : std::meta::parameters_of(c))
198 targs.push_back(std::meta::type_of(p));
199 sigs.push_back(sig(targs));
202 std::vector<std::meta::info> targs{^^T};
204 targs.push_back(std::meta::type_of(fld));
205 sigs.push_back(sig(targs));
211 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
213 constexpr std::size_t n{
215 std::array<std::meta::info, n> out{};
218 if constexpr (n != 0) {
220 for (std::size_t i{0}; i < n; ++i)
232 template <
class T,
auto Sigs, std::size_t... I>
234 std::index_sequence<I...>) {
236 ut[::sol::call_constructor] = ::sol::constructors<
typename [:Sigs[I]:]...>();
237 ut[
"new"] = ::sol::constructors<
typename [:Sigs[I]:]...>();
252 template <
class T,
auto Bases, std::size_t... I>
254 std::index_sequence<I...>) {
257 if constexpr (
sizeof...(I) == 0) {
258 return ::sol::usertype<T>{m.new_usertype<T>(name, ::sol::no_constructor)};
260 return ::sol::usertype<T>{m.new_usertype<T>(
261 name, ::sol::no_constructor, ::sol::base_classes,
262 ::sol::bases<
typename [:Bases[I]:]...>())};
282 std::meta::info type,
lang L, std::vector<std::meta::info>& out) {
305 constexpr std::size_t n{[] {
306 std::vector<std::meta::info> v;
310 std::array<std::meta::info, n> out{};
312 if constexpr (n != 0) {
313 std::vector<std::meta::info> v;
315 for (std::size_t i{0}; i < n; ++i)
332 template <
auto Grp,
class Target, std::size_t... I>
334 std::index_sequence<I...>) {
341 if constexpr (
sizeof...(I) == 1)
342 t[name] = &[:Grp[0]:];
344 t[name] = ::sol::overload(&[:Grp[I]:]...);
353 template <
auto Grp,
class Target, std::size_t... I>
357 if constexpr (
sizeof...(I) == 1)
358 t[slot] = &[:Grp[0]:];
360 t[slot] = ::sol::overload(&[:Grp[I]:]...);
368 static ::sol::object
_prev_index(::sol::this_state ts, const ::sol::object& prev,
369 const ::sol::table& self, const ::sol::object& key) {
370 if (prev.get_type() == ::sol::type::function)
371 return ::sol::object{prev.as<::sol::function>()(self, key)};
372 if (prev.get_type() == ::sol::type::table)
373 return ::sol::object{prev.as<::sol::table>()[key]};
374 return ::sol::make_object(ts, ::sol::lua_nil);
381 const ::sol::object& key, const ::sol::object& value) {
382 if (prev.get_type() == ::sol::type::function) {
383 prev.as<::sol::function>()(self, key, value);
386 if (prev.get_type() == ::sol::type::table) {
387 prev.as<::sol::table>()[key] = value;
390 self.raw_set(key, value);
404 ::sol::table setters) {
405 lua_State* L{m.lua_state()};
406 ::sol::state_view
lua{L};
412 const bool had_mt{lua_getmetatable(L, -1) != 0};
413 ::sol::table mt{had_mt ? ::sol::stack::pop<::sol::table>(L)
414 :
lua.create_table()};
418 ::sol::object prev_index{mt[
"__index"]};
419 ::sol::object prev_newindex{mt[
"__newindex"]};
421 mt[
"__index"] = [getters, prev_index](::sol::this_state ts, ::sol::table self,
422 ::sol::object key) -> ::sol::object {
423 ::sol::object g{getters[key]};
424 if (g.get_type() == ::sol::type::function)
425 return ::sol::object{g.as<::sol::function>()()};
428 mt[
"__newindex"] = [setters, prev_newindex](::sol::table self, ::sol::object key,
429 ::sol::object value) {
430 ::sol::object s{setters[key]};
431 if (s.get_type() == ::sol::type::function) {
432 s.as<::sol::function>()(value);
437 m[::sol::metatable_key] = mt;
473 template <
class T,
auto Bases, std::size_t... I>
475 std::index_sequence<I...> ) {
478 m, name, std::make_index_sequence<bases.size()>{});
491 template <
class T,
auto Bases, std::size_t... I>
493 const char*
doc, std::index_sequence<I...> seq) {
497 m[name] = ::sol::lua_nil;
505 template <
class T, auto Ctors,
bool HasDefault,
bool Aggregate>
508 if constexpr (sigs.size() != 0)
518 template <std::meta::info Mem,
class Style = ::welder::naming::none>
520 constexpr const char* name{
522 if constexpr (!std::meta::is_public(Mem)) {
528 if constexpr (std::meta::is_const_type(std::meta::type_of(Mem)))
529 ut[name] = ::sol::readonly_property(&fa::get);
531 ut[name] = ::sol::property(&fa::get, &fa::set);
532 }
else if constexpr (std::meta::is_const_type(std::meta::type_of(Mem))) {
533 ut[name] = ::sol::readonly(&[:Mem:]);
542 template <auto Fns,
class Style = ::welder::naming::none>
547 std::make_index_sequence<Fns.size()>{});
552 template <auto Fns,
class Style = ::welder::naming::none>
558 std::make_index_sequence<Fns.size()>{});
575 ::sol::table values{::sol::state_view{m.lua_state()}.create_table()};
578 values, [m](
const char* n, lua_Integer v)
mutable { m[n] = v; },
579 std::is_scoped_enum_v<E>};
590 ::sol::table values{::sol::state_view{m.lua_state()}.create_table()};
591 outer[name] = values;
596 [outer](
const char* n, lua_Integer v)
mutable {
597 outer[n] = ::sol::var(v);
599 std::is_scoped_enum_v<E>};
607 template <std::meta::info Enum,
class Style = ::welder::naming::none>
609 constexpr const char* name{
611 const lua_Integer value{
static_cast<lua_Integer
>(std::to_underlying([:Enum:]))};
612 e.values[name] = value;
614 e.mirror(name, value);
640 template <auto Fns,
class Style = ::welder::naming::none>
645 return m.get<sol::object>(fn_name);
660 template <std::meta::info Var,
class Style = ::welder::naming::none>
664 if constexpr (std::meta::is_const_type(std::meta::type_of(Var))) {
668 ::sol::state_view
lua{m.lua_state()};
673 s.
getters[key] = [] {
return [:Var:]; };
674 s.
setters[key] = [](
typename [:std::meta::type_of(Var):] v) {
682 ::sol::table sub{::sol::state_view{m.lua_state()}.create_table()};
695static_assert(::welder::rod<rod>,
696 "welder::rods::sol2::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 metamethod operator_mm(std::meta::info f)
Map a member operator to its sol2 metamethod ({…, nullptr} = not exposed).
T(A...) ctor_sig
The alias T(A...) — a constructor call signature, built by substitute (a namespace-scope alias so it ...
consteval bool welded_for(std::meta::info type, lang L)
Is type welded for language L — i.e.
consteval detail::doc_spec< N > doc(const char(&s)[N])
Attach a docstring to a namespace, class, function, or function parameter.
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.
consteval std::vector< std::meta::info > public_bases(std::meta::info type)
The types of the public base classes of type.
Splice-based accessors for data member Mem — the pointer-to-member-free route the rods bind a protect...
A welded enum's binding: the name→value table, how to mirror a name onto the enclosing scope,...
std::function< void(const char *, lua_Integer)> mirror
Write one name onto the enclosing scope.
bool scoped
true for enum class.
::sol::table values
The E = { Name = value, … } table.
Per-module session: the deferred state for live namespace variables.
::sol::table getters
name → fun(): value (live reads).
bool has_live
any mutable variable registered?
::sol::table setters
name → fun(value) (live writes).
static void add_field(auto &ut)
Bind data member Mem as a usertype property.
static module_type add_submodule(module_type &m, const char *name)
Create a submodule table named name under m.
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.
static void set_module_doc(module_type &, const char *)
No runtime module docstring in Lua (its home is a generated stub).
::sol::usertype< T > class_handle_type
The class / enum handles the per-class / per-enum hooks operate on — exactly what make_class / make_e...
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_constru...
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); w...
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...
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...
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_enumerator(auto &e)
Add enumerator Enum (as its underlying integer).
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 (modu...
static auto make_enum(module_type &m, const char *name, const char *)
Create the enum's Name = value table on the module (doc ignored).
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 (...
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(…) f...
_enum_binding< E > enum_handle_type
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 t...
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,...
static consteval auto _ctor_sigs_array()
_ctor_signatures<T, …>() as a fixed-size, splice-ready static array.
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....
static consteval auto _welded_bases_array()
_collect_welded_bases for T as a fixed-size, splice-ready static array.
static void finish_enum(auto &)
No whole-enum finalizer needed (unscoped export is done per-enumerator).
static void add_constructors(::sol::usertype< T > &ut)
Install T's whole constructor set — exactly what sol2 wants (one sol::constructors<…> assignment cove...
static void add_variable(module_type &m, session &s, const char *name=nullptr)
Bind namespace variable Var onto the module.
static void _set_constructors(::sol::usertype< T > &ut, std::index_sequence< I... >)
Register T's constructor set on the usertype from the reflected signatures.
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 session open_module(module_type &)
Open a per-module session.
static constexpr lang language
welder::lang::lua.
static constexpr bool has_native_caster
caster_oracle: T converts without welder registering a usertype iff sol2 does not classify it as need...
::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),...
::sol::table module_type
A Lua module is a table.
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...
static void add_operator(auto &ut)
Bind operator overload group Fns under its Lua metamethod (one operator + arity per group; each overl...
static constexpr bool _needs_registration
Whether sol2 can only convert T via runtime usertype registration.
static void add_method(auto &ut)
Bind method overload group Fns as one method (obj:name(…)) — a single callable when unique,...
welder's binding entry point: the welder::welder struct.