https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124121

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #4)
> Not sure what inplace_vector is for ...

std::vector that uses internal storage, not heap allocations.

So std::inplace_vector<T, N> stores between 0 and N objects of type T. It
contains

union {
  T _M_elems[N];
};

and we do not start the lifetime of the entire array, because we want it to
contain zero objects initially. The start_lifetime_as_array call creates the
array but not its subobjects, so we just have an empty shell that we can then
construct individual T objects into as the inplace_vector grows.

Maybe we can do this instead:

      constexpr void
      _M_init()
      {
        // TODO: use new(_M_elems) _Tp[_Nm]() once PR121068 is fixed
        if constexpr (is_trivial_v<_Tp>)
          for (size_t __i = 0; __i < _Nm; ++__i)
            _M_elems[__i] = _Tp();
        else if !consteval
          {
#if __glibcxx_start_lifetime_as
            std::start_lifetime_as_array<_Tp>(data(), _Nm);
#endif
          }
        else
          {
            // only trivial types are supported at compile time
            __builtin_unreachable();
          }
      }

This avoids the start_lifetime_as for trivial types.

Reply via email to