Skip to content

Commit 1afb4f1

Browse files
authored
Remove bounds on as_flattened(_mut); make const fn (#144)
Also adds tests. Previously these used the core `[T]::as_flattened(_mut)` to avoid additional unsafe code, however instead this approach opts to use a similar strategy to how the upstream `as_flattened(_mut)` is implemented to avoid having to have a bound on the inner `ArrayType`.
1 parent 6e38633 commit 1afb4f1

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

src/lib.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,32 @@ where
331331
}
332332
}
333333

334+
/// Obtain a flattened slice from a slice of array chunks.
335+
#[inline]
336+
pub const fn slice_as_flattened(slice: &[Self]) -> &[T] {
337+
let len = slice
338+
.len()
339+
.checked_mul(U::USIZE)
340+
.expect("slice len overflow");
341+
342+
// SAFETY: `[T]` is layout-identical to `Array<T, U>`, which is a `repr(transparent)`
343+
// newtype for `[T; N]`.
344+
unsafe { slice::from_raw_parts(slice.as_ptr().cast(), len) }
345+
}
346+
347+
/// Obtain a mutable flattened slice from a mutable slice of array chunks.
348+
#[inline]
349+
pub const fn slice_as_flattened_mut(slice: &mut [Self]) -> &mut [T] {
350+
let len = slice
351+
.len()
352+
.checked_mul(U::USIZE)
353+
.expect("slice len overflow");
354+
355+
// SAFETY: `[T]` is layout-identical to `Array<T, U>`, which is a `repr(transparent)`
356+
// newtype for `[T; N]`.
357+
unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), len) }
358+
}
359+
334360
/// Convert the given slice into a reference to a hybrid array.
335361
///
336362
/// # Panics
@@ -400,18 +426,6 @@ where
400426
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
401427
unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) }
402428
}
403-
404-
/// Obtain a flattened slice from a slice of array chunks.
405-
#[inline]
406-
pub fn slice_as_flattened(slice: &[Self]) -> &[T] {
407-
Self::cast_slice_to_core(slice).as_flattened()
408-
}
409-
410-
/// Obtain a mutable flattened slice from a mutable slice of array chunks.
411-
#[inline]
412-
pub fn slice_as_flattened_mut(slice: &mut [Self]) -> &mut [T] {
413-
Self::cast_slice_to_core_mut(slice).as_flattened_mut()
414-
}
415429
}
416430

417431
impl<T, U> Array<MaybeUninit<T>, U>

tests/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,13 @@ fn clone_from_slice() {
144144
let array = Array::<u8, U6>::clone_from_slice(EXAMPLE_SLICE);
145145
assert_eq!(array.as_slice(), EXAMPLE_SLICE);
146146
}
147+
148+
#[test]
149+
fn slice_as_flattened() {
150+
let slice: &mut [Array<u8, U4>] = &mut [Array([1, 2, 3, 4]), Array([5, 6, 7, 8])];
151+
assert_eq!(
152+
Array::slice_as_flattened_mut(slice),
153+
&mut [1, 2, 3, 4, 5, 6, 7, 8]
154+
);
155+
assert_eq!(Array::slice_as_flattened(slice), &[1, 2, 3, 4, 5, 6, 7, 8]);
156+
}

0 commit comments

Comments
 (0)