C++ Logo

sg7

Advanced search

Re: [SG7] string. vector vs string_view, span in reflection API

From: David Rector <davrec_at_[hidden]>
Date: Fri, 9 Apr 2021 20:20:57 -0400
> On Apr 9, 2021, at 8:35 AM, Matus Chochlik via SG7 <sg7_at_[hidden]> wrote:
>
> Hi Peter
>
> On Fri, Apr 9, 2021 at 2:26 PM Peter Dimov via SG7 <sg7_at_[hidden] <mailto:sg7_at_[hidden]>> wrote:
> Matus Chochlik wrote:
> > Hi,
> >
> > IIUC the current plan is to use `string` and `vector<meta::info>` in the
> > reflection API (both of which require consteval dynamic allocation). Is this
> > correct and if so, was there some reason for not using `string_view` and
> > `span<meta::info>` instead? The returned metadata is always static, so
> > mutable containers look like overkill.
>
> I would go even further and argue in favor of returning char const*. You
> can construct a string_view from that but not vice versa.
>
> vector<info> can't be replaced with span<info> though because it's
> often built dynamically (e.g. if the contents are filtered with a predicate.)
>
>
> This still happens at compile-time inside of the compiler, so it could allocate the filtered range of metaobjects by using some internal mechanism, that is not exposing generic "dynamic" allocation in consteval.
> Just saying, in case solving dynamic allocation in constexpr/consteval contexts is something blocking us moving forward with reflection.
> Or am I missing something?
>

To go further, why should the API include something that requires these allocations in the first place, since they don’t seem particularly efficient (or at least won’t scale well) even if the compiler can handle them internally?

That is, should we really be encouraging users to use things like `meta::members_of(reflection, predicate)`, which always necessitates a new allocation?

It would be more efficient, and permit more natural programming, to only expose `meta::members_of(reflection)` (i.e. no predicate argument) and instead encourage the user to condition actions on those members via control flow statements during iteration over the compiler’s already-allocated container of members.

This would require expanding the contexts in which `consteval {}` metaprograms are permitted, and introducing corresponding fragment kinds to permit injection of entities in those contexts.

That is the precisely the argument of this paper: https://isocpp.org/files/papers/P2353R0.html <https://isocpp.org/files/papers/P2353R0.html>, a cleaned up version of the paper “The syntactic gap” I shared on here awhile ago, which should appear in the next mailing.

Matus here is how I would write your `unpack_range`, using P2353 features:

```
template <std::experimental::meta::info MO>
consteval auto unpack_range() {
    return unpacked_range<
      consteval {
        template for (auto mem : meta::members_of(MO))
          if (meta::is_constructor(mem))
            << ^<frag::targ>{ mem }; //a template argument fragment
      }
>{};
```

This requires no allocations and is simple to read and write.

Something to consider moving forward, given the emphasis on efficiency.

Received on 2021-04-09 19:21:02