1use core::ops::{Deref, DerefMut};
23
24use const_default::ConstDefault;
25use generic_array::{
26 ArrayLength, GenericArray,
27 typenum::{B0, B1, IsGreater, PowerOfTwo, U0, U1, U8, U32, U64, UInt, Unsigned},
28};
29use zeroize::DefaultIsZeroes;
30
31pub unsafe trait AlignerTo<T>: Deref<Target = T> + DerefMut<Target = T> + From<T> {
37 type Alignment: Unsigned + PowerOfTwo + IsGreater<U0, Output = B1>;
39 type Output;
41
42 fn create_layout() -> core::alloc::Layout;
48}
49
50unsafe impl<T> AlignerTo<T> for Align1<T> {
51 type Alignment = U1;
52 type Output = Align1<T>;
53
54 fn create_layout() -> core::alloc::Layout {
55 core::alloc::Layout::from_size_align(core::mem::size_of::<T>(), 1)
56 .expect("request memory size is too large for allocation")
57 }
58}
59
60unsafe impl<T> AlignerTo<T> for Align8<T> {
61 type Alignment = U8;
62 type Output = Align8<T>;
63
64 fn create_layout() -> core::alloc::Layout {
65 core::alloc::Layout::from_size_align(core::mem::size_of::<T>(), 8)
66 .expect("request memory size is too large for allocation")
67 }
68}
69
70unsafe impl<T> AlignerTo<T> for Align32<T> {
71 type Alignment = U32;
72 type Output = Align32<T>;
73 fn create_layout() -> core::alloc::Layout {
74 core::alloc::Layout::from_size_align(core::mem::size_of::<T>(), 32)
75 .expect("request memory size is too large for allocation")
76 }
77}
78
79unsafe impl<T> AlignerTo<T> for Align64<T> {
80 type Alignment = U64;
81 type Output = Align64<T>;
82
83 fn create_layout() -> core::alloc::Layout {
84 core::alloc::Layout::from_size_align(core::mem::size_of::<T>(), 64)
85 .expect("request memory size is too large for allocation")
86 }
87}
88
89#[derive(Debug, Clone, Copy)]
91#[repr(transparent)]
92pub struct Align1<T>(pub T);
93
94impl<T: DefaultIsZeroes + Copy> DefaultIsZeroes for Align1<T> {}
95
96impl<T: Default> Default for Align1<T> {
97 fn default() -> Self {
98 Self(Default::default())
99 }
100}
101
102impl<T> Deref for Align1<T> {
103 type Target = T;
104
105 fn deref(&self) -> &Self::Target {
106 &self.0
107 }
108}
109
110impl<T> DerefMut for Align1<T> {
111 fn deref_mut(&mut self) -> &mut Self::Target {
112 &mut self.0
113 }
114}
115
116impl<T> From<T> for Align1<T> {
117 fn from(value: T) -> Self {
118 Self(value)
119 }
120}
121
122impl<T> Align1<T> {
123 pub const fn new(value: T) -> Self {
125 Self(value)
126 }
127
128 pub const unsafe fn from_raw_unchecked(ptr: *const T) -> *const Self {
134 ptr.cast::<Self>()
135 }
136
137 pub fn from_raw(input: &T) -> &Self {
142 unsafe { &*(input as *const T).cast::<Self>() }
143 }
144
145 pub const unsafe fn from_raw_mut_unchecked(ptr: *mut T) -> *mut Self {
151 ptr.cast::<Self>()
152 }
153
154 pub fn from_raw_mut(input: &mut T) -> &mut Self {
160 unsafe { &mut *(input as *mut T).cast::<Self>() }
161 }
162}
163
164#[repr(align(8))]
165#[derive(Debug, Clone, Copy)]
166pub struct Align8<T>(pub T);
168
169impl<T: DefaultIsZeroes + Copy> DefaultIsZeroes for Align8<T> {}
170
171impl<T: Default> Default for Align8<T> {
172 fn default() -> Self {
173 Self(Default::default())
174 }
175}
176
177impl<T> Deref for Align8<T> {
178 type Target = T;
179
180 fn deref(&self) -> &Self::Target {
181 &self.0
182 }
183}
184
185impl<T> DerefMut for Align8<T> {
186 fn deref_mut(&mut self) -> &mut Self::Target {
187 &mut self.0
188 }
189}
190
191impl<T> From<T> for Align8<T> {
192 fn from(value: T) -> Self {
193 Self(value)
194 }
195}
196
197type Times8<T> = UInt<UInt<UInt<T, B0>, B0>, B0>;
198
199type Times32<T> = UInt<UInt<Times8<T>, B0>, B0>;
200
201type Times64<T> = UInt<Times32<T>, B0>;
202
203impl<T, L: ArrayLength> Align8<GenericArray<T, Times8<L>>> {
204 #[must_use]
206 pub const fn lift<U: ArrayLength>(
207 input: GenericArray<Self, U>,
208 ) -> Align8<GenericArray<GenericArray<T, Times8<L>>, U>> {
209 unsafe { generic_array::const_transmute(input) }
211 }
212
213 #[cfg(feature = "alloc")]
215 #[must_use]
216 pub const fn lift_boxed<U: ArrayLength>(
217 input: alloc::boxed::Box<GenericArray<Self, U>>,
218 ) -> alloc::boxed::Box<Align8<GenericArray<GenericArray<T, Times8<L>>, U>>> {
219 unsafe { generic_array::const_transmute(input) }
221 }
222}
223
224impl<T> Align8<T> {
225 pub const fn new(value: T) -> Self {
227 Self(value)
228 }
229
230 pub const unsafe fn from_raw_unchecked(ptr: *const T) -> *const Self {
236 ptr.cast::<Self>()
237 }
238
239 pub fn from_raw(input: &T) -> &Self {
245 let ptr = input as *const T;
246 assert_eq!(ptr.align_offset(8), 0, "pointer is not aligned to 8 bytes");
247 unsafe { &*(ptr.cast::<Self>()) }
248 }
249
250 pub const unsafe fn from_raw_mut_unchecked(ptr: *mut T) -> *mut Self {
256 ptr.cast::<Self>()
257 }
258
259 pub fn from_raw_mut(input: &mut T) -> &mut Self {
265 let ptr = input as *mut T;
266 assert_eq!(ptr.align_offset(8), 0, "pointer is not aligned to 8 bytes");
267 unsafe { &mut *(ptr.cast::<Self>()) }
268 }
269}
270
271#[repr(align(32))]
272#[derive(Debug, Clone, Copy)]
273pub struct Align32<T>(pub T);
275
276impl<T: DefaultIsZeroes + Copy> DefaultIsZeroes for Align32<T> {}
277
278impl<T: Default> Default for Align32<T> {
279 fn default() -> Self {
280 Self(Default::default())
281 }
282}
283
284impl<T> Deref for Align32<T> {
285 type Target = T;
286
287 fn deref(&self) -> &Self::Target {
288 &self.0
289 }
290}
291
292impl<T> DerefMut for Align32<T> {
293 fn deref_mut(&mut self) -> &mut Self::Target {
294 &mut self.0
295 }
296}
297
298impl<T> From<T> for Align32<T> {
299 fn from(value: T) -> Self {
300 Self(value)
301 }
302}
303
304impl<T, L: ArrayLength> Align32<GenericArray<T, Times32<L>>> {
305 #[must_use]
307 pub const fn lift<U: ArrayLength>(
308 input: GenericArray<Self, U>,
309 ) -> Align32<GenericArray<GenericArray<T, Times32<L>>, U>> {
310 unsafe { generic_array::const_transmute(input) }
312 }
313
314 #[cfg(feature = "alloc")]
316 #[must_use]
317 pub const fn lift_boxed<U: ArrayLength>(
318 input: alloc::boxed::Box<GenericArray<Self, U>>,
319 ) -> alloc::boxed::Box<Align32<GenericArray<GenericArray<T, Times32<L>>, U>>> {
320 unsafe { generic_array::const_transmute(input) }
322 }
323}
324
325impl<T> Align32<T> {
326 pub const fn new(value: T) -> Self {
328 Self(value)
329 }
330
331 pub const unsafe fn from_raw_unchecked(ptr: *const T) -> *const Self {
337 ptr.cast::<Self>()
338 }
339
340 pub fn from_raw(input: &T) -> &Self {
346 let ptr = input as *const T;
347 assert_eq!(
348 ptr.align_offset(32),
349 0,
350 "pointer is not aligned to 32 bytes"
351 );
352 unsafe { &*(ptr.cast::<Self>()) }
353 }
354
355 pub const unsafe fn from_raw_mut_unchecked(ptr: *mut T) -> *mut Self {
361 ptr.cast::<Self>()
362 }
363
364 pub fn from_raw_mut(input: &mut T) -> &mut Self {
370 let ptr = input as *mut T;
371 assert_eq!(
372 ptr.align_offset(32),
373 0,
374 "pointer is not aligned to 32 bytes"
375 );
376 unsafe { &mut *(ptr.cast::<Self>()) }
377 }
378}
379
380#[repr(align(64))]
381#[derive(Debug, Clone, Copy)]
383pub struct Align64<T>(pub T);
384
385impl<T: DefaultIsZeroes + Copy> DefaultIsZeroes for Align64<T> {}
386
387impl<T: Default> Default for Align64<T> {
388 fn default() -> Self {
389 Self(Default::default())
390 }
391}
392
393impl<T> Deref for Align64<T> {
394 type Target = T;
395
396 fn deref(&self) -> &Self::Target {
397 &self.0
398 }
399}
400
401impl<T> DerefMut for Align64<T> {
402 fn deref_mut(&mut self) -> &mut Self::Target {
403 &mut self.0
404 }
405}
406
407impl<T> From<T> for Align64<T> {
408 fn from(value: T) -> Self {
409 Self(value)
410 }
411}
412
413impl<T> Align64<T> {
414 pub const fn new(value: T) -> Self {
416 Self(value)
417 }
418
419 pub const unsafe fn from_raw_unchecked(ptr: *const T) -> *const Self {
425 ptr.cast::<Self>()
426 }
427
428 pub fn from_raw(input: &T) -> &Self {
434 let ptr = input as *const T;
435 assert_eq!(
436 ptr.align_offset(64),
437 0,
438 "pointer is not aligned to 64 bytes"
439 );
440 unsafe { &*(ptr.cast::<Self>()) }
441 }
442
443 pub const unsafe fn from_raw_mut_unchecked(ptr: *mut T) -> *mut Self {
449 ptr.cast::<Self>()
450 }
451
452 pub fn from_raw_mut(input: &mut T) -> &mut Self {
458 let ptr = input as *mut T;
459 assert_eq!(
460 ptr.align_offset(64),
461 0,
462 "pointer is not aligned to 64 bytes"
463 );
464 unsafe { &mut *(ptr.cast::<Self>()) }
465 }
466}
467
468impl<T, L: ArrayLength> Align64<GenericArray<T, Times64<L>>> {
469 #[must_use]
471 pub const fn lift<U: ArrayLength>(
472 input: GenericArray<Self, U>,
473 ) -> Align64<GenericArray<GenericArray<T, Times64<L>>, U>> {
474 unsafe { generic_array::const_transmute(input) }
476 }
477
478 #[cfg(feature = "alloc")]
480 #[must_use]
481 pub const fn lift_boxed<U: ArrayLength>(
482 input: alloc::boxed::Box<GenericArray<Self, U>>,
483 ) -> alloc::boxed::Box<Align64<GenericArray<GenericArray<T, Times64<L>>, U>>> {
484 unsafe { generic_array::const_transmute(input) }
486 }
487}
488
489#[repr(C)]
490pub struct DefaultPaddedArray<E, L: ArrayLength, P: ArrayLength> {
492 _pad0: GenericArray<E, P>,
493 inner: GenericArray<E, L>,
494 _pad1: GenericArray<E, P>,
495}
496
497impl<E, L: ArrayLength, P: ArrayLength> DefaultPaddedArray<E, L, P> {
498 pub fn as_ptr(&self) -> *const E {
500 self.inner.as_ptr()
501 }
502
503 pub fn as_mut_ptr(&mut self) -> *mut E {
505 self.inner.as_mut_ptr()
506 }
507}
508
509impl<E: ConstDefault, L: ArrayLength, P: ArrayLength> AsRef<GenericArray<E, L>>
510 for DefaultPaddedArray<E, L, P>
511{
512 fn as_ref(&self) -> &GenericArray<E, L> {
513 &self.inner
514 }
515}
516
517impl<E: ConstDefault, L: ArrayLength, P: ArrayLength> AsMut<GenericArray<E, L>>
518 for DefaultPaddedArray<E, L, P>
519{
520 fn as_mut(&mut self) -> &mut GenericArray<E, L> {
521 &mut self.inner
522 }
523}
524
525impl<E: ConstDefault, L: ArrayLength, P: ArrayLength> DefaultPaddedArray<E, L, P>
526where
527 <P as ArrayLength>::ArrayType<E>: ConstDefault,
528{
529 pub const fn new(inner: GenericArray<E, L>) -> Self {
531 Self {
532 _pad0: GenericArray::const_default(),
533 inner,
534 _pad1: GenericArray::const_default(),
535 }
536 }
537}
538
539impl<E: ConstDefault, L: ArrayLength, P: ArrayLength> Deref for DefaultPaddedArray<E, L, P> {
540 type Target = GenericArray<E, L>;
541
542 fn deref(&self) -> &Self::Target {
543 &self.inner
544 }
545}
546
547impl<E: ConstDefault, L: ArrayLength, P: ArrayLength> DerefMut for DefaultPaddedArray<E, L, P> {
548 fn deref_mut(&mut self) -> &mut Self::Target {
549 &mut self.inner
550 }
551}
552
553impl<E: Default, L: ArrayLength, P: ArrayLength> Default for DefaultPaddedArray<E, L, P> {
554 fn default() -> Self {
555 Self {
556 _pad0: GenericArray::default(),
557 inner: GenericArray::default(),
558 _pad1: GenericArray::default(),
559 }
560 }
561}
562
563#[cfg(feature = "alloc")]
564pub fn calloc_generic_array_1d<
566 T: DefaultIsZeroes + Copy,
567 A: AlignerTo<GenericArray<T, L>>,
568 L: ArrayLength,
569>() -> alloc::boxed::Box<<A as AlignerTo<GenericArray<T, L>>>::Output> {
570 use core::mem::MaybeUninit;
575 unsafe {
576 let template = T::default();
577 let layout = A::create_layout();
578 let memory = alloc::alloc::alloc(layout);
579 let mut_slice = core::slice::from_raw_parts_mut(memory.cast::<MaybeUninit<T>>(), L::USIZE);
580 mut_slice.iter_mut().for_each(|item| {
581 item.as_mut_ptr().write(template);
582 });
583 alloc::boxed::Box::from_raw(memory.cast())
584 }
585}
586
587#[cfg(feature = "alloc")]
588pub fn calloc_generic_array_2d<
590 T: DefaultIsZeroes + Copy,
591 A: AlignerTo<GenericArray<GenericArray<T, M>, L>>,
592 L: ArrayLength,
593 M: ArrayLength,
594>() -> alloc::boxed::Box<<A as AlignerTo<GenericArray<GenericArray<T, M>, L>>>::Output> {
595 use core::mem::MaybeUninit;
600 unsafe {
601 let template = T::default();
602 let layout = A::create_layout();
603 let memory = alloc::alloc::alloc(layout);
604 let mut_slice =
605 core::slice::from_raw_parts_mut(memory.cast::<MaybeUninit<T>>(), L::USIZE * M::USIZE);
606
607 mut_slice.iter_mut().for_each(|item| {
608 item.as_mut_ptr().write(template);
609 });
610 alloc::boxed::Box::from_raw(memory.cast())
611 }
612}
613
614#[cfg(feature = "alloc")]
615pub fn calloc_generic_array_3d<
617 T: DefaultIsZeroes + Copy,
618 A: AlignerTo<GenericArray<GenericArray<GenericArray<T, M>, N>, L>>,
619 L: ArrayLength,
620 M: ArrayLength,
621 N: ArrayLength,
622>()
623-> alloc::boxed::Box<<A as AlignerTo<GenericArray<GenericArray<GenericArray<T, M>, N>, L>>>::Output>
624{
625 use core::mem::MaybeUninit;
630
631 unsafe {
632 let template = T::default();
633 let layout = A::create_layout();
634 let memory = alloc::alloc::alloc(layout);
635 let mut_slice = core::slice::from_raw_parts_mut(
636 memory.cast::<MaybeUninit<T>>(),
637 L::USIZE * M::USIZE * N::USIZE,
638 );
639 mut_slice.iter_mut().for_each(|item| {
640 item.as_mut_ptr().write(template);
641 });
642 alloc::boxed::Box::from_raw(memory.cast())
643 }
644}