I'd like it to be trivial, not just trivially copyable.

https://godbolt.org/z/GGzEYjv6q

That said, std::start_lifetime_as and std::start_lifetime_as_array, which are the relevant two functions here, only require trivally copyable, so maybe that's enough.

G

On Thu, Dec 7, 2023 at 11:00 AM Lénárd Szolnoki <cpp@lenardszolnoki.com> wrote:
On Thu, 2023-12-07 at 10:09 +0000, Gašper Ažman wrote:
> The implementation is a reasonable start but unaligned<trivial> needs
> to itself be trivial (to allow composition of structs containing
> unaligned members inside other unaligned<> ), so it gets just a tad
> more interesting.

It is trivial, isn't it?

https://godbolt.org/z/ddT6Mb65n

Specifically it needs to be trivially copyable.

>
> On Thu, Dec 7, 2023, 08:01 Lénárd Szolnoki via Std-Proposals
> <std-proposals@lists.isocpp.org> wrote:
> > On Wed, 2023-12-06 at 17:01 +0000, Frederick Virchanza Gotham via
> > Std-
> > Proposals wrote:
> > > On Wed, Dec 6, 2023 at 4:52 PM Gašper Ažman wrote:
> > > >
> > > > ++ for unaligned<trivial>
> > >
> > >
> > > So how would "std::unaligned<Trivial>" work? Would it lack tail
> > > padding? Or would it lack tail padding and also lack padding
> > > between
> > > members?
> >
> > std::unaligned would be applied to the members, not the enclosing
> > class, like so:
> >
> > struct Monkey {
> >    std::unaligned<long> l;
> >    char ch;
> > };
> > static_assert(sizeof(Monkey) == sizeof(long) + sizeof(char));
> >
> > std::unaligned could be implemented something like this:
> >
> > template <typename T, std::size_t alignment = 1>
> > requires (std::popcount(alignment) == 1)
> > class unaligned {
> >     static_assert(std::is_trivially_copyable_v<T>);
> >
> >     using storage_t = std::array<std::byte, sizeof(T)>;
> >     alignas(alignment) storage_t m_storage;
> >
> >     public:
> >     constexpr unaligned(T t) noexcept
> >     : m_storage(std::bit_cast<storage_t>(t))
> >     {}
> >
> >     constexpr operator T() noexcept {
> >         return std::bit_cast<T>(m_storage);
> >     }
> > };
> >
> > You also identified the problem of taking address of packed members
> > and
> > the potential need for special treatment of them in the language.
> > If
> > implemented like above then you don't need special treatment in the
> > language, you can't take the address and get a `long *` out of an
> > unaligned<long>.
> >
> > >
> > > So if I have a trivial standard-layout struct as follows:
> > >
> > >     struct Monkey {
> > >         long unsigned a;
> > >         char b;
> > >         // padding here?
> > >         long double c;
> > >         char d;
> > >         // padding here?
> > >         float e;
> > >         char f;
> > >         // padding here?
> > >     };
> > >
> > > Then what will std::unaligned<Monkey> do? Will it take out just
> > > the
> > > tail padding, or will it take out the 3 pieces of padding?
> >