Concept Subspace :: sus :: mem :: TriviallyRelocatable
template <class... T>concept TriviallyRelocatable
(... && __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]]
.