2

I want to accept classes which are "trivially copyable", in the sense that if I mem-copy the byte representation of one variable of the type into another, it will be usable, and nothing will have been broken in any way.

Looking at std::is_trivially_copyable, I see the requirements are:

Trivially copyable classes, i.e. classes satisfying following requirements:

  • At least one copy constructor, move constructor, copy assignment operator, or move assignment operator is eligible
  • Every eligible copy constructor (if any) is trivial
  • Every eligible move constructor (if any) is trivial
  • Every eligible copy assignment operator (if any) is trivial
  • Every eligible move assignment operator (if any) is trivial
  • Has a trivial non-deleted destructor

First and last requirement - check. But the other requirements are super-strong and not what I want! I'd be willing to "compromise" on having a trivial copy ctor as a requirement, and that's already quite different than what I really want.

So, what type trait can I use from the standard library, or write myself, to express the constraint I'm interested in?

I'm writing C++11 right now, so if your answer requires a later standard - write it, but mention that fact explicitly.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 2
    Not sure that I follow, here. If a byte-wise memory copy doesn't break the object, then all the copy and move c'tors and assignments would *have* to be trivial. – Adrian Mole Apr 21 '22 at 12:11
  • What does your non-trivial copy/move constructor/assignment? – Jarod42 Apr 21 '22 at 12:30
  • @Jarod42: Essentially, assignment from pair to pair. I'm using a slightly adaptation of EASTL's pair class for something. – einpoklum Apr 21 '22 at 13:59
  • @AdrianMole: Trivial for you and me, not officially-trivial , i.e. defaulted/implicit. – einpoklum Apr 21 '22 at 13:59
  • 1
    @einpoklum: those seems not copy constructors, as type differs. – Jarod42 Apr 21 '22 at 14:04
  • @Jarod42: But the requirements include assignment operators :-( – einpoklum Apr 21 '22 at 14:05
  • 1
    @einpoklum: Can you provide problematic class? I try to mimic your problematic class [Demo](https://godbolt.org/z/bWbWG8814) but it is trivially copyable... – Jarod42 Apr 21 '22 at 14:12
  • @Jarod42: [EASTL pair](https://github.com/electronicarts/EASTL/blob/master/include/EASTL/utility.h#L370) should do it, I think. – einpoklum Apr 21 '22 at 18:45
  • Fix should be `pair& operator=(const pair&) noexcept(/*..*/) = default;`. There is no ways to know that implementation matches the trivial one. – Jarod42 Apr 21 '22 at 18:50
  • @Jarod42: Yes, I realize there is no way to know that. I just want to say that plain copying is good enough, not that there is no other possible way to construct/assign. – einpoklum Apr 21 '22 at 18:56

1 Answers1

3
  • At least one copy constructor, move constructor, copy assignment operator, or move assignment operator is eligible
  • Has a trivial non-deleted destructor

First and last requirement - check. But the other requirements are super-strong

So, what type trait can I use from the standard library, or write myself, to express the constraint I'm interested in?

You could use (is_copy_constructible || is_move_constructible || is_assignable) && std::is_trivially_destructible.

I'd be willing to "compromise" on having a trivial ... copy ctor as a requirement

You could use std::is_trivially_copy_constructible.

if I mem-copy the byte representation of one variable of the type into another, it will be usable, and nothing will have been broken in any way.

However, those requirements won't be sufficient for this. You need the "super-strong" requirements for this. This is what std::is_trivially_copyable is for.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Removed the "trivial = defaulted" parentheses from the question. – einpoklum Apr 21 '22 at 18:46
  • I don't think your bottom-line is correct. I can manually define an additional constructor or copy-assignment operator, which does not change anything else about the class, and break `is_trivially_copyable` - meaning it is _not_ what I need. – einpoklum Apr 21 '22 at 19:26
  • @einpoklum Classes that have user defined a copy-assignment operator may have defined it in a way that behaves differently from trivial copy assignment. Hence, such classes cannot be assumed to be usable after mem-copy of byte representation. – eerorika Apr 21 '22 at 20:27