Skip to content

Commit 7569e51

Browse files
authored
Add functions for casting from core references (#181)
- `Array::cast_from_core`: `const fn` equivalent of `From<[T; N]>` - `Array::cast_from_core_mut`: `mut` equivalent of the above - `Array::from_ref`: cast `&T` to `&Array<T; U1>` - `Array::from_mut`: `mut` equivalent of the above The latter are the equivalents of `core::array::{from_ref, from_mut}` which I opted to put on `Array<T, U1>` for consistency with `Array::from_fn` which is impl'd on the type instead of as a free function.
1 parent e16fe91 commit 7569e51

2 files changed

Lines changed: 49 additions & 9 deletions

File tree

src/lib.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ use core::{
126126
ptr,
127127
slice::{self, Iter, IterMut},
128128
};
129-
use typenum::{Diff, Sum};
129+
use typenum::{Diff, Sum, U1};
130130

131131
#[cfg(feature = "arbitrary")]
132132
use arbitrary::Arbitrary;
@@ -401,6 +401,19 @@ where
401401
}
402402
}
403403

404+
impl<T> Array<T, U1> {
405+
/// Convert a reference to `T` into a reference to an [`Array`] of length [`U1`].
406+
pub const fn from_ref(r: &T) -> &Self {
407+
Self::cast_from_core(core::array::from_ref(r))
408+
}
409+
410+
/// Converts a mutable reference to `T` into a mutable reference to an [`Array`] of
411+
/// length [`U1`].
412+
pub const fn from_mut(r: &mut T) -> &mut Self {
413+
Self::cast_from_core_mut(core::array::from_mut(r))
414+
}
415+
}
416+
404417
impl<T, U, V> Array<Array<T, U>, V>
405418
where
406419
U: ArraySize,
@@ -475,30 +488,44 @@ impl<T, U, const N: usize> Array<T, U>
475488
where
476489
U: ArraySize<ArrayType<T> = [T; N]>,
477490
{
491+
/// Cast a reference to a core array to an [`Array`] reference.
492+
#[inline]
493+
pub const fn cast_from_core(array_ref: &[T; N]) -> &Self {
494+
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
495+
unsafe { &*array_ref.as_ptr().cast() }
496+
}
497+
498+
/// Cast a mutable reference to a core array to an [`Array`] reference.
499+
#[inline]
500+
pub const fn cast_from_core_mut(array_ref: &mut [T; N]) -> &mut Self {
501+
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; 1]`
502+
unsafe { &mut *array_ref.as_mut_ptr().cast() }
503+
}
504+
478505
/// Transform slice to slice of core array type.
479506
#[inline]
480-
pub const fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]] {
507+
pub const fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self] {
481508
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
482509
unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) }
483510
}
484511

485512
/// Transform mutable slice to mutable slice of core array type.
486513
#[inline]
487-
pub const fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]] {
514+
pub const fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self] {
488515
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
489516
unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) }
490517
}
491518

492519
/// Transform slice to slice of core array type.
493520
#[inline]
494-
pub const fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self] {
521+
pub const fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]] {
495522
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
496523
unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) }
497524
}
498525

499526
/// Transform mutable slice to mutable slice of core array type.
500527
#[inline]
501-
pub const fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self] {
528+
pub const fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]] {
502529
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]`
503530
unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) }
504531
}
@@ -733,8 +760,7 @@ where
733760
{
734761
#[inline]
735762
fn from(array_ref: &'a [T; N]) -> &'a Array<T, U> {
736-
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]`
737-
unsafe { &*array_ref.as_ptr().cast() }
763+
Array::cast_from_core(array_ref)
738764
}
739765
}
740766

@@ -754,8 +780,7 @@ where
754780
{
755781
#[inline]
756782
fn from(array_ref: &'a mut [T; N]) -> &'a mut Array<T, U> {
757-
// SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]`
758-
unsafe { &mut *array_ref.as_mut_ptr().cast() }
783+
Array::cast_from_core_mut(array_ref)
759784
}
760785
}
761786

tests/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ fn split_ref_mut() {
8585
assert_eq!(suffix.as_slice(), &EXAMPLE_SLICE[4..]);
8686
}
8787

88+
#[test]
89+
fn from_ref() {
90+
let n = 42u64;
91+
let array = Array::from_ref(&n);
92+
assert_eq!(array[0], n);
93+
}
94+
95+
#[test]
96+
fn from_mut() {
97+
let mut n = 42u64;
98+
let array = Array::from_mut(&mut n);
99+
array[0] = 43;
100+
assert_eq!(n, 43);
101+
}
102+
88103
#[test]
89104
fn from_fn() {
90105
let array = Array::<u8, U6>::from_fn(|n| (n + 1) as u8);

0 commit comments

Comments
 (0)