27namespace welder::inline v0::detail {
37template <std::meta::info Fn>
39 constexpr std::size_t n{std::meta::parameters_of(Fn).size()};
40 std::array<std::meta::info, n> types{};
42 for (
auto p : std::meta::parameters_of(Fn))
43 types[i++] = std::meta::type_of(p);
53template <std::meta::info Fn>
55 constexpr std::size_t n{std::meta::parameters_of(Fn).size()};
56 std::array<const char*, n> names{};
58 for (
auto p : std::meta::parameters_of(Fn))
59 names[i++] = std::meta::has_identifier(p)
60 ? std::define_static_string(std::meta::identifier_of(p))
78template <std::meta::info Fn>
80 constexpr std::size_t n{
82 std::array<keep_alive_pair, n> out{};
83 if constexpr (n != 0) {
85 for (
auto a : std::meta::annotations_of_with_type(Fn, ^^
keep_alive_spec)) {
86 auto s{std::meta::extract<keep_alive_spec>(a)};
87 out[i++] = {s.nurse, s.patient};
100template <std::meta::info Fn>
102 for (
auto p : std::meta::parameters_of(Fn))
103 if (!std::meta::has_identifier(p))
119 return std::meta::is_constructor(c) && std::meta::is_public(c) &&
120 !std::meta::is_deleted(c) && !std::meta::is_copy_constructor(c) &&
121 !std::meta::is_move_constructor(c) &&
122 !std::meta::parameters_of(c).empty();
141 return std::meta::is_function(f) && !std::meta::is_constructor(f) &&
142 !std::meta::is_special_member_function(f) &&
143 !std::meta::is_destructor(f) && !std::meta::is_operator_function(f) &&
144 !std::meta::is_private(f) && !std::meta::is_deleted(f);
159 return std::meta::is_function(f) && std::meta::is_operator_function(f) &&
160 !std::meta::is_special_member_function(f) &&
161 !std::meta::is_private(f) && !std::meta::is_deleted(f);
201template <
class Resolution>
203 std::meta::info bound_into) {
204 if (std::meta::is_public(mem))
206 if (!std::meta::is_protected(mem))
208 if constexpr (
requires {
209 Resolution::protected_participates(mem, L, bound_into);
211 return Resolution::protected_participates(mem, L, bound_into);
212 }
else if constexpr (
requires {
213 Resolution::protected_participates(mem, L);
216 throw ::welder::diag::stale_hook_signature{};
218 return ::welder::protected_welded(std::meta::parent_of(mem), L);
241template <std::meta::info Mem>
265 return std::meta::parameters_of(f).empty();
283 constexpr auto ctx{std::meta::access_context::unchecked()};
284 constexpr std::size_t n{std::meta::nonstatic_data_members_of(^^T, ctx).size()};
285 std::array<std::meta::info, n> fs{};
289 if constexpr (n != 0) {
291 for (
auto m : std::meta::nonstatic_data_members_of(^^T, ctx))
311template <
class T, lang L,
class Resolution>
315 constexpr auto ctx{std::meta::access_context::unchecked()};
316 auto fields{std::meta::nonstatic_data_members_of(^^T, ctx)};
320 for (
auto m : fields)
321 if (!Resolution::class_member_participates(m, L, pol, ^^T))
337 return (std::meta::is_type(mem) &&
338 (std::meta::is_class_type(mem) || std::meta::is_enum_type(mem))) ||
339 std::meta::is_function(mem) || std::meta::is_variable(mem);
365 constexpr auto ctx{std::meta::access_context::unchecked()};
367 for (
auto mem : std::meta::members_of(ns, ctx)) {
368 if (std::meta::is_namespace(mem)) {
390 constexpr auto ctx{std::meta::access_context::unchecked()};
392 for (
auto mem : std::meta::members_of(ns, ctx)) {
393 if (std::meta::is_namespace(mem)) {
422template <
class Resolution>
424 std::meta::info fn,
lang L, std::meta::info bound_into) {
425 const std::meta::info cls{std::meta::parent_of(fn)};
427 const auto name{std::meta::identifier_of(fn)};
428 const bool is_static{std::meta::is_static_member(fn)};
429 std::vector<std::meta::info> out{};
430 for (
auto m : std::meta::members_of(cls, std::meta::access_context::unchecked()))
433 Resolution::class_member_participates(m, L, pol, bound_into) &&
434 std::meta::is_static_member(m) == is_static &&
435 std::meta::identifier_of(m) == name)
448template <
class Resolution>
450 std::meta::info fn,
lang L, std::meta::info bound_into) {
451 const std::meta::info cls{std::meta::parent_of(fn)};
453 std::vector<std::meta::info> out{};
454 for (
auto m : std::meta::members_of(cls, std::meta::access_context::unchecked()))
457 Resolution::class_member_participates(m, L, pol, bound_into) &&
458 std::meta::operator_of(m) == std::meta::operator_of(fn) &&
473template <
class Resolution>
475 std::meta::info fn,
lang L, std::meta::info bound_into) {
476 const std::meta::info ns{std::meta::parent_of(fn)};
478 const auto name{std::meta::identifier_of(fn)};
479 std::vector<std::meta::info> out{};
480 for (
auto m : std::meta::members_of(ns, std::meta::access_context::unchecked()))
481 if (std::meta::is_function(m) &&
482 Resolution::member_participates(m, L, pol, bound_into) &&
483 std::meta::identifier_of(m) == name)
491 std::vector<std::meta::info> (*)(std::meta::info,
lang, std::meta::info);
500 std::meta::info BoundInto>
502 constexpr std::size_t n{Select(Fn, L, BoundInto).size()};
503 std::array<std::meta::info, n> out{};
506 if constexpr (n != 0) {
507 auto v{Select(Fn, L, BoundInto)};
508 for (std::size_t i{0}; i < n; ++i)
520template <overload_selector Select>
522 std::meta::info bound_into) {
523 auto v{Select(fn, L, bound_into)};
524 return !v.empty() && v.front() == fn;
541template <
class Resolution, std::meta::info Fn, lang L>
543 if constexpr (!std::meta::has_identifier(Fn)) {
544 return std::array<std::meta::info, 1>{Fn};
546 constexpr std::size_t n{[] {
548 std::meta::parent_of(Fn))};
549 std::size_t extra{1};
553 return v.size() + extra;
555 std::array<std::meta::info, n> out{};
588template <
class Resolution, std::meta::info Type, lang L, policy_kind Pol>
590 constexpr auto ctx{std::meta::access_context::unchecked()};
591 constexpr std::size_t n{[] {
592 std::size_t count{0};
593 for (
auto c : std::meta::members_of(Type, ctx))
595 Resolution::class_member_participates(c, L, Pol, Type))
599 std::array<std::meta::info, n> out{};
600 if constexpr (n != 0) {
602 for (
auto c : std::meta::members_of(Type, ctx))
604 Resolution::class_member_participates(c, L, Pol, Type))
624template <
class Resolution, std::meta::info Type, lang L>
626 constexpr auto ctx{std::meta::access_context::unchecked()};
627 for (
auto c : std::meta::members_of(Type, ctx))
628 if (std::meta::is_constructor(c) && std::meta::parameters_of(c).empty())
629 return std::meta::is_public(c) && !std::meta::is_deleted(c) &&
630 Resolution::class_member_participates(
657 std::vector<std::meta::info>& out) {
682template <std::meta::info Type, lang L>
684 constexpr std::size_t n{[] {
685 std::vector<std::meta::info> v;
689 std::array<std::meta::info, n> types{};
692 if constexpr (n != 0) {
693 std::vector<std::meta::info> v;
welder's consteval diagnostics, collected in one place: every hand-rolled compile-time error the libr...
The stored forms of the annotation vocabulary.
consteval bool is_overload_leader(std::meta::info fn, lang L, std::meta::info bound_into)
Whether fn is the first (declaration order) member of its Select overload set — the single visit on w...
consteval auto aggregate_fields()
The fields an aggregate is initialized from: its non-static data members in declaration order (all pu...
consteval std::vector< std::meta::info > method_overload_set(std::meta::info fn, lang L, std::meta::info bound_into)
The participating method overloads sharing fn's name and static-ness, from the class where fn is decl...
consteval bool is_operator_candidate(std::meta::info f)
The shape of a bindable member operator.
consteval bool namespace_has_bound(std::meta::info ns, lang L)
Whether ns holds anything that would bind, directly or nested.
consteval bool is_unary_operator(std::meta::info f)
Whether a member operator is unary (0 parameters) vs binary (1 parameter).
consteval auto ctor_group()
The participating constructors of Type under policy Pol: every bindable-shape constructor (see is_bin...
consteval bool entity_bound(std::meta::info mem, lang L, policy_kind pol)
Whether a leaf entity binds: a welded candidate that also resolves as bound.
consteval bool is_bindable_constructor(std::meta::info c)
A non-default, non-copy/move public constructor a backend should expose.
consteval auto manual_function_group()
The semi-manual (weld_function<Fn>) group: Fn first — the user's named entity resolves the group's ta...
std::vector< std::meta::info >(*)(std::meta::info, lang, std::meta::info) overload_selector
The signature of an overload-set selector specialization: the representative overload,...
consteval std::vector< std::meta::info > function_overload_set(std::meta::info fn, lang L, std::meta::info bound_into)
The participating free-function overloads sharing fn's name, from fn's declaring namespace,...
consteval bool is_method_candidate(std::meta::info f)
The shape of a bindable method: a plain non-private member function.
consteval auto overload_group()
Select's overload set for Fn as a fixed-size, splice-ready static array.
consteval auto param_types()
A function's parameter types, as a static array of reflections.
consteval bool default_ctor_admitted()
Whether the resolution admits Type's DEFAULT constructor.
consteval void collect_native_bases(std::meta::info type, lang L, std::vector< std::meta::info > &out)
Collect the native bases of type for L: its nearest welded ancestors.
consteval bool namespace_has_bindable(std::meta::info ns, lang L)
The greedy twin of namespace_has_bound: whether ns holds any bindable kind (ignoring the weld marker)...
consteval bool member_access_admitted(std::meta::info mem, lang L, std::meta::info bound_into)
Is mem's access level admitted for binding under Resolution?
consteval bool all_params_named()
Whether every parameter of Fn carries an identifier.
consteval std::vector< std::meta::info > operator_overload_set(std::meta::info fn, lang L, std::meta::info bound_into)
The participating operator overloads sharing fn's target slot (same operator and arity — hence the sa...
consteval auto param_names()
A function's parameter names, in order.
consteval bool aggregate_initializable()
Whether to synthesize an aggregate field constructor for T (language L, resolution Resolution).
consteval auto keep_alive_pairs()
The keep_alive dependencies declared on Fn, in declaration order.
consteval auto native_base_types()
The native bases of Type for L as a static array of type reflections.
consteval bool is_bindable_kind(std::meta::info mem)
The member kinds welder can expose from a namespace.
consteval bool welded_for(std::meta::info type, lang L)
Is type welded for language L — i.e.
policy_kind
How greedily a type's members are reflected for binding.
@ automatic
Reflect every member unless explicitly excluded (default).
lang
The target languages welder ships rods for — but not the whole value space.
consteval policy_kind policy_of(std::meta::info type)
The reflection policy declared on type, defaulting to automatic.
consteval bool member_bound(std::meta::info member, lang L, policy_kind pol)
The core decision a backend asks for each member: does member bind for language L under policy pol?
consteval std::vector< std::meta::info > public_bases(std::meta::info type)
The types of the public base classes of type.
Language-agnostic resolution: given a reflected type/member and a target language,...
Splice-based accessors for data member Mem — the pointer-to-member-free route the rods bind a protect...
static void set(class_type &c, const field_type &v)
Write the field (instantiated only for mutable fields).
typename[:std::meta::type_of(Mem):] field_type
The field's declared type (const included).
typename[:std::meta::parent_of(Mem):] class_type
The declaring class.
static const field_type & get(const class_type &c)
Read the field (a reference, so backends can apply their reference-internal return semantics,...
A keep_alive lifetime dependency: a (nurse, patient) index pair.
unsigned patient
The dependant kept alive until the nurse is collected.
unsigned nurse
The keeper whose collection bounds the dependency.
The stored form of a keep_alive annotation: a lifetime dependency between two of a call's entities,...