31namespace welder::inline v0::detail {
41template <std::meta::info Fn>
43 constexpr std::size_t n{std::meta::parameters_of(Fn).size()};
44 std::array<std::meta::info, n> types{};
46 for (
auto p : std::meta::parameters_of(Fn))
47 types[i++] = std::meta::type_of(p);
61template <std::meta::info Fn>
63 auto ps = std::meta::parameters_of(Fn);
65 for (std::size_t i = ps.size(); i > 0; --i) {
66 if (!std::meta::has_default_argument(ps[i - 1]))
79template <std::meta::info Fn>
81 constexpr std::size_t n{std::meta::parameters_of(Fn).size()};
82 std::array<const char*, n> names{};
84 for (
auto p : std::meta::parameters_of(Fn))
85 names[i++] = std::meta::has_identifier(p)
86 ? std::define_static_string(std::meta::identifier_of(p))
104template <std::meta::info Fn>
106 constexpr std::size_t n{
108 std::array<keep_alive_pair, n> out{};
109 if constexpr (n != 0) {
111 for (
auto a : std::meta::annotations_of_with_type(Fn, ^^
keep_alive_spec)) {
112 auto s{std::meta::extract<keep_alive_spec>(a)};
113 out[i++] = {s.nurse, s.patient};
126template <std::meta::info Fn>
128 for (
auto p : std::meta::parameters_of(Fn))
129 if (!std::meta::has_identifier(p))
148 return std::meta::is_constructor(c) && std::meta::is_public(c) &&
149 !std::meta::is_deleted(c) && !std::meta::is_copy_constructor(c) &&
150 !std::meta::is_move_constructor(c) &&
151 !std::meta::parameters_of(c).empty();
170 return std::meta::is_function(f) && !std::meta::is_constructor(f) &&
171 !std::meta::is_special_member_function(f) &&
172 !std::meta::is_destructor(f) && !std::meta::is_operator_function(f) &&
173 !std::meta::is_private(f) && !std::meta::is_deleted(f);
188 return std::meta::is_function(f) && std::meta::is_operator_function(f) &&
189 !std::meta::is_special_member_function(f) &&
190 !std::meta::is_private(f) && !std::meta::is_deleted(f);
209consteval bool decays_to(std::meta::info t, std::meta::info type) {
210 return std::meta::dealias(std::meta::remove_cvref(t)) ==
211 std::meta::dealias(type);
220 return std::meta::is_function(f) && std::meta::is_operator_function(f) &&
221 !std::meta::is_class_member(f) && !std::meta::is_deleted(f);
233 std::meta::operator_of(f) != std::meta::operators::op_less_less)
235 auto ps{std::meta::parameters_of(f)};
238 const auto p0{std::meta::type_of(ps[0])};
239 return std::meta::is_lvalue_reference_type(p0) &&
241 decays_to(std::meta::type_of(ps[1]), type);
254 for (
auto p : std::meta::parameters_of(f)) {
255 const auto t{std::meta::type_of(p)};
256 if (
decays_to(t, type) && !std::meta::is_rvalue_reference_type(t))
271 if (std::meta::is_class_member(f))
273 auto ps{std::meta::parameters_of(f)};
274 return ps.size() == 2 && !
decays_to(std::meta::type_of(ps[0]), type);
286template <auto Fns, std::meta::info Type,
bool Reflected>
288 constexpr std::size_t n{[] {
295 std::array<std::meta::info, n> out{};
297 if constexpr (n != 0) {
312 auto p{std::meta::parent_of(type)};
313 while (!std::meta::is_namespace(p))
314 p = std::meta::parent_of(p);
325 std::meta::info type) {
326 for (
auto p : std::meta::parameters_of(f))
327 if (!
decays_to(std::meta::type_of(p), type))
328 return std::meta::type_of(p);
338template <auto Fns, std::meta::info Type>
358template <
class A,
class B, cmp_slot S>
363 static bool call(
const A& a,
const B& b) {
383template <
class T, std::meta::info Fn>
385 std::ostringstream os{};
427template <
class Resolution>
429 std::meta::info bound_into) {
430 if (std::meta::is_public(mem))
432 if (!std::meta::is_protected(mem))
434 if constexpr (
requires {
435 Resolution::protected_participates(mem, L, bound_into);
437 return Resolution::protected_participates(mem, L, bound_into);
438 }
else if constexpr (
requires {
439 Resolution::protected_participates(mem, L);
442 throw ::welder::diag::stale_hook_signature{};
444 return ::welder::protected_welded(std::meta::parent_of(mem), L);
467template <std::meta::info Mem>
494 const std::size_t n{std::meta::parameters_of(f).size()};
495 return (std::meta::is_class_member(f) && !std::meta::is_static_member(f))
515 constexpr auto ctx{std::meta::access_context::unchecked()};
516 constexpr std::size_t n{std::meta::nonstatic_data_members_of(^^T, ctx).size()};
517 std::array<std::meta::info, n> fs{};
521 if constexpr (n != 0) {
523 for (
auto m : std::meta::nonstatic_data_members_of(^^T, ctx))
543template <
class T, lang L,
class Resolution>
547 constexpr auto ctx{std::meta::access_context::unchecked()};
548 auto fields{std::meta::nonstatic_data_members_of(^^T, ctx)};
552 for (
auto m : fields) {
558 if (!std::meta::has_identifier(m))
560 if (!Resolution::class_member_participates(m, L, pol, ^^T))
584 std::size_t required{0};
588 if constexpr (fields.size() != 0) {
589 for (std::size_t i{0}; i < fields.size(); ++i)
590 if (!std::meta::has_default_member_initializer(fields[i]))
614 if (!std::meta::is_default_constructible_type(^^T))
615 return fields.size();
618 if constexpr (fields.size() != 0) {
619 for (std::size_t i{from}; i < fields.size(); ++i)
620 if (!std::meta::is_copy_constructible_type(
621 std::meta::type_of(fields[i])))
638 return (std::meta::is_type(mem) &&
639 (std::meta::is_class_type(mem) || std::meta::is_enum_type(mem))) ||
640 std::meta::is_function(mem) || std::meta::is_variable(mem);
666 constexpr auto ctx{std::meta::access_context::unchecked()};
668 for (
auto mem : std::meta::members_of(ns, ctx)) {
669 if (std::meta::is_namespace(mem)) {
691 constexpr auto ctx{std::meta::access_context::unchecked()};
693 for (
auto mem : std::meta::members_of(ns, ctx)) {
694 if (std::meta::is_namespace(mem)) {
726template <
class Resolution>
728 std::meta::info fn,
lang L, std::meta::info bound_into) {
729 const std::meta::info cls{std::meta::parent_of(fn)};
731 const auto name{std::meta::identifier_of(fn)};
732 const bool is_static{std::meta::is_static_member(fn)};
733 std::vector<std::meta::info> out{};
734 for (
auto m : std::meta::members_of(cls, std::meta::access_context::unchecked()))
737 Resolution::class_member_participates(m, L, pol, bound_into) &&
739 std::meta::is_static_member(m) == is_static &&
740 std::meta::identifier_of(m) == name)
756template <
class Resolution>
758 std::meta::info bound_into,
759 std::vector<std::meta::info>& out) {
761 if (!Resolution::is_native_base(base, L, src))
765 std::meta::members_of(src, std::meta::access_context::unchecked()))
768 Resolution::class_member_participates(m, L, pol, bound_into))
785template <
class Resolution>
788 std::vector<std::meta::info> out{};
792 std::meta::access_context::unchecked()))
794 Resolution::class_member_participates(m, L, pol, type))
809template <
class Resolution>
811 std::meta::info fn,
lang L, std::meta::info bound_into) {
812 std::vector<std::meta::info> out{};
814 if (std::meta::operator_of(m) == std::meta::operator_of(fn) &&
829template <
class Resolution>
832 std::vector<std::meta::info> out{};
835 std::meta::access_context::unchecked()))
837 Resolution::class_member_participates(m, L, pol, type))
852template <
class Resolution>
855 std::array<bool, 4> covered{};
859 switch (std::meta::operator_of(m)) {
860 case std::meta::operators::op_less:
863 case std::meta::operators::op_less_equals:
866 case std::meta::operators::op_greater:
869 case std::meta::operators::op_greater_equals:
888template <
class Resolution>
890 std::meta::info fn,
lang L, std::meta::info bound_into) {
891 const std::meta::info ns{std::meta::parent_of(fn)};
893 const auto name{std::meta::identifier_of(fn)};
894 std::vector<std::meta::info> out{};
895 for (
auto m : std::meta::members_of(ns, std::meta::access_context::unchecked()))
896 if (std::meta::is_function(m) &&
897 Resolution::member_participates(m, L, pol, bound_into) &&
898 std::meta::identifier_of(m) == name)
906 std::vector<std::meta::info> (*)(std::meta::info,
lang, std::meta::info);
915 std::meta::info BoundInto>
917 constexpr std::size_t n{Select(Fn, L, BoundInto).size()};
918 std::array<std::meta::info, n> out{};
921 if constexpr (n != 0) {
922 auto v{Select(Fn, L, BoundInto)};
923 for (std::size_t i{0}; i < n; ++i)
935template <overload_selector Select>
937 std::meta::info bound_into) {
938 auto v{Select(fn, L, bound_into)};
939 return !v.empty() && v.front() == fn;
956template <
class Resolution, std::meta::info Fn, lang L>
958 if constexpr (!std::meta::has_identifier(Fn)) {
959 return std::array<std::meta::info, 1>{Fn};
961 constexpr std::size_t n{[] {
963 std::meta::parent_of(Fn))};
964 std::size_t extra{1};
968 return v.size() + extra;
970 std::array<std::meta::info, n> out{};
1003template <
class Resolution, std::meta::info Type, lang L, policy_kind Pol>
1005 constexpr auto ctx{std::meta::access_context::unchecked()};
1006 constexpr std::size_t n{[] {
1007 std::size_t count{0};
1008 for (
auto c : std::meta::members_of(Type, ctx))
1010 Resolution::class_member_participates(c, L, Pol, Type))
1014 std::array<std::meta::info, n> out{};
1015 if constexpr (n != 0) {
1017 for (
auto c : std::meta::members_of(Type, ctx))
1019 Resolution::class_member_participates(c, L, Pol, Type))
1039template <
class Resolution, std::meta::info Type, lang L>
1041 constexpr auto ctx{std::meta::access_context::unchecked()};
1042 for (
auto c : std::meta::members_of(Type, ctx))
1043 if (std::meta::is_constructor(c) && std::meta::parameters_of(c).empty())
1044 return std::meta::is_public(c) && !std::meta::is_deleted(c) &&
1045 Resolution::class_member_participates(
1071template <
class Resolution, std::meta::info Type, lang L>
1073 constexpr auto ctx{std::meta::access_context::unchecked()};
1074 bool declared{
false};
1075 for (
auto c : std::meta::members_of(Type, ctx))
1076 if (std::meta::is_copy_constructor(c)) {
1078 if (std::meta::is_public(c) && !std::meta::is_deleted(c) &&
1079 Resolution::class_member_participates(
1098template <std::meta::info Type>
1100 constexpr auto ctx{std::meta::access_context::unchecked()};
1101 for (
auto c : std::meta::members_of(Type, ctx))
1102 if (std::meta::is_move_constructor(c) &&
1103 (!std::meta::annotations_of_with_type(c, ^^
include_spec).empty() ||
1104 !std::meta::annotations_of_with_type(c, ^^
only_spec).empty()))
1134 for (
auto a : std::meta::annotations_of(m)) {
1135 auto t{std::meta::type_of(a)};
1136 if (std::meta::has_template_arguments(t) &&
1153 if (!explicit_name.empty())
1167template <
class Resolution>
1169 std::meta::info bound_into,
1170 std::vector<std::meta::info>& out) {
1172 if (!Resolution::is_native_base(base, L, src))
1176 std::meta::members_of(src, std::meta::access_context::unchecked()))
1179 Resolution::class_member_participates(m, L, pol, bound_into) &&
1197template <
class Resolution>
1199 std::meta::info src,
lang L, std::meta::info bound_into,
1200 const std::vector<std::vector<std::string>>& keys) {
1202 if (!Resolution::is_native_base(base, L, src))
1204 constexpr auto ctx{std::meta::access_context::unchecked()};
1206 auto clashes{[&](std::meta::info m) {
1208 for (
const auto& k : keys)
1213 for (
auto m : std::meta::nonstatic_data_members_of(src, ctx))
1214 if (std::meta::has_identifier(m) &&
1216 Resolution::class_member_participates(m, L, pol, bound_into) &&
1219 for (
auto m : std::meta::members_of(src, ctx))
1222 Resolution::class_member_participates(m, L, pol, bound_into) &&
1244template <
class Resolution>
1247 std::vector<std::meta::info> acc{};
1250 for (
auto m : acc) {
1254 if (std::meta::is_static_member(m))
1256 if (std::meta::is_virtual(m))
1262 std::vector<property_entry> props{};
1263 std::vector<std::vector<std::string>> keys{};
1264 for (
auto m : acc) {
1267 if (!std::meta::parameters_of(m).empty() ||
1268 std::meta::dealias(std::meta::return_type_of(m)) == ^^
void ||
1269 !std::meta::is_const(m) ||
1270 std::meta::is_rvalue_reference_qualified(m))
1273 for (
const auto& k : keys)
1276 props.push_back({m, std::meta::info{}});
1277 keys.push_back(std::move(key));
1279 for (
auto m : acc) {
1282 if (std::meta::parameters_of(m).size() != 1 ||
1283 std::meta::is_rvalue_reference_qualified(m))
1286 bool matched{
false};
1287 for (std::size_t i{0}; i < keys.size(); ++i) {
1290 if (props[i].
setter != std::meta::info{})
1292 props[i].setter = m;
1315template <std::meta::info Getter, lang L,
class Style>
1317 constexpr std::string_view explicit_name{std::define_static_string(
1319 if constexpr (!explicit_name.empty())
1320 return explicit_name.data();
1322 return std::define_static_string(
1348 std::vector<std::meta::info>& out) {
1358 out.push_back(base);
1373template <std::meta::info Type, lang L>
1375 constexpr std::size_t n{[] {
1376 std::vector<std::meta::info> v;
1380 std::array<std::meta::info, n> types{};
1383 if constexpr (n != 0) {
1384 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 std::meta::info enclosing_namespace(std::meta::info type)
The nearest enclosing namespace of type — the scope its anchored free operators are swept from (for a...
consteval auto partition_reflected()
Split slot group Fns by free_operator_reflected — the entries whose reflectedness equals Reflected,...
consteval std::vector< property_entry > property_entries(std::meta::info type, lang L)
The resolved properties of type for language L: every participating accessor collected (own + flatten...
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 std::size_t aggregate_required_arity()
How many leading fields the synthesized aggregate field constructor REQUIRES: everything up to and in...
consteval std::vector< std::meta::info > operator_entries(std::meta::info type, lang L)
Every participating operator entry of type's binding — member operators (own + flattened bases') and ...
consteval void validate_property_shadowing(std::meta::info src, lang L, std::meta::info bound_into, const std::vector< std::vector< std::string > > &keys)
Guard the property surface against name shadowing: no property's key may equal a bound data member's ...
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 an operator function is unary vs binary.
consteval auto ctor_group()
The participating constructors of Type under policy Pol: every bindable-shape constructor (see is_bin...
consteval std::vector< std::meta::info > stringifier_entries(std::meta::info type, lang L)
The participating stringifier entries for type: free operator<<(std::ostream&, T) overloads of its en...
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 std::meta::info comparison_operand(std::meta::info f, std::meta::info type)
The operand a comparison synthesized from spaceship overload f takes: the parameter type that is not ...
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::size_t trailing_default_count()
How many TRAILING parameters of Fn carry a C++ default argument.
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 bool copy_ctor_admitted()
Whether the resolution admits Type's copy constructor — the marks half of the copy decision; the carr...
consteval bool has_heterogeneous_comparison()
Whether spaceship group Fns contains a heterogeneous overload (an operand that is not Type itself) — ...
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 bool free_operator_reflected(std::meta::info f, std::meta::info type)
Whether anchored free operator f binds reflected for type: type is the right operand and the left is ...
consteval void collect_accessors(std::meta::info src, lang L, std::meta::info bound_into, std::vector< std::meta::info > &out)
Collect the participating accessor-marked member functions visible on bound_into's binding: src's own...
consteval std::vector< std::string > property_key(std::meta::info mem, accessor_role role, lang L)
The pairing key of accessor mem's property for language L: the case-normalized word sequence of its e...
consteval std::array< bool, 4 > covered_comparison_slots(std::meta::info type, lang L)
Which relational slots (lt, le, gt, ge — indexed by cmp_slot) are already covered by an explicit part...
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 std::size_t aggregate_defaults_from()
The field index from which a value-extracting backend (the Python rods) can attach the NSDMI defaults...
consteval bool free_operator_anchored(std::meta::info f, std::meta::info type)
Whether free operator f is anchored on type: some parameter decays to exactly type (an rvalue-referen...
consteval bool is_free_operator_candidate(std::meta::info f)
The shape of a bindable freestanding operator: a non-deleted namespace-scope operator function.
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 std::vector< std::meta::info > operator_slot_set(std::meta::info fn, lang L, std::meta::info bound_into)
The participating operator entries sharing fn's target slot (same operator and arity — hence the same...
consteval const char * property_bound_name()
The bound name of the property Getter defines, for language L under name style Style: the mark's expl...
consteval bool all_params_named()
Whether every parameter of Fn carries an identifier.
consteval bool is_stringifier_for(std::meta::info f, std::meta::info type)
Whether f is the stream-inserter ("stringifier") shape for type: operator<<(std::ostream&,...
std::string stringify(const T &self)
The stringifier wrapper every runtime rod binds for a swept ostream inserter (see is_stringifier_for)...
consteval void collect_member_operators(std::meta::info src, lang L, std::meta::info bound_into, std::vector< std::meta::info > &out)
Collect the participating member operators visible on bound_into's binding: src's own,...
consteval bool decays_to(std::meta::info t, std::meta::info type)
Whether type reflection t is exactly the (welded) type type once stripped of cv/ref qualifiers and al...
consteval void validate_move_ctor_marks()
Reject an include/only mark on a move constructor of Type.
consteval auto param_names()
A function's parameter names, in order.
consteval bool carries_weld_as(std::meta::info m)
Does m carry a (templated) weld_as annotation?
cmp_slot
The rewritten-expression comparison a rod binds for a type whose C++ comparisons come from operator<=...
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 std::string strip_accessor_word(std::string_view styled)
Strip the accessor word off an already styled accessor name, re-joining the remainder in styled's own...
consteval std::vector< std::string > accessor_property_words(std::string_view id)
The words of an accessor's property: id split, with a leading get / set word stripped when at least o...
consteval std::vector< std::string > split_words(std::string_view id)
Split an identifier into lower-cased words, however it was spelled.
consteval bool welded_for(std::meta::info type, lang L)
Is type welded for language L — i.e.
consteval bool is_accessor_for(std::meta::info member, lang L)
Does member supply either property half for language L — i.e.
consteval bool accessor_marked(std::meta::info member, accessor_role role, lang L)
Does member carry a getter/setter mark of role covering L?
policy_kind
How greedily a type's members are reflected for binding.
@ automatic
Reflect every member unless explicitly excluded (default).
constexpr detail::accessor_spec setter
Mark a member function as a property setter (exactly one parameter) — the write half of welder::gette...
lang
The target languages welder ships rods for — but not the whole value space.
accessor_role
Which half of a property a marked accessor function supplies.
@ getter
The function reads the property's value (const, no parameters).
@ setter
The function writes it (exactly one parameter).
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::string accessor_explicit_name(std::meta::info member, accessor_role role, lang L)
The explicit property name an accessor mark of role forces for L, or "" when the name derives from th...
consteval std::vector< std::meta::info > public_bases(std::meta::info type)
The types of the public base classes of type.
Language-agnostic name styling: reshape a C++ identifier into a target language's naming convention,...
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,...
The stored form of an include mark: the languages a member is opted into.
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,...
The stored form of an only mark: the complete set of languages a member may bind for — implicitly,...
One resolved property: its getter and its (optional) setter.
std::meta::info getter
The read half (always present).
std::meta::info setter
The write half; a null reflection = read-only.
static bool call(const A &a, const B &b)
Evaluate a OP b through C++'s rewriting rules.
The stored form of a weld_as annotation: a forced target-language name.
Thrown by property_entries (<welder/bind_traits.hpp>) when one function carries both a getter and a s...
Thrown by property_entries (<welder/bind_traits.hpp>) when an accessor-marked function also carries a...
Thrown by property_entries (<welder/bind_traits.hpp>) when two getters (or two setters) resolve to th...
Thrown by validate_move_ctor_marks (<welder/bind_traits.hpp>) — the carriage runs it for every welded...
Thrown by property_entries (<welder/bind_traits.hpp>) when a resolved property name collides with a b...
Thrown by property_entries (<welder/bind_traits.hpp>) when a participating setter's property has no p...
Thrown by property_entries (<welder/bind_traits.hpp>) on an accessor-marked static member function: s...
Thrown by property_entries (<welder/bind_traits.hpp>) on an accessor-marked virtual member function: ...