zenoh_shm/api/provider/
memory_layout.rs1use std::{fmt::Display, marker::PhantomData, mem, num::NonZeroUsize};
16
17use crate::api::provider::types::{AllocAlignment, ZLayoutError};
18
19#[zenoh_macros::unstable_doc]
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct MemoryLayout {
23 size: NonZeroUsize,
24 alignment: AllocAlignment,
25}
26
27impl From<&MemoryLayout> for MemoryLayout {
28 fn from(other: &MemoryLayout) -> Self {
29 *other
30 }
31}
32
33impl Display for MemoryLayout {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 f.write_fmt(format_args!(
36 "[size={},alignment={}]",
37 self.size, self.alignment
38 ))
39 }
40}
41
42impl MemoryLayout {
43 #[zenoh_macros::unstable_doc]
49 pub fn new<T>(size: T, alignment: AllocAlignment) -> Result<Self, ZLayoutError>
50 where
51 T: TryInto<NonZeroUsize>,
52 {
53 let Ok(size) = size.try_into() else {
54 return Err(ZLayoutError::IncorrectLayoutArgs);
55 };
56
57 match size.get() % alignment.get_alignment_value() {
59 0 => Ok(Self { size, alignment }),
60 _ => Err(ZLayoutError::IncorrectLayoutArgs),
61 }
62 }
63
64 const unsafe fn new_unchecked(size: NonZeroUsize, alignment: AllocAlignment) -> Self {
67 Self { size, alignment }
68 }
69
70 #[allow(path_statements)]
72 #[zenoh_macros::unstable_doc]
73 pub const fn for_type<T: Sized>() -> Self {
74 struct ZstCheck<T>(PhantomData<T>);
75 impl<T> ZstCheck<T> {
76 const NOT_ZST: () = assert!(mem::size_of::<T>() != 0, "`T` must not be a ZST");
77 }
78 ZstCheck::<T>::NOT_ZST;
79 let size = unsafe { NonZeroUsize::new_unchecked(mem::size_of::<T>()) };
81 let alignment = AllocAlignment::for_type::<T>();
82 unsafe { Self::new_unchecked(size, alignment) }
83 }
84
85 #[zenoh_macros::unstable_doc]
87 pub const fn for_value<T: Sized>(_: &T) -> Self {
88 Self::for_type::<T>()
89 }
90
91 #[zenoh_macros::unstable_doc]
92 pub fn size(&self) -> NonZeroUsize {
93 self.size
94 }
95
96 #[zenoh_macros::unstable_doc]
97 pub fn alignment(&self) -> AllocAlignment {
98 self.alignment
99 }
100
101 #[zenoh_macros::unstable_doc]
120 pub fn extend(&self, new_alignment: AllocAlignment) -> Result<MemoryLayout, ZLayoutError> {
121 if new_alignment < self.alignment {
122 return Err(ZLayoutError::IncorrectLayoutArgs);
123 }
124 let new_size = new_alignment.align_size(self.size);
125 MemoryLayout::new(new_size, new_alignment)
126 }
127}
128
129impl TryFrom<NonZeroUsize> for MemoryLayout {
130 type Error = ZLayoutError;
131
132 fn try_from(value: NonZeroUsize) -> Result<Self, Self::Error> {
133 MemoryLayout::new(value, AllocAlignment::ALIGN_1_BYTE)
134 }
135}
136
137impl TryFrom<usize> for MemoryLayout {
138 type Error = ZLayoutError;
139
140 fn try_from(value: usize) -> Result<Self, Self::Error> {
141 MemoryLayout::new(value, AllocAlignment::ALIGN_1_BYTE)
142 }
143}
144
145impl TryFrom<(NonZeroUsize, AllocAlignment)> for MemoryLayout {
146 type Error = ZLayoutError;
147
148 fn try_from(value: (NonZeroUsize, AllocAlignment)) -> Result<Self, Self::Error> {
149 MemoryLayout::new(value.0, value.1)
150 }
151}
152
153impl TryFrom<(usize, AllocAlignment)> for MemoryLayout {
154 type Error = ZLayoutError;
155
156 fn try_from(value: (usize, AllocAlignment)) -> Result<Self, Self::Error> {
157 MemoryLayout::new(value.0, value.1)
158 }
159}
160
161#[zenoh_macros::unstable_doc]
167pub struct TypedLayout<T> {
168 _phantom: PhantomData<T>,
169}
170
171impl<T> Default for TypedLayout<T> {
172 fn default() -> Self {
173 Self::new()
174 }
175}
176
177impl<T> TypedLayout<T> {
178 #[zenoh_macros::unstable_doc]
180 pub fn new() -> Self {
181 Self {
182 _phantom: PhantomData,
183 }
184 }
185
186 #[zenoh_macros::unstable_doc]
188 pub fn for_value(_: &T) -> Self {
189 Self::new()
190 }
191}
192
193impl<T> Clone for TypedLayout<T> {
194 fn clone(&self) -> Self {
195 *self
196 }
197}
198
199impl<T> Copy for TypedLayout<T> {}