27namespace welder::inline v0::rods::luacats {
39 std::string_view indent = {}) {
44 for (
const char* c{text}; *c; ++c) {
46 if (*c ==
'\n' && c[1] !=
'\0') {
62 for (
const char* c{text}; *c; ++c)
63 out += (*c ==
'\n') ?
' ' : *c;
78 std::vector<std::string> parts{};
79 if (std::meta::has_identifier(ent))
80 parts.emplace_back(std::meta::identifier_of(ent));
81 std::meta::info p{std::meta::parent_of(ent)};
83 (std::meta::is_namespace(p) ||
84 (std::meta::is_type(p) && std::meta::is_class_type(p)))) {
85 if (std::meta::has_identifier(p))
86 parts.emplace_back(std::meta::identifier_of(p));
87 p = std::meta::parent_of(p);
90 for (
auto it{parts.rbegin()}; it != parts.rend(); ++it) {
103consteval bool type_trait(std::meta::info trait_var, std::meta::info t) {
104 return std::meta::extract<bool>(std::meta::substitute(trait_var, {t}));
112consteval bool is_wrapper(std::meta::info type, std::meta::info& tmpl_out) {
113 if (!std::meta::has_template_arguments(type))
115 tmpl_out = std::meta::template_of(type);
129 namespace m = std::meta;
130 const m::info w{m::dealias(m::substitute(^^std::remove_cvref_t, {type}))};
133 if (w == m::dealias(^^std::string) || w == m::dealias(^^std::string_view))
136 const m::info pointee{m::dealias(m::substitute(
137 ^^std::remove_cv_t, {m::substitute(^^std::remove_pointer_t, {w})}))};
138 if (pointee == ^^
char)
146 const auto args{m::template_arguments_of(w)};
148 if (tmpl == ^^std::vector || tmpl == ^^std::list || tmpl == ^^std::deque ||
149 tmpl == ^^std::set || tmpl == ^^std::multiset ||
150 tmpl == ^^std::unordered_set || tmpl == ^^std::unordered_multiset ||
151 tmpl == ^^std::array)
152 return elem(0) +
"[]";
153 if (tmpl == ^^std::map || tmpl == ^^std::multimap ||
154 tmpl == ^^std::unordered_map || tmpl == ^^std::unordered_multimap)
155 return "table<" + elem(0) +
", " + elem(1) +
">";
156 if (tmpl == ^^std::optional)
157 return elem(0) +
"?";
158 if (tmpl == ^^std::shared_ptr || tmpl == ^^std::unique_ptr)
160 if (tmpl == ^^std::pair)
161 return "{ [1]: " + elem(0) +
", [2]: " + elem(1) +
" }";
162 if (tmpl == ^^std::variant) {
164 for (std::size_t i{0}; i < args.size(); ++i)
175 if (
type_trait(^^std::is_floating_point_v, w))
177 if (m::is_enum_type(w) || m::is_class_type(w))
186consteval const char*
lua_type(std::meta::info type) {
196 std::is_arithmetic_v<U> ||
197 std::is_same_v<std::remove_cv_t<U>, std::string> ||
198 std::is_same_v<std::remove_cv_t<U>, std::string_view> ||
199 std::is_same_v<std::remove_cv_t<std::remove_pointer_t<std::remove_cvref_t<U>>>,
226 using std::meta::operators;
228 switch (std::meta::operator_of(f)) {
229 case operators::op_plus:
return unary ? nullptr :
"add";
230 case operators::op_minus:
return unary ?
"unm" :
"sub";
231 case operators::op_star:
return unary ? nullptr :
"mul";
232 case operators::op_slash:
return "div";
233 case operators::op_percent:
return "mod";
234 case operators::op_parentheses:
return "call";
236 case operators::op_caret:
return "bxor";
237 case operators::op_tilde:
return unary ?
"bnot" :
nullptr;
238 case operators::op_ampersand:
return unary ? nullptr :
"band";
239 case operators::op_pipe:
return "bor";
240 case operators::op_less_less:
return "shl";
241 case operators::op_greater_greater:
return "shr";
242 default:
return nullptr;
Backend-agnostic selection layer: the reflection predicates and selectors that decide what participat...
Backend-agnostic bindability ("can the target language represent this type?").
consteval bool is_unary_operator(std::meta::info f)
Whether an operator function is unary vs binary.
consteval bool type_trait(std::meta::info trait_var, std::meta::info t)
Evaluate a standard unary type-trait variable template (e.g.
constexpr bool is_native_lua
Whether the backend converts U without welder registering a type: scalars, strings and char*.
consteval const char * lua_type(std::meta::info type)
lua_type_string as a static-storage C string, callable on a constant type reflection.
consteval std::string qualified_name(std::meta::info ent)
The dotted LuaCATS name of a namespace-or-type reflection: its own identifier prefixed by each enclos...
std::string one_line(const char *text)
A one-line description for a @field/@param/@return tail: newlines in text collapse to spaces (LuaCATS...
consteval bool is_wrapper(std::meta::info type, std::meta::info &tmpl_out)
Whether type (already a bare type) is a listed element-wise wrapper whose LuaCATS spelling this map r...
consteval std::string lua_type_string(std::meta::info type)
The LuaCATS type name for a C++ type reflection.
void emit_doc_comment(std::string &out, const char *text, std::string_view indent={})
Append text as --- comment lines (each source line prefixed), so a multiline summary lands as a LuaC...
consteval const char * operator_luacats(std::meta::info f)
A member operator's LuaCATS ---@operator name, or nullptr if not rendered.