1use core::mem::MaybeUninit;
2
3use crate::traits::{Initialize, InitializeExt as _, InitializeVectored, TrustedDeref};
4use crate::wrappers::{AsUninit, AssertInit, AssertInitVectors, SingleVector};
5
6#[derive(Debug)]
12pub struct BufferInitializer<T> {
13 pub(crate) inner: T,
21 pub(crate) items_initialized: usize,
31 }
35
36impl<T> BufferInitializer<T> {
37 #[inline]
40 pub const fn uninit(inner: T) -> Self {
41 Self {
42 inner,
43 items_initialized: 0,
44 }
45 }
46
47 #[inline]
48 pub fn into_inner(self) -> T {
49 self.inner
50 }
51
52 #[inline]
53 pub const fn items_initialized(&self) -> usize {
54 self.items_initialized
55 }
56}
57impl<T, Item> BufferInitializer<AsUninit<T>>
58where
59 T: core::ops::Deref<Target = [Item]> + core::ops::DerefMut + TrustedDeref,
60{
61 pub fn new(init: T) -> Self {
64 let mut this = Self::uninit(AsUninit(init));
65 unsafe {
67 this.advance_to_end();
68 }
69 this
70 }
71}
72impl<T> BufferInitializer<T>
73where
74 T: Initialize,
75{
76 pub(crate) fn debug_assert_validity(&self) {
77 debug_assert!(self.items_initialized <= self.capacity());
78 }
79
80 #[inline]
90 pub unsafe fn advance(&mut self, count: usize) {
91 self.items_initialized += count;
92 }
93 #[inline]
100 pub unsafe fn advance_to_end(&mut self) {
101 self.items_initialized = self.all_uninit().len();
102 }
103
104 #[inline]
111 pub unsafe fn assume_init(self) -> AssertInit<T> {
112 self.inner.assume_init()
113 }
114
115 #[inline]
116 pub fn into_raw_parts(self) -> (T, usize) {
117 let Self {
118 inner,
119 items_initialized,
120 } = self;
121 (inner, items_initialized)
122 }
123
124 #[inline]
126 pub fn all_uninit(&self) -> &[MaybeUninit<T::Item>] {
127 self.inner.as_maybe_uninit_slice()
128 }
129 #[inline]
136 pub unsafe fn all_uninit_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
137 self.inner.as_maybe_uninit_slice_mut()
138 }
139 #[inline]
141 pub fn capacity(&self) -> usize {
142 self.all_uninit().len()
143 }
144 #[inline]
147 pub fn remaining(&self) -> usize {
148 debug_assert!(self.capacity() >= self.items_initialized);
149 self.capacity().wrapping_sub(self.items_initialized)
150 }
151 #[inline]
154 pub fn is_completely_init(&self) -> bool {
155 self.items_initialized() == self.capacity()
156 }
157 #[inline]
159 pub fn is_completely_uninit(&self) -> bool {
160 self.items_initialized() == 0
161 }
162 #[inline]
166 pub fn uninit_part(&self) -> &[MaybeUninit<T::Item>] {
167 let all = self.all_uninit();
168
169 self.debug_assert_validity();
171
172 unsafe {
175 let ptr = all.as_ptr().add(self.items_initialized);
186 let len = all.len().wrapping_sub(self.items_initialized);
187
188 core::slice::from_raw_parts(ptr, len)
203 }
204 }
205 #[inline]
208 pub fn init_part(&self) -> &[T::Item] {
209 self.debug_assert_validity();
211
212 unsafe {
214 let ptr = self.all_uninit().as_ptr();
215 let len = self.items_initialized;
216
217 core::slice::from_raw_parts(ptr as *const T::Item, len)
224 }
225 }
226
227 #[inline]
230 pub fn uninit_part_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
231 let (orig_ptr, orig_len) = unsafe {
234 let orig = self.all_uninit_mut();
235 (orig.as_mut_ptr(), orig.len())
236 };
237 unsafe {
238 self.debug_assert_validity();
240
241 let ptr = orig_ptr.add(self.items_initialized);
244 let len = orig_len.wrapping_sub(self.items_initialized);
245
246 core::slice::from_raw_parts_mut(ptr, len)
250 }
251 }
252
253 #[inline]
256 pub fn init_part_mut(&mut self) -> &mut [T::Item] {
257 let orig_ptr = unsafe { self.all_uninit_mut().as_mut_ptr() };
258
259 unsafe {
260 let ptr = orig_ptr;
261 let len = self.items_initialized;
262
263 core::slice::from_raw_parts_mut(ptr as *mut T::Item, len)
267 }
268 }
269 #[inline]
272 pub fn try_into_init(self) -> Result<AssertInit<T>, Self> {
273 if self.is_completely_init() {
274 Ok(unsafe { self.assume_init() })
275 } else {
276 Err(self)
277 }
278 }
279 pub fn finish_init_by_filling(mut self, item: T::Item) -> AssertInit<T>
282 where
283 T::Item: Copy,
284 {
285 self.fill_uninit_part(item);
286 unsafe { self.assume_init() }
287 }
288 #[inline]
296 pub fn fill_uninit_part(&mut self, item: T::Item)
297 where
298 T::Item: Copy,
299 {
300 crate::fill_uninit_slice(self.uninit_part_mut(), item);
301 unsafe {
302 self.advance_to_end();
303 }
304 }
305 #[inline]
306 pub fn partially_fill_uninit_part(&mut self, count: usize, item: T::Item)
307 where
308 T::Item: Copy,
309 {
310 crate::fill_uninit_slice(&mut self.uninit_part_mut()[..count], item);
311 unsafe { self.advance(count) }
313 }
314 #[inline]
324 pub fn init_uninit_parts(&self) -> (&[T::Item], &[MaybeUninit<T::Item>]) {
325 (self.init_part(), self.uninit_part())
326 }
327 #[inline]
329 pub fn init_uninit_parts_mut(&mut self) -> (&mut [T::Item], &mut [MaybeUninit<T::Item>]) {
330 let (all_ptr, all_len) = unsafe {
331 let all = self.all_uninit_mut();
332
333 (all.as_mut_ptr(), all.len())
334 };
335
336 unsafe {
337 self.debug_assert_validity();
338
339 let init_base_ptr = all_ptr as *mut T::Item;
340 let init_len = self.items_initialized;
341
342 let uninit_base_ptr = all_ptr.add(self.items_initialized);
343 let uninit_len = all_len.wrapping_sub(self.items_initialized);
344
345 let init = core::slice::from_raw_parts_mut(init_base_ptr, init_len);
346 let uninit = core::slice::from_raw_parts_mut(uninit_base_ptr, uninit_len);
347
348 (init, uninit)
349 }
350 }
351}
352impl<T> BufferInitializer<T>
353where
354 T: Initialize<Item = u8>,
357{
358 pub fn finish_init_by_zeroing(self) -> AssertInit<T> {
361 self.finish_init_by_filling(0_u8)
362 }
363 #[inline]
364 pub fn partially_zero_uninit_part(&mut self, count: usize) {
365 crate::fill_uninit_slice(&mut self.uninit_part_mut()[..count], 0_u8);
366 unsafe { self.advance(count) }
368 }
369 #[inline]
377 pub fn zero_uninit_part(&mut self) {
378 self.fill_uninit_part(0_u8);
379 unsafe { self.advance_to_end() }
380 }
381}
382
383pub struct BuffersInitializer<T> {
384 pub(crate) inner: T,
388
389 pub(crate) vectors_initialized: usize,
394 pub(crate) items_initialized_for_vector: usize,
395}
396
397impl<T> BuffersInitializer<T> {
398 #[inline]
399 pub const fn uninit(inner: T) -> Self {
400 Self {
401 inner,
402 vectors_initialized: 0,
403 items_initialized_for_vector: 0,
404 }
405 }
406 #[inline]
407 pub fn into_raw_parts(self) -> (T, usize, usize) {
408 let Self {
409 inner,
410 vectors_initialized,
411 items_initialized_for_vector,
412 } = self;
413
414 (inner, vectors_initialized, items_initialized_for_vector)
415 }
416 #[inline]
417 pub fn into_inner(self) -> T {
418 let (inner, _, _) = self.into_raw_parts();
419
420 inner
421 }
422}
423impl<T> BuffersInitializer<SingleVector<T>> {
424 pub fn from_single_buffer_initializer(single: BufferInitializer<T>) -> Self {
425 let BufferInitializer {
426 items_initialized,
427 inner,
428 } = single;
429
430 Self {
431 items_initialized_for_vector: items_initialized,
432 vectors_initialized: 0,
433 inner: SingleVector(inner),
434 }
435 }
436}
437
438impl<T, Item> BuffersInitializer<T>
439where
440 T: InitializeVectored,
441 T::UninitVector: Initialize<Item = Item>,
442{
443 #[inline]
444 fn all_vectors_uninit(&self) -> &[T::UninitVector] {
445 self.inner.as_maybe_uninit_vectors()
446 }
447
448 #[inline]
450 pub fn current_vector_all(&self) -> Option<&[MaybeUninit<Item>]> {
451 self.debug_assert_validity();
452
453 let vectors_initialized = self.vectors_initialized;
454
455 if vectors_initialized != self.total_vector_count() {
456 Some(unsafe {
457 self.all_vectors_uninit()
458 .get_unchecked(vectors_initialized)
459 .as_maybe_uninit_slice()
460 })
461 } else {
462 None
463 }
464 }
465 #[inline]
471 pub unsafe fn current_vector_all_mut(&mut self) -> Option<&mut [MaybeUninit<Item>]> {
472 self.debug_assert_validity();
473
474 let vectors_initialized = self.vectors_initialized;
475
476 if vectors_initialized != self.total_vector_count() {
477 let all_vectors_uninit_mut = self.all_uninit_vectors_mut();
478 let current_vector_uninit_mut =
479 all_vectors_uninit_mut.get_unchecked_mut(vectors_initialized);
480 Some(current_vector_uninit_mut.as_maybe_uninit_slice_mut())
481 } else {
482 None
483 }
484 }
485
486 #[inline]
487 pub fn current_vector_init_part(&self) -> Option<&[Item]> {
488 let (init_part, _) = self.current_vector_init_uninit_parts()?;
489
490 Some(init_part)
491 }
492
493 #[inline]
494 pub fn current_vector_uninit_part(&self) -> Option<&[MaybeUninit<Item>]> {
495 let (_, uninit_part) = self.current_vector_init_uninit_parts()?;
496
497 Some(uninit_part)
498 }
499 #[inline]
500 pub fn current_vector_init_uninit_parts(&self) -> Option<(&[Item], &[MaybeUninit<Item>])> {
501 let vector = self.current_vector_all()?;
502
503 Some(unsafe {
504 let init_vector_base_ptr = vector.as_ptr() as *const Item;
505 let init_vector_len = self.items_initialized_for_vector;
506
507 let init_vector = core::slice::from_raw_parts(init_vector_base_ptr, init_vector_len);
508
509 let uninit_vector_base_ptr = vector.as_ptr().add(self.items_initialized_for_vector);
510 let uninit_vector_len = vector.len().wrapping_sub(self.items_initialized_for_vector);
511
512 let uninit_vector =
513 core::slice::from_raw_parts(uninit_vector_base_ptr, uninit_vector_len);
514
515 (init_vector, uninit_vector)
516 })
517 }
518
519 #[inline]
520 pub fn current_vector_init_part_mut(&mut self) -> Option<&mut [Item]> {
521 let (init_part_mut, _) = self.current_vector_init_uninit_parts_mut()?;
522
523 Some(init_part_mut)
524 }
525
526 #[inline]
527 pub fn current_vector_uninit_part_mut(&mut self) -> Option<&mut [MaybeUninit<Item>]> {
528 let (_, uninit_part_mut) = self.current_vector_init_uninit_parts_mut()?;
529
530 Some(uninit_part_mut)
531 }
532 #[inline]
533 pub fn current_vector_init_uninit_parts_mut(
534 &mut self,
535 ) -> Option<(&mut [Item], &mut [MaybeUninit<Item>])> {
536 let (orig_base_ptr, orig_len) = unsafe {
537 let vector = self.current_vector_all_mut()?;
538
539 (vector.as_mut_ptr(), vector.len())
540 };
541 Some(unsafe {
542 let init_vector_base_ptr = orig_base_ptr as *mut Item;
543 let init_vector_len = self.items_initialized_for_vector;
544
545 let init_vector =
546 core::slice::from_raw_parts_mut(init_vector_base_ptr, init_vector_len);
547
548 let uninit_vector_base_ptr = orig_base_ptr.add(self.items_initialized_for_vector);
549 let uninit_vector_len = orig_len.wrapping_sub(self.items_initialized_for_vector);
550
551 let uninit_vector =
552 core::slice::from_raw_parts_mut(uninit_vector_base_ptr, uninit_vector_len);
553
554 (init_vector, uninit_vector)
555 })
556 }
557
558 fn debug_assert_validity(&self) {
559 debug_assert!(self
560 .inner
561 .as_maybe_uninit_vectors()
562 .get(self.vectors_initialized)
563 .map_or(true, |current_vector| current_vector
564 .as_maybe_uninit_slice()
565 .len()
566 >= self.items_initialized_for_vector));
567 debug_assert!(self.items_initialized_for_vector <= isize::MAX as usize);
568 debug_assert!(self.inner.as_maybe_uninit_vectors().len() >= self.vectors_initialized);
569 }
570
571 #[inline]
573 pub fn total_vector_count(&self) -> usize {
574 self.inner.as_maybe_uninit_vectors().len()
575 }
576
577 #[inline]
579 pub fn vectors_initialized(&self) -> usize {
580 self.vectors_initialized
581 }
582
583 #[inline]
586 pub fn vectors_remaining(&self) -> usize {
587 self.total_vector_count()
588 .wrapping_sub(self.vectors_initialized())
589 }
590
591 pub fn count_items_to_initialize(&self) -> usize {
597 let items_to_initialize_for_remaining = self
598 .all_uninit_vectors()
599 .iter()
600 .skip(self.vectors_initialized + 1_usize)
601 .map(|buffer| buffer.as_maybe_uninit_slice().len())
602 .sum::<usize>();
603
604 self.items_initialized_for_vector + items_to_initialize_for_remaining
605 }
606 pub fn count_total_items_in_all_vectors(&self) -> usize {
607 self.all_uninit_vectors()
608 .iter()
609 .map(|buffer| buffer.as_maybe_uninit_slice().len())
610 .sum()
611 }
612
613 #[inline]
625 pub unsafe fn items_initialized_for_vector_unchecked(&self, vector_index: usize) -> usize {
626 let ordering = vector_index.cmp(&self.vectors_initialized);
627
628 match ordering {
629 core::cmp::Ordering::Equal => self.items_initialized_for_vector,
630 core::cmp::Ordering::Greater => 0,
631 core::cmp::Ordering::Less => self
632 .all_uninit_vectors()
633 .get_unchecked(vector_index)
634 .as_maybe_uninit_slice()
635 .len(),
636 }
637 }
638 #[inline]
639 pub fn items_initialized_for_vector(&self, vector_index: usize) -> usize {
640 assert!(vector_index < self.total_vector_count());
641
642 unsafe { self.items_initialized_for_vector_unchecked(vector_index) }
643 }
644 #[inline]
645 pub fn items_initialized_for_current_vector(&self) -> usize {
646 if self.vectors_initialized() != self.total_vector_count() {
647 self.items_initialized_for_vector
648 } else {
649 0
650 }
651 }
652
653 #[inline]
655 pub fn all_uninit_vectors(&self) -> &[T::UninitVector] {
656 self.inner.as_maybe_uninit_vectors()
657 }
658 #[inline]
664 pub unsafe fn all_uninit_vectors_mut(&mut self) -> &mut [T::UninitVector] {
665 self.inner.as_maybe_uninit_vectors_mut()
666 }
667 #[inline]
680 pub unsafe fn advance(&mut self, mut count: usize) -> usize {
681 let mut items_advanced = 0;
682
683 while let Some(current_uninit_part) = self.current_vector_uninit_part() {
684 let current_uninit_part_len = current_uninit_part.len();
685
686 if count >= current_uninit_part_len {
687 self.vectors_initialized = self
688 .vectors_initialized
689 .checked_add(1)
690 .expect("reached usize::MAX when incrementing the buffer index");
691 self.items_initialized_for_vector = 0;
692
693 count -= current_uninit_part_len;
694
695 items_advanced -= current_uninit_part_len;
696 continue;
697 } else {
698 self.items_initialized_for_vector += current_uninit_part_len;
699 }
700 }
701
702 items_advanced
703 }
704 pub unsafe fn advance_current_vector_to_end(&mut self) {
716 self.debug_assert_validity();
717
718 self.vectors_initialized += 1;
719 self.items_initialized_for_vector = 0;
720 }
721 pub unsafe fn advance_current_vector(&mut self, count: usize) {
722 self.debug_assert_validity();
723
724 if let Some(current_vector) = self.current_vector_all() {
725 let current_vector_len = current_vector.len();
726 let end = self.items_initialized_for_vector + count;
727
728 assert!(end <= current_vector_len);
729
730 if end == current_vector_len {
731 self.vectors_initialized += 1;
732 self.items_initialized_for_vector = 0;
733 } else {
734 self.items_initialized_for_vector = end;
735 }
736 } else if count > 0 {
737 panic!("cannot advance beyond the end of the current vector")
738 }
739 }
740 pub fn partially_fill_current_vector_uninit_part(&mut self, count: usize, item: Item)
741 where
742 Item: Copy,
743 {
744 if let Some(current_vector_uninit_part_mut) = self.current_vector_uninit_part_mut() {
745 crate::fill_uninit_slice(&mut current_vector_uninit_part_mut[..count], item);
746 unsafe { self.advance_current_vector(count) }
747 } else if count > 0 {
748 panic!("cannot partially fill a vector when none are left");
749 }
750 }
751 pub fn fill_current_vector_uninit_part(&mut self, item: Item)
752 where
753 Item: Copy,
754 {
755 if let Some(current_vector_uninit_part_mut) = self.current_vector_uninit_part_mut() {
756 crate::fill_uninit_slice(current_vector_uninit_part_mut, item);
757 unsafe { self.advance_current_vector_to_end() }
758 }
759 }
760 pub fn try_into_init(self) -> Result<AssertInitVectors<T>, Self> {
761 if self.vectors_remaining() == 0 {
762 Ok(unsafe { AssertInitVectors::new_unchecked(self.into_inner()) })
763 } else {
764 Err(self)
765 }
766 }
767}
768impl<T> BuffersInitializer<T>
769where
770 T: InitializeVectored,
771 T::UninitVector: Initialize<Item = u8>,
773{
774 pub fn partially_zero_current_vector_uninit_part(&mut self, count: usize) {
775 self.partially_fill_current_vector_uninit_part(count, 0_u8)
776 }
777 pub fn zero_current_vector_uninit_part(&mut self) {
778 self.fill_current_vector_uninit_part(0_u8)
779 }
780}
781
782#[cfg(test)]
783mod tests {
784 use super::*;
785
786 mod single {
787 use super::*;
788
789 #[test]
790 fn new_fills_completely() {
791 let slice = *b"Calling BufferInitializer::new() will ensure that the initialization marker is put at the end of the slice, making it fully zero-cost when already using initialized memory.";
792 let mut copy = slice;
793
794 let mut initializer = BufferInitializer::new(&mut copy[..]);
795
796 assert_eq!(initializer.remaining(), 0);
797 assert_eq!(initializer.capacity(), slice.len());
798 assert!(initializer.is_completely_init());
799 assert!(!initializer.is_completely_uninit());
800 assert!(initializer.uninit_part().is_empty());
801 assert!(initializer.uninit_part_mut().is_empty());
802 assert_eq!(initializer.init_part(), slice);
803 assert_eq!(initializer.init_part_mut(), slice);
804 assert!(initializer.try_into_init().is_ok());
805 }
806
807 #[test]
808 fn basic_initialization() {
809 let mut slice = [MaybeUninit::uninit(); 32];
810 let buffer = BufferInitializer::uninit(&mut slice[..]);
811 let initialized = buffer.finish_init_by_filling(42_u8);
812 assert!(initialized.iter().all(|&byte| byte == 42_u8));
813 }
814 #[test]
815 fn buffer_parts() {
816 let mut slice = [MaybeUninit::<u8>::uninit(); 32];
817 let mut buffer = BufferInitializer::uninit(&mut slice[..]);
818
819 assert_eq!(buffer.uninit_part().len(), 32);
820 assert_eq!(buffer.uninit_part_mut().len(), 32);
821 assert_eq!(buffer.init_part(), &[]);
822 assert_eq!(buffer.init_part_mut(), &mut []);
823 assert!(!buffer.is_completely_init());
824
825 }
827 }
828 mod vectored {
829 use super::*;
830
831 #[test]
832 fn fill_uninit_part() {
833 let mut first = [MaybeUninit::uninit(); 32];
834 let mut second = [MaybeUninit::uninit(); 128];
835 let mut third = [MaybeUninit::uninit(); 64];
836
837 let mut vectors = [&mut first[..], &mut second[..], &mut third[..]];
838 let mut initializer = BuffersInitializer::uninit(&mut vectors[..]);
839
840 initializer.zero_current_vector_uninit_part();
841 assert_eq!(initializer.vectors_initialized(), 1);
842 assert_eq!(initializer.items_initialized_for_current_vector(), 0);
843
844 initializer.partially_zero_current_vector_uninit_part(96);
845 assert_eq!(initializer.vectors_initialized(), 1);
846 assert_eq!(initializer.items_initialized_for_current_vector(), 96);
847
848 initializer.partially_fill_current_vector_uninit_part(32, 0x13_u8);
849 assert_eq!(initializer.vectors_initialized(), 2);
850 assert_eq!(initializer.items_initialized_for_current_vector(), 0);
851
852 initializer.partially_fill_current_vector_uninit_part(16, 0x37_u8);
853 assert_eq!(initializer.vectors_initialized(), 2);
854 assert_eq!(initializer.items_initialized_for_current_vector(), 16);
855 initializer.fill_current_vector_uninit_part(0x42);
856 assert_eq!(initializer.vectors_initialized(), 3);
857 assert!(initializer.current_vector_all().is_none());
858 }
859 }
860}