Date: Mon, 31 Jan 2022 20:10:45 +0200
Daveed Vandevoorde wrote:
> > In Boost.Describe, I support a "modifier" mod_inherited, which
> > includes the inherited members in the "members_of" list. I don't
> > currently support it for the base classes, but I could. So when you
> > have
> >
> > struct B {};
> > struct D1: B {};
> > struct D2: B {};
> > struct C: D1, D2 {};
> >
> > and you say describe_bases<C, mod_any_access | mod_inherited>, you
> > would get a list of base class descriptors [desc(D1), desc(B), desc(D2),
> desc(B)].
>
> Okay, so like the alternative API I described where you also get indirect bases.
> Do the descriptors maintain information about the derivation path?
Not at the moment.
In a prototype of mine (before the official Describe) I had base descriptors
have something like
struct Desc
{
static constexpr auto pointer = [](C* p) -> B*
{
return (B*)(D1*)p;
};
};
with the derivation path implicitly encoded in the lambda. But in Describe
I don't provide `pointer` for base descriptors at all, having, err, postponed it.
A similar issue actually exists for inherited members. If you have
struct B { int m; };
struct D1: B {};
struct D2: B {};
struct C: D1, D2 {};
and you get the all members list for C, including inherited, that would
be two descriptors for B::m. At the moment in Describe both of these have
struct Desc
{
static constexpr auto pointer = &B::m;
};
but that's wrong; they should actually have two different member pointers
of type `int D::*`, one pointing to the first `m`, other to the second.
I don't think this is achievable without compiler support, though.
Both &C::D1::m and &C::D2::m give &B::m.
> IIRC, in the context of P1240 someone once suggested that we should be able
> to write something like:
>
> D *p;
> auto *pb = p->[:bases_of(^D)[0]:];
>
> (assuming D has a base class). That’s similar to your suggestion of a more
> general pointer-to-member value concept, but it has the advantage of
> generalizing to bit fields as well.
That would indeed be a way to do it.
> > In Boost.Describe, I support a "modifier" mod_inherited, which
> > includes the inherited members in the "members_of" list. I don't
> > currently support it for the base classes, but I could. So when you
> > have
> >
> > struct B {};
> > struct D1: B {};
> > struct D2: B {};
> > struct C: D1, D2 {};
> >
> > and you say describe_bases<C, mod_any_access | mod_inherited>, you
> > would get a list of base class descriptors [desc(D1), desc(B), desc(D2),
> desc(B)].
>
> Okay, so like the alternative API I described where you also get indirect bases.
> Do the descriptors maintain information about the derivation path?
Not at the moment.
In a prototype of mine (before the official Describe) I had base descriptors
have something like
struct Desc
{
static constexpr auto pointer = [](C* p) -> B*
{
return (B*)(D1*)p;
};
};
with the derivation path implicitly encoded in the lambda. But in Describe
I don't provide `pointer` for base descriptors at all, having, err, postponed it.
A similar issue actually exists for inherited members. If you have
struct B { int m; };
struct D1: B {};
struct D2: B {};
struct C: D1, D2 {};
and you get the all members list for C, including inherited, that would
be two descriptors for B::m. At the moment in Describe both of these have
struct Desc
{
static constexpr auto pointer = &B::m;
};
but that's wrong; they should actually have two different member pointers
of type `int D::*`, one pointing to the first `m`, other to the second.
I don't think this is achievable without compiler support, though.
Both &C::D1::m and &C::D2::m give &B::m.
> IIRC, in the context of P1240 someone once suggested that we should be able
> to write something like:
>
> D *p;
> auto *pb = p->[:bases_of(^D)[0]:];
>
> (assuming D has a base class). That’s similar to your suggestion of a more
> general pointer-to-member value concept, but it has the advantage of
> generalizing to bit fields as well.
That would indeed be a way to do it.
Received on 2022-01-31 18:10:47