Concept Subspace :: sus :: mem :: TriviallyRelocatable

template <class... T>
concept TriviallyRelocatable
requires
(... && __private::TriviallyRelocatable_impl<T>)

Tests if a variable of type T can be relocated with ptr::copy.

IMPORTANT: If a class satisfies this trait, only sus::mem::data_size_of<T>() bytes should be copied when relocating the type, or Undefined Behaviour can result, due to the possibility of overwriting data stored in the tail padding bytes of T. See the docs on data_size_of for more.

Volatile types are excluded, as they can not be safely memcpy'd byte-by-byte without introducing tearing. References are treated like pointers, and are always trivially relocatable, as reference data members are relocatable in the same way pointers are.

Marking a type as trivially relocatable

Use one of the provided macros inside a class to mark it as conditionally or unconditionally trivially relocatable. They are unsafe because there are no compiler checks that the claim is actually true, though macros are provided to make this easier. The sus_class_trivially_relocatable and sus_class_trivially_relocatable_if_types macros verify that all the types given to it are also trivially relocatable. As long as every field type of the class is given as a parameter, and each field type correctly advertises its trivial relocatability, it will ensure correctness.

This concept also honors the [[clang::trivial_abi]] Clang attribute, as types annotated with the attribute are now considered trivially relocatable in https://reviews.llvm.org/D114732. However, when marking a class with this attribute it is highly recommended to use the sus_class_trivially_relocatable macro as well to help verify correctness and gain compiler independence.

Macro Style
sus_class_trivially_relocatable asserts all param types are trivially relocatable
sus_class_trivially_relocatable_if_types is conditionally trivially relocatable if all param types are
sus_class_trivially_relocatable_if is conditionally trivially relocatable if the condition is true
sus_class_trivially_relocatable_unchecked is trivially relocatable without any condition or assertion

Implementation notes

The concept tests against std::remove_all_extents_t<T> so that the same answer is returned for arrays of T, such as for T or T[] or T[][][].

While the standard expects types to be std::is_trivially_copyble in order to copy by memcpy, Clang also allows trivial relocation of move-only types with non-trivial move operations and destructors through [[clang::trivial_abi]] while also noting that attributes are not part of and do not modify the type or how the compiler itself treats it outside of argument passing. As such, we consider trivally moveable and destructible types as automatically trivially relocatable, and allow other types to opt in conditionally with the macros and without [[clang::trivial_abi]].