iceoryx2_bb_elementary_traits/zero_copy_send.rs
1// Copyright (c) 2025 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13use crate::iceoryx_send::*;
14use crate::type_name::TypeName;
15
16/// Marks types that can be sent to another process in a zero-copy manner, i.e. the types can be
17/// safely used from within different process address spaces and can be uniquely identified by their
18/// [`ZeroCopySend::type_name()`] in an inter-process communication context.
19///
20/// # Safety
21///
22/// The user must ensure that
23/// * the types are self-contained, meaning they shall not contain pointers, references, indices
24/// or handles to resources that are not part of the type.
25/// Examples:
26/// * file descriptors point to resources that can be different in another process
27/// * a list with pointers into the heap
28/// * the types do not have references or pointer members; they shall not use pointers to manage
29/// their internal structure.
30/// Example:
31/// * a list must be implemented using indices to structure itself
32/// * the types must have a uniform memory representation, meaning they are annotated with
33/// `#[repr(C)]`.
34///
35pub unsafe trait ZeroCopySend: TypeName {
36 /// The unique identifier of the type. It shall be used to identify a specific type across
37 /// processes and languages.
38 ///
39 /// # Safety
40 ///
41 /// * The user must guarantee that all types, also definitions in different languages, have
42 /// the same memory layout.
43 unsafe fn type_name() -> &'static str {
44 core::any::type_name::<Self>()
45 }
46
47 #[doc(hidden)]
48 /// used as dummy call in the derive macro to ensure at compile-time that all fields of
49 /// a struct implement ZeroCopySend
50 fn __is_zero_copy_send(&self) {}
51}
52
53unsafe impl ZeroCopySend for usize {}
54unsafe impl ZeroCopySend for u8 {}
55unsafe impl ZeroCopySend for u16 {}
56unsafe impl ZeroCopySend for u32 {}
57unsafe impl ZeroCopySend for u64 {}
58unsafe impl ZeroCopySend for u128 {}
59
60unsafe impl ZeroCopySend for isize {}
61unsafe impl ZeroCopySend for i8 {}
62unsafe impl ZeroCopySend for i16 {}
63unsafe impl ZeroCopySend for i32 {}
64unsafe impl ZeroCopySend for i64 {}
65unsafe impl ZeroCopySend for i128 {}
66
67unsafe impl ZeroCopySend for f32 {}
68unsafe impl ZeroCopySend for f64 {}
69
70unsafe impl ZeroCopySend for char {}
71unsafe impl ZeroCopySend for bool {}
72
73unsafe impl ZeroCopySend for () {}
74
75unsafe impl<T: ZeroCopySend> ZeroCopySend for [T] {}
76unsafe impl<T: ZeroCopySend, const N: usize> ZeroCopySend for [T; N] {}
77unsafe impl<T: ZeroCopySend> ZeroCopySend for core::mem::MaybeUninit<T> {}
78unsafe impl<T: ZeroCopySend> ZeroCopySend for core::marker::PhantomData<T> {}
79
80// Note: `ZeroCopySend` cannot be implemented for tuples because `#[repr(C)]` can only be applied
81// to structs, enums, and unions.
82
83unsafe impl<T: ZeroCopySend> __InternalNoTouchyFishy for T {}
84unsafe impl<T: ZeroCopySend> __InternalNoTouchyFishy for [T] {}
85impl<T: ZeroCopySend> IceoryxSend for T {}
86impl<T: ZeroCopySend> IceoryxSend for [T] {}
87
88unsafe impl<T: ZeroCopySend + ?Sized> TypeName for T {
89 unsafe fn type_name() -> &'static str {
90 unsafe { <T as ZeroCopySend>::type_name() }
91 }
92}