aboutsummaryrefslogtreecommitdiff
path: root/src/misc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc.rs')
-rw-r--r--src/misc.rs71
1 files changed, 43 insertions, 28 deletions
diff --git a/src/misc.rs b/src/misc.rs
index d923d58..faef34f 100644
--- a/src/misc.rs
+++ b/src/misc.rs
@@ -1,37 +1,52 @@
use std::mem;
+use std::mem::MaybeUninit;
use std::slice;
-/// Slice from `vec[vec.len()..vec.capacity()]`
-pub unsafe fn remaining_capacity_as_slice_mut<A>(vec: &mut Vec<A>) -> &mut [A] {
- slice::from_raw_parts_mut(
- vec.as_mut_slice().as_mut_ptr().offset(vec.len() as isize),
- vec.capacity() - vec.len(),
- )
+/// `Vec::spare_capacity_mut` is not stable until Rust 1.60.
+pub(crate) fn vec_spare_capacity_mut<A>(vec: &mut Vec<A>) -> &mut [MaybeUninit<A>] {
+ // SAFETY: copy-paste from rust stdlib.
+ unsafe {
+ slice::from_raw_parts_mut(
+ vec.as_mut_ptr().add(vec.len()) as *mut MaybeUninit<A>,
+ vec.capacity() - vec.len(),
+ )
+ }
}
-pub unsafe fn remove_lifetime_mut<A: ?Sized>(a: &mut A) -> &'static mut A {
- mem::transmute(a)
+/// `MaybeUninit::write_slice` is not stable.
+pub(crate) fn maybe_uninit_write_slice<'a, T>(
+ this: &'a mut [MaybeUninit<T>],
+ src: &[T],
+) -> &'a mut [T]
+where
+ T: Copy,
+{
+ // SAFETY: copy-paste from rust stdlib.
+
+ let uninit_src: &[MaybeUninit<T>] = unsafe { mem::transmute(src) };
+
+ this.copy_from_slice(uninit_src);
+
+ unsafe { &mut *(this as *mut [MaybeUninit<T>] as *mut [T]) }
}
-#[cfg(test)]
-mod test {
- use super::*;
+/// `MaybeUninit::array_assume_init` is not stable.
+#[inline]
+pub(crate) unsafe fn maybe_ununit_array_assume_init<T, const N: usize>(
+ array: [MaybeUninit<T>; N],
+) -> [T; N] {
+ // SAFETY:
+ // * The caller guarantees that all elements of the array are initialized
+ // * `MaybeUninit<T>` and T are guaranteed to have the same layout
+ // * `MaybeUninit` does not drop, so there are no double-frees
+ // And thus the conversion is safe
+ (&array as *const _ as *const [T; N]).read()
+}
- #[test]
- fn test_remaining_capacity_as_slice_mut() {
- let mut v = Vec::with_capacity(5);
- v.push(10);
- v.push(11);
- v.push(12);
- unsafe {
- {
- let s = remaining_capacity_as_slice_mut(&mut v);
- assert_eq!(2, s.len());
- s[0] = 13;
- s[1] = 14;
- }
- v.set_len(5);
- }
- assert_eq!(vec![10, 11, 12, 13, 14], v);
- }
+/// `MaybeUninit::write` is stable since 1.55.
+#[inline]
+pub(crate) fn maybe_uninit_write<T>(uninit: &mut MaybeUninit<T>, val: T) -> &mut T {
+ // SAFETY: copy-paste from rust stdlib.
+ *uninit = MaybeUninit::new(val);
+ unsafe { &mut *uninit.as_mut_ptr() }
}