Implement TryFrom for array reference types
There are many cases where a buffer with a static compile-time size is preferred over a slice with a dynamic size. This allows for performing a checked conversion from &[T] to &[T; N]. This may also lead to compile-time optimizations involving [T; N] such as loop unrolling.
This commit is contained in:
parent
1b55d19479
commit
13221770a3
1 changed files with 34 additions and 0 deletions
|
@ -21,6 +21,7 @@
|
|||
|
||||
use borrow::{Borrow, BorrowMut};
|
||||
use cmp::Ordering;
|
||||
use convert::TryFrom;
|
||||
use fmt;
|
||||
use hash::{Hash, self};
|
||||
use marker::Unsize;
|
||||
|
@ -57,6 +58,11 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
|
|||
}
|
||||
}
|
||||
|
||||
/// The error type returned when a conversion from a slice to an array fails.
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TryFromSliceError(());
|
||||
|
||||
macro_rules! __impl_slice_eq1 {
|
||||
($Lhs: ty, $Rhs: ty) => {
|
||||
__impl_slice_eq1! { $Lhs, $Rhs, Sized }
|
||||
|
@ -123,6 +129,34 @@ macro_rules! array_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
|
||||
type Error = TryFromSliceError;
|
||||
|
||||
fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
|
||||
if slice.len() == $N {
|
||||
let ptr = slice.as_ptr() as *const [T; $N];
|
||||
unsafe { Ok(&*ptr) }
|
||||
} else {
|
||||
Err(TryFromSliceError(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
|
||||
type Error = TryFromSliceError;
|
||||
|
||||
fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
|
||||
if slice.len() == $N {
|
||||
let ptr = slice.as_mut_ptr() as *mut [T; $N];
|
||||
unsafe { Ok(&mut *ptr) }
|
||||
} else {
|
||||
Err(TryFromSliceError(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Hash> Hash for [T; $N] {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
|
|
Loading…
Reference in a new issue