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

Rod-agnostic module entry point — the WELDER_MODULE macro. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  welder::detail::module_welder< Default, Override >
 Pick the entry macro's welder: the user's optional override, else the rod's default welder::welder<rod>. More...
struct  welder::detail::module_welder< Default, First, Rest... >

Namespaces

namespace  welder
namespace  welder::detail
 The stored forms of the annotation vocabulary.

Macros

#define WELDER_MODULE(ns, rod, ...)
 Emit a binding module's entry point and weld a namespace into it.

Typedefs

template<class Default, class... Override>
using welder::detail::module_welder_t = typename module_welder<Default, Override...>::type

Detailed Description

Rod-agnostic module entry point — the WELDER_MODULE macro.

Definition in file module.hpp.

Macro Definition Documentation

◆ WELDER_MODULE

#define WELDER_MODULE ( ns,
rod,
... )
Value:
WELDER_DETAIL_MODULE_ENTRY_##rod(ns __VA_OPT__(, ) __VA_ARGS__)

Emit a binding module's entry point and weld a namespace into it.

Parameters
nsthe namespace to bind; its token doubles as the module name.
rodthe rod selector (e.g. pybind11).
...optionally, the exact welder::welder<…> type to drive the weld with — the way to thread a name style (or a custom carriage) through the one-line module form. Defaults to the rod's plain welder::welder<rod>. Commas inside the template-id are fine (the macro is variadic), and the type's module_type must match the selected rod's (checked by a static_assert in the expansion):
WELDER_MODULE(geometry, pybind11,
#define WELDER_MODULE(ns, rod,...)
Emit a binding module's entry point and weld a namespace into it.
Definition module.hpp:78
The pybind11 rod: a stateless policy type satisfying welder::rod.
Definition rod.hpp:71
PEP 8 naming: CapWords (PascalCase) for classes and enum types, snake_case for everything callable or...
Definition naming.hpp:45
welder's binding entry point, parameterized on a rod.
Definition welder.hpp:85

Defining a binding module needs exactly one irreducible macro. A target runtime imports a module by a pasted entry symbol — Python's PyInit_<name>, Lua's luaopen_<name> — and only the preprocessor can form that token; it cannot be synthesized from a reflection or a constexpr string. WELDER_MODULE hides which rod's macro forms it behind one uniform, rod-selected spelling, so the call site is the same across rods.

Because each language has its own entry symbol, a single shared object can expose several languages at once — one WELDER_MODULE per rod, each emitting its own symbol from the same namespace:

WELDER_MODULE(geometry, pybind11) { module.attr("VERSION") = "1.0"; }
WELDER_MODULE(geometry, sol2) { module["VERSION"] = "1.0"; } // Lua glue

(pybind11 and nanobind both emit PyInit_<name>, so those two can't coexist in one module — pick one Python rod.)

The namespace token doubles as the module name: geometry is both ^^geometry (the bound namespace) and the PyInit_geometry / luaopen_geometry symbol, so there is no separate name argument. The trailing { } is optional hand-written glue, run after welder binds the namespace, with the rod's module handle named module in scope; write {} for none.

rod selects the expansion WELDER_DETAIL_MODULE_ENTRY_<rod>, which the corresponding rod's module.hpp defines (e.g. <welder/rods/python/pybind11/module.hpp>). Selecting a rod whose module.hpp you did not include is a preprocessor error.

Definition at line 78 of file module.hpp.