mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
Initial implementation of std::meta::{,{,non}static_data_}members_of and std::meta::has_inaccessible_nonstatic_data_members.
Doesn't handle yet https://eel.is/c++draft/meta.reflection#member.queries-3.5.2 nor does it test https://eel.is/c++draft/meta.reflection#member.queries-3.4 undeduced placeholder type, the namespace queries definitely need better testsuite coverage. Doesn't handle yet the underlying variables of tuple using namespace scope structured bindings, doesn't have any tests for structured bindings, guess structured binding packs need to be tested too. And for members_of (^^::, access_context::current ()) I guess we need to decide if e.g. __builtin_ etc. prefixed builtins or anticipated normal identifier builtins should appear or not.
This commit is contained in:
committed by
Marek Polacek
parent
552ae76eb4
commit
8cc8c8143b
@@ -6007,6 +6007,415 @@ eval_is_accessible (location_t loc, const constexpr_ctx *ctx, tree r,
|
||||
return boolean_true_node;
|
||||
}
|
||||
|
||||
/* Returns true if R is C-members-of-representable from
|
||||
current point P. */
|
||||
|
||||
static bool
|
||||
members_of_representable_p (tree c, tree r)
|
||||
{
|
||||
if (TREE_CODE (r) == CONST_DECL)
|
||||
return false;
|
||||
if (LAMBDA_TYPE_P (c) && !LAMBDA_FUNCTION_P (r))
|
||||
return false;
|
||||
if (TYPE_P (r))
|
||||
{
|
||||
if (CP_DECL_CONTEXT (TYPE_NAME (r)) != c)
|
||||
return false;
|
||||
if (LAMBDA_TYPE_P (r))
|
||||
return false;
|
||||
if (OVERLOAD_TYPE_P (r))
|
||||
return true;
|
||||
if (typedef_variant_p (r))
|
||||
return true;
|
||||
}
|
||||
else if (DECL_P (r))
|
||||
{
|
||||
if (CP_DECL_CONTEXT (r) != c)
|
||||
return false;
|
||||
if (DECL_CLASS_TEMPLATE_P (r)
|
||||
|| DECL_FUNCTION_TEMPLATE_P (r)
|
||||
|| variable_template_p (r)
|
||||
|| DECL_ALIAS_TEMPLATE_P (r)
|
||||
|| concept_definition_p (r)
|
||||
|| TREE_CODE (r) == FIELD_DECL
|
||||
|| TREE_CODE (r) == NAMESPACE_DECL)
|
||||
return true;
|
||||
if (VAR_P (r) && !undeduced_auto_decl (r))
|
||||
return true;
|
||||
if (TREE_CODE (r) == FUNCTION_DECL)
|
||||
{
|
||||
if (undeduced_auto_decl (r))
|
||||
return false;
|
||||
// TODO: check if constraints are satisfied.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Callback for vector qsort to compare members by ascending DECL_UID. */
|
||||
|
||||
static int
|
||||
members_cmp (const void *a, const void *b)
|
||||
{
|
||||
const constructor_elt *ea = (const constructor_elt *) a;
|
||||
const constructor_elt *eb = (const constructor_elt *) b;
|
||||
tree vala = REFLECT_EXPR_HANDLE (ea->value);
|
||||
tree valb = REFLECT_EXPR_HANDLE (eb->value);
|
||||
if (TYPE_P (vala))
|
||||
vala = TYPE_NAME (vala);
|
||||
if (TYPE_P (valb))
|
||||
valb = TYPE_NAME (valb);
|
||||
if (DECL_UID (vala) < DECL_UID (valb))
|
||||
return -1;
|
||||
if (DECL_UID (vala) > DECL_UID (valb))
|
||||
return 1;
|
||||
gcc_assert (ea == eb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enumerate members of namespace NS for eval_members_of. */
|
||||
|
||||
static vec<constructor_elt, va_gc> *
|
||||
namespace_members_of (location_t loc, tree ns)
|
||||
{
|
||||
vec<constructor_elt, va_gc> *elts = nullptr;
|
||||
for (tree b : *DECL_NAMESPACE_BINDINGS (ns))
|
||||
{
|
||||
tree m = b;
|
||||
if (VAR_P (b) && DECL_ANON_UNION_VAR_P (b))
|
||||
continue;
|
||||
if (TREE_CODE (b) == TYPE_DECL)
|
||||
m = TREE_TYPE (b);
|
||||
if (!members_of_representable_p (ns, m))
|
||||
continue;
|
||||
if (DECL_DECOMPOSITION_P (m) && !DECL_DECOMP_IS_BASE (m))
|
||||
continue;
|
||||
/* I don't see much point in calling eval_is_accessible here,
|
||||
won't it always return true? */
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
}
|
||||
if (elts)
|
||||
elts->qsort (members_cmp);
|
||||
return elts;
|
||||
}
|
||||
|
||||
/* Enumerate members of class R for eval_*members_of. KIND is
|
||||
0 for members_of, 1 for static_members_of, 2 for
|
||||
nonstatic_members_of and 3 for has_inaccessible_nonstatic_data_members.
|
||||
For KIND 3 don't append any elts except for the first one for
|
||||
which is_accessible returned false. */
|
||||
|
||||
static vec<constructor_elt, va_gc> *
|
||||
class_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
|
||||
tree actx, tree call, bool *non_constant_p,
|
||||
tree *jump_target, int kind)
|
||||
{
|
||||
if (kind == 0)
|
||||
{
|
||||
if (modules_p ())
|
||||
lazy_load_pendings (TYPE_NAME (r));
|
||||
if (CLASSTYPE_LAZY_DEFAULT_CTOR (r))
|
||||
lazily_declare_fn (sfk_constructor, r);
|
||||
if (CLASSTYPE_LAZY_COPY_CTOR (r))
|
||||
lazily_declare_fn (sfk_copy_constructor, r);
|
||||
if (CLASSTYPE_LAZY_MOVE_CTOR (r))
|
||||
lazily_declare_fn (sfk_move_constructor, r);
|
||||
if (CLASSTYPE_LAZY_DESTRUCTOR (r))
|
||||
lazily_declare_fn (sfk_destructor, r);
|
||||
if (CLASSTYPE_LAZY_COPY_ASSIGN (r))
|
||||
lazily_declare_fn (sfk_copy_assignment, r);
|
||||
if (CLASSTYPE_LAZY_MOVE_ASSIGN (r))
|
||||
lazily_declare_fn (sfk_move_assignment, r);
|
||||
}
|
||||
auto_vec <tree, 6> implicitly_declared;
|
||||
vec<constructor_elt, va_gc> *elts = nullptr;
|
||||
for (tree field = TYPE_FIELDS (r); field; field = DECL_CHAIN (field))
|
||||
{
|
||||
tree m = field;
|
||||
if (TREE_CODE (field) == FIELD_DECL && DECL_ARTIFICIAL (field))
|
||||
continue; /* Ignore bases. */
|
||||
else if (DECL_SELF_REFERENCE_P (field))
|
||||
continue;
|
||||
else if (TREE_CODE (field) == TYPE_DECL)
|
||||
m = TREE_TYPE (field);
|
||||
else if (TREE_CODE (field) == FUNCTION_DECL)
|
||||
{
|
||||
/* Ignore cloned cdtors. */
|
||||
if (DECL_COMPLETE_CONSTRUCTOR_P (field)
|
||||
|| DECL_BASE_CONSTRUCTOR_P (field)
|
||||
|| DECL_COMPLETE_DESTRUCTOR_P (field)
|
||||
|| DECL_BASE_DESTRUCTOR_P (field)
|
||||
|| DECL_DELETING_DESTRUCTOR_P (field))
|
||||
continue;
|
||||
}
|
||||
if (members_of_representable_p (r, m))
|
||||
{
|
||||
if (kind == 1
|
||||
&& eval_is_variable (m, REFLECT_UNDEF) != boolean_true_node)
|
||||
continue; /* For static_data_members_of only include
|
||||
is_variable. */
|
||||
else if ((kind == 2 || kind == 3)
|
||||
&& eval_is_nonstatic_data_member (m) != boolean_true_node)
|
||||
continue; /* For nonstatic_data_members_of only include
|
||||
is_nonstatic_data_member. */
|
||||
tree a = eval_is_accessible (loc, ctx, m, actx, call, non_constant_p,
|
||||
jump_target);
|
||||
if (*jump_target || *non_constant_p)
|
||||
return nullptr;
|
||||
if (a == boolean_false_node)
|
||||
{
|
||||
if (kind == 3 && elts == nullptr)
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, boolean_true_node);
|
||||
continue;
|
||||
}
|
||||
gcc_assert (a == boolean_true_node);
|
||||
if (kind == 0
|
||||
&& TREE_CODE (m) == FUNCTION_DECL
|
||||
&& DECL_ARTIFICIAL (m))
|
||||
{
|
||||
/* Implicitly-declared special members appear after any user
|
||||
declared members */
|
||||
implicitly_declared.safe_push (m);
|
||||
continue;
|
||||
}
|
||||
else if (kind == 3)
|
||||
continue;
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
}
|
||||
}
|
||||
/* TYPE_DECLs in TYPE_FIELDS come after other decls, so for members_of
|
||||
the declaration order is not preserved. */
|
||||
if (kind == 0 && elts)
|
||||
elts->qsort (members_cmp);
|
||||
if (kind == 0 && !implicitly_declared.is_empty ())
|
||||
{
|
||||
gcc_assert (implicitly_declared.length () <= 6);
|
||||
for (tree m : implicitly_declared)
|
||||
if (default_ctor_p (m))
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
for (tree m : implicitly_declared)
|
||||
if (DECL_COPY_CONSTRUCTOR_P (m))
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
for (tree m : implicitly_declared)
|
||||
if (special_function_p (m) == sfk_copy_assignment)
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
for (tree m : implicitly_declared)
|
||||
if (DECL_MOVE_CONSTRUCTOR_P (m))
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
for (tree m : implicitly_declared)
|
||||
if (special_function_p (m) == sfk_move_assignment)
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
for (tree m : implicitly_declared)
|
||||
if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (m))
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
|
||||
get_reflection_raw (loc, m));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return elts;
|
||||
}
|
||||
|
||||
/* Implement std::meta::members_of.
|
||||
A declaration D members-of-precedes a point P if D precedes either P or the
|
||||
point immediately following the class-specifier of the outermost class for
|
||||
which P is in a complete-class context.
|
||||
A declaration D of a member M of a class or namespace Q is
|
||||
Q-members-of-eligible if
|
||||
-- the host scope of D is the class scope or namespace scope associated
|
||||
with Q,
|
||||
-- D is not a friend declaration,
|
||||
-- M is not a closure type,
|
||||
-- M is not a specialization of a template,
|
||||
-- if Q is a class that is not a closure type, then M is a direct member of
|
||||
Q that is not a variant member of a nested anonymous union of Q, and
|
||||
-- if Q is a closure type, then M is a function call operator or function
|
||||
call operator template.
|
||||
It is implementation-defined whether declarations of other members of a
|
||||
closure type Q are Q-members-of-eligible.
|
||||
A member M of a class or namespace Q is Q-members-of-representable from a
|
||||
point P if a Q-members-of-eligible declaration of M members-of-precedes P,
|
||||
and M is
|
||||
-- a class or enumeration type
|
||||
-- a type alias
|
||||
-- a class template, function template, variable template, alias template,
|
||||
or concept,
|
||||
-- a variable or reference V for which the type of V does not contain an
|
||||
undeduced placeholder type,
|
||||
-- a function F for which
|
||||
-- the type of F does not contain an undeduced placeholder type,
|
||||
-- the constraints (if any) of F are satisfied, and
|
||||
-- if F is a prospective destructor, F is the selected destructor,
|
||||
-- a non-static data member,
|
||||
-- a namespace, or
|
||||
-- a namespace alias.
|
||||
Returns: A vector containing reflections of all members M of the entity Q
|
||||
represented by dealias(r) for which
|
||||
-- M is Q-members-of-representable from some point in the evaluation
|
||||
context and
|
||||
-- is_accessible(^^M, ctx) is true.
|
||||
If dealias(r) represents a class C, then the vector also contains
|
||||
reflections representing all unnamed bit-fields B whose declarations
|
||||
inhabit the class scope corresponding to C for which
|
||||
is_accessible(^^B, ctx) is true.
|
||||
Reflections of class members and unnamed bit-fields that are declared
|
||||
appear in the order in which they are declared.
|
||||
Throws: meta::exception unless dealias(r) is a reflection representing
|
||||
either a class type that is complete from some point in the evaluation
|
||||
context or a namespace. */
|
||||
|
||||
static tree
|
||||
eval_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
|
||||
tree actx, tree call, bool *non_constant_p,
|
||||
tree *jump_target)
|
||||
{
|
||||
if (TYPE_P (r) && typedef_variant_p (r))
|
||||
r = strip_typedefs (r);
|
||||
else if (TREE_CODE (r) == NAMESPACE_DECL)
|
||||
r = ORIGINAL_NAMESPACE (r);
|
||||
vec<constructor_elt, va_gc> *elts;
|
||||
if (TREE_CODE (r) == NAMESPACE_DECL)
|
||||
elts = namespace_members_of (loc, r);
|
||||
else if (CLASS_TYPE_P (r) && COMPLETE_TYPE_P (r))
|
||||
{
|
||||
elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
|
||||
jump_target, 0);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
else if (*non_constant_p)
|
||||
return call;
|
||||
}
|
||||
else
|
||||
return throw_exception (loc, ctx,
|
||||
N_("neither complete class type nor namespace"),
|
||||
r, jump_target);
|
||||
return get_vector_of_info_elts (elts);
|
||||
}
|
||||
|
||||
/* Implement std::meta::static_data_members_of.
|
||||
Returns: A vector containing each element e of members_of(type, ctx) such
|
||||
that is_variable(e) is true, preserving their order.
|
||||
Throws: meta::exception unless dealias(type) represents a class type that
|
||||
is complete from some point in the evaluation context. */
|
||||
|
||||
static tree
|
||||
eval_static_data_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
|
||||
tree actx, tree call, bool *non_constant_p,
|
||||
tree *jump_target)
|
||||
{
|
||||
if (TYPE_P (r) && typedef_variant_p (r))
|
||||
r = strip_typedefs (r);
|
||||
vec<constructor_elt, va_gc> *elts = nullptr;
|
||||
if (CLASS_TYPE_P (r) && COMPLETE_TYPE_P (r))
|
||||
{
|
||||
elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
|
||||
jump_target, 1);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
else if (*non_constant_p)
|
||||
return call;
|
||||
}
|
||||
else
|
||||
return throw_exception (loc, ctx,
|
||||
N_("not a complete class type"),
|
||||
r, jump_target);
|
||||
return get_vector_of_info_elts (elts);
|
||||
}
|
||||
|
||||
/* Implement std::meta::nonstatic_data_members_of.
|
||||
Returns: A vector containing each element e of members_of(type, ctx) such
|
||||
that is_nonstatic_data_member(e) is true, preserving their order.
|
||||
Throws: meta::exception unless dealias(type) represents a class type that
|
||||
is complete from some point in the evaluation context. */
|
||||
|
||||
static tree
|
||||
eval_nonstatic_data_members_of (location_t loc, const constexpr_ctx *ctx,
|
||||
tree r, tree actx, tree call,
|
||||
bool *non_constant_p, tree *jump_target)
|
||||
{
|
||||
if (TYPE_P (r) && typedef_variant_p (r))
|
||||
r = strip_typedefs (r);
|
||||
vec<constructor_elt, va_gc> *elts = nullptr;
|
||||
if (CLASS_TYPE_P (r) && COMPLETE_TYPE_P (r))
|
||||
{
|
||||
elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
|
||||
jump_target, 2);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
else if (*non_constant_p)
|
||||
return call;
|
||||
}
|
||||
else
|
||||
return throw_exception (loc, ctx,
|
||||
N_("not a complete class type"),
|
||||
r, jump_target);
|
||||
return get_vector_of_info_elts (elts);
|
||||
}
|
||||
|
||||
/* Implement std::meta::has_inaccessible_nonstatic_data_members.
|
||||
Returns: true if is_accessible(R, ctx) is false for any R in
|
||||
nonstatic_data_members_of(r, access_context::unchecked()).
|
||||
Otherwise, false.
|
||||
Throws: meta::exception unless
|
||||
-- nonstatic_data_members_of(r, access_context::unchecked()) is a constant
|
||||
subexpression and
|
||||
-- r does not represent a closure type. */
|
||||
|
||||
static tree
|
||||
eval_has_inaccessible_nonstatic_data_members (location_t loc,
|
||||
const constexpr_ctx *ctx,
|
||||
tree r, tree actx, tree call,
|
||||
bool *non_constant_p,
|
||||
tree *jump_target)
|
||||
{
|
||||
if (TYPE_P (r) && typedef_variant_p (r))
|
||||
r = strip_typedefs (r);
|
||||
vec<constructor_elt, va_gc> *elts = nullptr;
|
||||
if (CLASS_TYPE_P (r) && COMPLETE_TYPE_P (r))
|
||||
{
|
||||
if (LAMBDA_TYPE_P (r))
|
||||
return throw_exception (loc, ctx, N_("closure type"), r,
|
||||
jump_target);
|
||||
elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
|
||||
jump_target, 3);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
else if (*non_constant_p)
|
||||
return call;
|
||||
}
|
||||
else
|
||||
return throw_exception (loc, ctx,
|
||||
N_("not a complete class type"),
|
||||
r, jump_target);
|
||||
if (elts == nullptr)
|
||||
return boolean_false_node;
|
||||
else
|
||||
return boolean_true_node;
|
||||
}
|
||||
|
||||
/* Expand a call to a metafunction FUN. CALL is the CALL_EXPR.
|
||||
JUMP_TARGET is set if we are throwing std::meta::exception. */
|
||||
|
||||
@@ -6600,6 +7009,21 @@ process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
|
||||
return eval_has_thread_storage_duration (h, kind);
|
||||
if (!strcmp (ident, "automatic_storage_duration"))
|
||||
return eval_has_automatic_storage_duration (h, kind);
|
||||
if (!strcmp (ident, "inaccessible_nonstatic_data_members"))
|
||||
{
|
||||
tree actx = get_nth_callarg (call, 1);
|
||||
actx = cxx_eval_constant_expression (ctx, actx, vc_prvalue,
|
||||
non_constant_p, overflow_p,
|
||||
jump_target);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
if (*non_constant_p)
|
||||
return call;
|
||||
return eval_has_inaccessible_nonstatic_data_members (loc, ctx, h,
|
||||
actx, call,
|
||||
non_constant_p,
|
||||
jump_target);
|
||||
}
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
@@ -6819,6 +7243,28 @@ process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
|
||||
return call;
|
||||
return eval_define_aggregate (loc, ctx, h, hvec, call, non_constant_p);
|
||||
}
|
||||
if (id_equal (name, "members_of")
|
||||
|| id_equal (name, "static_data_members_of")
|
||||
|| id_equal (name, "nonstatic_data_members_of"))
|
||||
{
|
||||
tree actx = get_nth_callarg (call, 1);
|
||||
actx = cxx_eval_constant_expression (ctx, actx, vc_prvalue,
|
||||
non_constant_p, overflow_p,
|
||||
jump_target);
|
||||
if (*jump_target)
|
||||
return NULL_TREE;
|
||||
if (*non_constant_p)
|
||||
return call;
|
||||
if (id_equal (name, "members_of"))
|
||||
return eval_members_of (loc, ctx, h, actx, call, non_constant_p,
|
||||
jump_target);
|
||||
else if (id_equal (name, "static_data_members_of"))
|
||||
return eval_static_data_members_of (loc, ctx, h, actx, call,
|
||||
non_constant_p, jump_target);
|
||||
else if (id_equal (name, "nonstatic_data_members_of"))
|
||||
return eval_nonstatic_data_members_of (loc, ctx, h, actx, call,
|
||||
non_constant_p, jump_target);
|
||||
}
|
||||
|
||||
not_found:
|
||||
sorry ("%qE", name);
|
||||
|
||||
459
gcc/testsuite/g++.dg/reflect/members_of1.C
Normal file
459
gcc/testsuite/g++.dg/reflect/members_of1.C
Normal file
@@ -0,0 +1,459 @@
|
||||
// { dg-do compile { target c++26 } }
|
||||
// { dg-additional-options "-freflection" }
|
||||
// Test std::meta::{,{,non}static_data_}members_of and
|
||||
// has_inaccessible_nonstatic_data_members.
|
||||
|
||||
#include <meta>
|
||||
#include <ranges>
|
||||
|
||||
using namespace std::meta;
|
||||
using std::views::filter;
|
||||
using std::ranges::to;
|
||||
using std::vector;
|
||||
using std::string_view;
|
||||
|
||||
consteval bool
|
||||
check_special_members (const vector <info> &vec, int cnt, bool dct, bool cct, bool cas, bool mct, bool mas, bool dt)
|
||||
{
|
||||
if ((vec | filter (is_special_member_function) | filter (is_defaulted) | to <vector> ()).size () != cnt)
|
||||
throw 1;
|
||||
if ((vec | filter (is_default_constructor) | to <vector> ()).size () != dct)
|
||||
throw 2;
|
||||
if ((vec | filter (is_copy_constructor) | to <vector> ()).size () != cct)
|
||||
throw 3;
|
||||
if ((vec | filter (is_copy_assignment) | to <vector> ()).size () != cas)
|
||||
throw 4;
|
||||
if ((vec | filter (is_move_constructor) | to <vector> ()).size () != mct)
|
||||
throw 5;
|
||||
if ((vec | filter (is_move_assignment) | to <vector> ()).size () != mas)
|
||||
throw 6;
|
||||
if ((vec | filter (is_destructor) | to <vector> ()).size () != dt)
|
||||
throw 7;
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace N1 {
|
||||
struct A {
|
||||
int a;
|
||||
static int b;
|
||||
enum E { E0 };
|
||||
using c = int;
|
||||
typedef long d;
|
||||
consteval {
|
||||
}
|
||||
};
|
||||
int A::b = 24;
|
||||
consteval {
|
||||
}
|
||||
}
|
||||
namespace N2 {
|
||||
struct B {};
|
||||
struct C { int : 5; };
|
||||
struct D { D (int = 42); int d; };
|
||||
struct E { E (int); int e; };
|
||||
struct F { int f; F (const F &); };
|
||||
struct G { G &operator = (const G &); int g; };
|
||||
struct H { int h; H (H &&); };
|
||||
struct I { I &operator = (I &&); int i; };
|
||||
struct J { ~J (); };
|
||||
struct K {
|
||||
int a;
|
||||
static int b;
|
||||
enum E { E0 };
|
||||
using c = int;
|
||||
typedef long d;
|
||||
template <typename T>
|
||||
struct A {};
|
||||
template <typename T>
|
||||
static consteval bool foo (const T &) { return true; }
|
||||
template <int N>
|
||||
static constexpr int e = N;
|
||||
template <typename T>
|
||||
using f = const T &;
|
||||
void bar () {}
|
||||
auto baz ();
|
||||
int g : 3;
|
||||
long : 2;
|
||||
int : 0;
|
||||
consteval {
|
||||
A <int> z = {};
|
||||
static_assert (e <42> == 42);
|
||||
f <int> w = 42;
|
||||
}
|
||||
protected:
|
||||
int Xa;
|
||||
static int Xb;
|
||||
enum XE { XE0 };
|
||||
using Xc = int;
|
||||
typedef long Xd;
|
||||
template <typename T>
|
||||
struct XA {};
|
||||
template <typename T>
|
||||
static consteval bool Xfoo (const T &) { return true; }
|
||||
template <int N>
|
||||
static constexpr int Xe = N;
|
||||
template <typename T>
|
||||
using Xf = const T &;
|
||||
void Xbar () {}
|
||||
auto Xbaz ();
|
||||
int Xg : 5;
|
||||
long : 4;
|
||||
int : 0;
|
||||
private:
|
||||
int Ya;
|
||||
static int Yb;
|
||||
enum YE { YE0 };
|
||||
using Yc = int;
|
||||
typedef long Yd;
|
||||
template <typename T>
|
||||
struct YA {};
|
||||
template <typename T>
|
||||
static consteval bool Yfoo (const T &) { return true; }
|
||||
template <int N>
|
||||
static constexpr int Ye = N;
|
||||
template <typename T>
|
||||
using Yf = const T &;
|
||||
void Ybar () {}
|
||||
auto Ybaz ();
|
||||
int Yg : 7;
|
||||
long : 6;
|
||||
int : 0;
|
||||
public:
|
||||
static constexpr info rXa = ^^Xa;
|
||||
static constexpr info rXb = ^^Xb;
|
||||
static constexpr info rXE = ^^XE;
|
||||
static constexpr info rXg = ^^Xg;
|
||||
static constexpr info rYa = ^^Ya;
|
||||
static constexpr info rYb = ^^Yb;
|
||||
static constexpr info rYE = ^^YE;
|
||||
static constexpr info rYg = ^^Yg;
|
||||
};
|
||||
namespace W {}
|
||||
namespace X = W;
|
||||
namespace W {}
|
||||
namespace W {}
|
||||
inline namespace Y { int a; }
|
||||
template <typename T>
|
||||
concept Z = requires { true; };
|
||||
}
|
||||
static_assert (N2::K::foo (42) && N2::K::foo (42UL));
|
||||
|
||||
constexpr access_context gctx = access_context::current ();
|
||||
constexpr access_context uctx = access_context::unchecked ();
|
||||
|
||||
static_assert (members_of (^^N1::A, gctx).size () == 11);
|
||||
static_assert (members_of (^^N1::A, gctx)[0] == ^^N1::A::a);
|
||||
static_assert (members_of (^^N1::A, gctx)[1] == ^^N1::A::b);
|
||||
static_assert (members_of (^^N1::A, gctx)[2] == ^^N1::A::E);
|
||||
static_assert (members_of (^^N1::A, gctx)[3] == ^^N1::A::c);
|
||||
static_assert (members_of (^^N1::A, gctx)[4] == ^^N1::A::d);
|
||||
static_assert (check_special_members (members_of (^^N1::A, gctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N1::A, gctx).size () == 1);
|
||||
static_assert (static_data_members_of (^^N1::A, gctx)[0] == ^^N1::A::b);
|
||||
static_assert (nonstatic_data_members_of (^^N1::A, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N1::A, gctx)[0] == ^^N1::A::a);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N1::A, gctx));
|
||||
|
||||
static_assert (members_of (^^N1, gctx).size () == 1);
|
||||
static_assert (members_of (^^N1, gctx)[0] == ^^N1::A);
|
||||
|
||||
static_assert (members_of (^^N2::B, gctx).size () == 6);
|
||||
static_assert (check_special_members (members_of (^^N2::B, gctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::B, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::B, gctx).size () == 0);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::B, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::C, gctx).size () == 7);
|
||||
static_assert (is_bit_field (members_of (^^N2::C, gctx)[0]));
|
||||
static_assert (!has_identifier (members_of (^^N2::C, gctx)[0]));
|
||||
static_assert (bit_size_of (members_of (^^N2::C, gctx)[0]) == 5);
|
||||
static_assert (type_of (members_of (^^N2::C, gctx)[0]) == ^^int);
|
||||
static_assert (check_special_members (members_of (^^N2::C, gctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::C, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::C, gctx).size () == 0);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::C, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::D, gctx).size () == 7);
|
||||
static_assert (is_default_constructor (members_of (^^N2::D, gctx)[0]));
|
||||
static_assert (members_of (^^N2::D, gctx)[1] == ^^N2::D::d);
|
||||
static_assert (check_special_members (members_of (^^N2::D, gctx), 5, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::D, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::D, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::D, gctx)[0] == ^^N2::D::d);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::D, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::E, gctx).size () == 7);
|
||||
static_assert (is_constructor (members_of (^^N2::E, gctx)[0]));
|
||||
static_assert (members_of (^^N2::E, gctx)[1] == ^^N2::E::e);
|
||||
static_assert (check_special_members (members_of (^^N2::E, gctx), 5, false, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::E, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::E, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::E, gctx)[0] == ^^N2::E::e);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::E, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::F, gctx).size () == 4);
|
||||
static_assert (members_of (^^N2::F, gctx)[0] == ^^N2::F::f);
|
||||
static_assert (is_copy_constructor (members_of (^^N2::F, gctx)[1]));
|
||||
static_assert (check_special_members (members_of (^^N2::F, gctx), 2, false, true, true, false, false, true));
|
||||
static_assert (static_data_members_of (^^N2::F, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::F, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::F, gctx)[0] == ^^N2::F::f);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::F, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::G, gctx).size () == 5);
|
||||
static_assert (is_copy_assignment (members_of (^^N2::G, gctx)[0]));
|
||||
static_assert (members_of (^^N2::G, gctx)[1] == ^^N2::G::g);
|
||||
static_assert (check_special_members (members_of (^^N2::G, gctx), 3, true, true, true, false, false, true));
|
||||
static_assert (static_data_members_of (^^N2::G, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::G, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::G, gctx)[0] == ^^N2::G::g);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::G, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::H, gctx).size () == 5);
|
||||
static_assert (members_of (^^N2::H, gctx)[0] == ^^N2::H::h);
|
||||
static_assert (is_move_constructor (members_of (^^N2::H, gctx)[1]));
|
||||
static_assert (check_special_members (members_of (^^N2::H, gctx), 3, false, true, true, true, false, true));
|
||||
static_assert (static_data_members_of (^^N2::H, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::H, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::H, gctx)[0] == ^^N2::H::h);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::H, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::I, gctx).size () == 6);
|
||||
static_assert (is_move_assignment (members_of (^^N2::I, gctx)[0]));
|
||||
static_assert (members_of (^^N2::I, gctx)[1] == ^^N2::I::i);
|
||||
static_assert (check_special_members (members_of (^^N2::I, gctx), 4, true, true, true, false, true, true));
|
||||
static_assert (static_data_members_of (^^N2::I, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::I, gctx).size () == 1);
|
||||
static_assert (nonstatic_data_members_of (^^N2::I, gctx)[0] == ^^N2::I::i);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::I, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::J, gctx).size () == 4);
|
||||
static_assert (is_destructor (members_of (^^N2::J, gctx)[0]));
|
||||
static_assert (check_special_members (members_of (^^N2::J, gctx), 3, true, true, true, false, false, true));
|
||||
static_assert (static_data_members_of (^^N2::J, gctx).size () == 0);
|
||||
static_assert (nonstatic_data_members_of (^^N2::J, gctx).size () == 0);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::J, gctx));
|
||||
|
||||
static_assert (members_of (^^N2::K, gctx).size () == 27);
|
||||
static_assert (members_of (^^N2::K, gctx)[0] == ^^N2::K::a);
|
||||
static_assert (members_of (^^N2::K, gctx)[1] == ^^N2::K::b);
|
||||
static_assert (members_of (^^N2::K, gctx)[2] == ^^N2::K::E);
|
||||
static_assert (members_of (^^N2::K, gctx)[3] == ^^N2::K::c);
|
||||
static_assert (members_of (^^N2::K, gctx)[4] == ^^N2::K::d);
|
||||
static_assert (members_of (^^N2::K, gctx)[5] == ^^N2::K::A);
|
||||
static_assert (members_of (^^N2::K, gctx)[6] == ^^N2::K::foo);
|
||||
static_assert (members_of (^^N2::K, gctx)[7] == ^^N2::K::e);
|
||||
static_assert (members_of (^^N2::K, gctx)[8] == ^^N2::K::f);
|
||||
static_assert (members_of (^^N2::K, gctx)[9] == ^^N2::K::bar);
|
||||
static_assert (members_of (^^N2::K, gctx)[10] == ^^N2::K::g);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, gctx)[11]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, gctx)[11]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, gctx)[11]) == 2);
|
||||
static_assert (type_of (members_of (^^N2::K, gctx)[11]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, gctx)[12]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, gctx)[12]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, gctx)[12]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, gctx)[12]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, gctx)[13] == ^^N2::K::rXa);
|
||||
static_assert (members_of (^^N2::K, gctx)[14] == ^^N2::K::rXb);
|
||||
static_assert (members_of (^^N2::K, gctx)[15] == ^^N2::K::rXE);
|
||||
static_assert (members_of (^^N2::K, gctx)[16] == ^^N2::K::rXg);
|
||||
static_assert (members_of (^^N2::K, gctx)[17] == ^^N2::K::rYa);
|
||||
static_assert (members_of (^^N2::K, gctx)[18] == ^^N2::K::rYb);
|
||||
static_assert (members_of (^^N2::K, gctx)[19] == ^^N2::K::rYE);
|
||||
static_assert (members_of (^^N2::K, gctx)[20] == ^^N2::K::rYg);
|
||||
static_assert (check_special_members (members_of (^^N2::K, gctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::K, gctx).size () == 9);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[0] == ^^N2::K::b);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[1] == ^^N2::K::rXa);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[2] == ^^N2::K::rXb);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[3] == ^^N2::K::rXE);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[4] == ^^N2::K::rXg);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[5] == ^^N2::K::rYa);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[6] == ^^N2::K::rYb);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[7] == ^^N2::K::rYE);
|
||||
static_assert (static_data_members_of (^^N2::K, gctx)[8] == ^^N2::K::rYg);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, gctx).size () == 2);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, gctx)[0] == ^^N2::K::a);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, gctx)[1] == ^^N2::K::g);
|
||||
static_assert (has_inaccessible_nonstatic_data_members (^^N2::K, gctx));
|
||||
static_assert (members_of (^^N2::K, uctx).size () == 53);
|
||||
static_assert (members_of (^^N2::K, uctx)[0] == ^^N2::K::a);
|
||||
static_assert (members_of (^^N2::K, uctx)[1] == ^^N2::K::b);
|
||||
static_assert (members_of (^^N2::K, uctx)[2] == ^^N2::K::E);
|
||||
static_assert (members_of (^^N2::K, uctx)[3] == ^^N2::K::c);
|
||||
static_assert (members_of (^^N2::K, uctx)[4] == ^^N2::K::d);
|
||||
static_assert (members_of (^^N2::K, uctx)[5] == ^^N2::K::A);
|
||||
static_assert (members_of (^^N2::K, uctx)[6] == ^^N2::K::foo);
|
||||
static_assert (members_of (^^N2::K, uctx)[7] == ^^N2::K::e);
|
||||
static_assert (members_of (^^N2::K, uctx)[8] == ^^N2::K::f);
|
||||
static_assert (members_of (^^N2::K, uctx)[9] == ^^N2::K::bar);
|
||||
static_assert (members_of (^^N2::K, uctx)[10] == ^^N2::K::g);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[11]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[11]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[11]) == 2);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[11]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[12]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[12]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[12]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[12]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, uctx)[13] == N2::K::rXa);
|
||||
static_assert (members_of (^^N2::K, uctx)[14] == N2::K::rXb);
|
||||
static_assert (members_of (^^N2::K, uctx)[15] == N2::K::rXE);
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[16]) == string_view ("Xc"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[17]) == string_view ("Xd"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[18]) == string_view ("XA"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[19]) == string_view ("Xfoo"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[20]) == string_view ("Xe"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[21]) == string_view ("Xf"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[22]) == string_view ("Xbar"));
|
||||
static_assert (members_of (^^N2::K, uctx)[23] == N2::K::rXg);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[24]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[24]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[24]) == 4);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[24]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[25]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[25]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[25]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[25]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, uctx)[26] == N2::K::rYa);
|
||||
static_assert (members_of (^^N2::K, uctx)[27] == N2::K::rYb);
|
||||
static_assert (members_of (^^N2::K, uctx)[28] == N2::K::rYE);
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[29]) == string_view ("Yc"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[30]) == string_view ("Yd"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[31]) == string_view ("YA"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[32]) == string_view ("Yfoo"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[33]) == string_view ("Ye"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[34]) == string_view ("Yf"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, uctx)[35]) == string_view ("Ybar"));
|
||||
static_assert (members_of (^^N2::K, uctx)[36] == N2::K::rYg);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[37]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[37]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[37]) == 6);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[37]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, uctx)[38]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, uctx)[38]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, uctx)[38]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, uctx)[38]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, uctx)[39] == ^^N2::K::rXa);
|
||||
static_assert (members_of (^^N2::K, uctx)[40] == ^^N2::K::rXb);
|
||||
static_assert (members_of (^^N2::K, uctx)[41] == ^^N2::K::rXE);
|
||||
static_assert (members_of (^^N2::K, uctx)[42] == ^^N2::K::rXg);
|
||||
static_assert (members_of (^^N2::K, uctx)[43] == ^^N2::K::rYa);
|
||||
static_assert (members_of (^^N2::K, uctx)[44] == ^^N2::K::rYb);
|
||||
static_assert (members_of (^^N2::K, uctx)[45] == ^^N2::K::rYE);
|
||||
static_assert (members_of (^^N2::K, uctx)[46] == ^^N2::K::rYg);
|
||||
static_assert (check_special_members (members_of (^^N2::K, uctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::K, uctx).size () == 11);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[0] == ^^N2::K::b);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[1] == N2::K::rXb);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[2] == N2::K::rYb);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[3] == ^^N2::K::rXa);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[4] == ^^N2::K::rXb);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[5] == ^^N2::K::rXE);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[6] == ^^N2::K::rXg);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[7] == ^^N2::K::rYa);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[8] == ^^N2::K::rYb);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[9] == ^^N2::K::rYE);
|
||||
static_assert (static_data_members_of (^^N2::K, uctx)[10] == ^^N2::K::rYg);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx).size () == 6);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[0] == ^^N2::K::a);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[1] == ^^N2::K::g);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[2] == N2::K::rXa);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[3] == N2::K::rXg);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[4] == N2::K::rYa);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, uctx)[5] == N2::K::rYg);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::K, uctx));
|
||||
|
||||
static_assert (members_of (^^N2, gctx).size () == 14);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_type) | filter (is_class_type) | to <vector> ()).size () == 10);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_namespace) | to <vector> ()).size () == 3);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_namespace_alias) | to <vector> ()).size () == 1);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_concept) | to <vector> ()).size () == 1);
|
||||
|
||||
namespace N2 {
|
||||
struct L : public K {
|
||||
static constexpr auto ctx = access_context::current ();
|
||||
};
|
||||
static constexpr auto ctx = L::ctx.via (^^L);
|
||||
}
|
||||
|
||||
static_assert (members_of (^^N2::K, N2::ctx).size () == 40);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[0] == ^^N2::K::a);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[1] == ^^N2::K::b);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[2] == ^^N2::K::E);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[3] == ^^N2::K::c);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[4] == ^^N2::K::d);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[5] == ^^N2::K::A);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[6] == ^^N2::K::foo);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[7] == ^^N2::K::e);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[8] == ^^N2::K::f);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[9] == ^^N2::K::bar);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[10] == ^^N2::K::g);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, N2::ctx)[11]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, N2::ctx)[11]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, N2::ctx)[11]) == 2);
|
||||
static_assert (type_of (members_of (^^N2::K, N2::ctx)[11]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, N2::ctx)[12]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, N2::ctx)[12]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, N2::ctx)[12]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, N2::ctx)[12]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[13] == N2::K::rXa);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[14] == N2::K::rXb);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[15] == N2::K::rXE);
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[16]) == string_view ("Xc"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[17]) == string_view ("Xd"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[18]) == string_view ("XA"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[19]) == string_view ("Xfoo"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[20]) == string_view ("Xe"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[21]) == string_view ("Xf"));
|
||||
static_assert (identifier_of (members_of (^^N2::K, N2::ctx)[22]) == string_view ("Xbar"));
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[23] == N2::K::rXg);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, N2::ctx)[24]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, N2::ctx)[24]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, N2::ctx)[24]) == 4);
|
||||
static_assert (type_of (members_of (^^N2::K, N2::ctx)[24]) == ^^long);
|
||||
static_assert (is_bit_field (members_of (^^N2::K, N2::ctx)[25]));
|
||||
static_assert (!has_identifier (members_of (^^N2::K, N2::ctx)[25]));
|
||||
static_assert (bit_size_of (members_of (^^N2::K, N2::ctx)[25]) == 0);
|
||||
static_assert (type_of (members_of (^^N2::K, N2::ctx)[25]) == ^^int);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[26] == ^^N2::K::rXa);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[27] == ^^N2::K::rXb);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[28] == ^^N2::K::rXE);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[29] == ^^N2::K::rXg);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[30] == ^^N2::K::rYa);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[31] == ^^N2::K::rYb);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[32] == ^^N2::K::rYE);
|
||||
static_assert (members_of (^^N2::K, N2::ctx)[33] == ^^N2::K::rYg);
|
||||
static_assert (check_special_members (members_of (^^N2::K, N2::ctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx).size () == 10);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[0] == ^^N2::K::b);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[1] == N2::K::rXb);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[2] == ^^N2::K::rXa);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[3] == ^^N2::K::rXb);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[4] == ^^N2::K::rXE);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[5] == ^^N2::K::rXg);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[6] == ^^N2::K::rYa);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[7] == ^^N2::K::rYb);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[8] == ^^N2::K::rYE);
|
||||
static_assert (static_data_members_of (^^N2::K, N2::ctx)[9] == ^^N2::K::rYg);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, N2::ctx).size () == 4);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, N2::ctx)[0] == ^^N2::K::a);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, N2::ctx)[1] == ^^N2::K::g);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, N2::ctx)[2] == N2::K::rXa);
|
||||
static_assert (nonstatic_data_members_of (^^N2::K, N2::ctx)[3] == N2::K::rXg);
|
||||
static_assert (has_inaccessible_nonstatic_data_members (^^N2::K, N2::ctx));
|
||||
static_assert (members_of (^^N2::L, gctx).size () == 7);
|
||||
static_assert (members_of (^^N2::L, gctx)[0] == ^^N2::L::ctx);
|
||||
static_assert (check_special_members (members_of (^^N2::L, gctx), 6, true, true, true, true, true, true));
|
||||
static_assert (static_data_members_of (^^N2::L, gctx).size () == 1);
|
||||
static_assert (static_data_members_of (^^N2::L, gctx)[0] == ^^N2::L::ctx);
|
||||
static_assert (nonstatic_data_members_of (^^N2::L, gctx).size () == 0);
|
||||
static_assert (!has_inaccessible_nonstatic_data_members (^^N2::L, gctx));
|
||||
|
||||
static_assert (members_of (^^N2, gctx).size () == 16);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_type) | filter (is_class_type) | to <vector> ()).size () == 11);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_namespace) | to <vector> ()).size () == 3);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_namespace_alias) | to <vector> ()).size () == 1);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_concept) | to <vector> ()).size () == 1);
|
||||
static_assert ((members_of (^^N2, gctx) | filter (is_variable) | to <vector> ()).size () == 1);
|
||||
@@ -296,8 +296,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// [meta.reflection.access.queries], member accessibility queries
|
||||
consteval bool is_accessible(info, access_context);
|
||||
consteval bool has_inaccessible_nonstatic_data_members(info,
|
||||
access_context);
|
||||
|
||||
// [meta.reflection.member.queries], reflection member queries
|
||||
consteval vector<info> members_of(info, access_context);
|
||||
consteval vector<info> static_data_members_of(info, access_context);
|
||||
consteval vector<info> nonstatic_data_members_of(info, access_context);
|
||||
consteval vector<info> enumerators_of(info);
|
||||
|
||||
// [meta.reflection.layout], reflection layout queries
|
||||
|
||||
Reference in New Issue
Block a user