diff options
| author | Nikolai Vazquez <nvazquez1297@gmail.com> | 2017-09-21 16:35:23 -0400 |
|---|---|---|
| committer | Nikolai Vazquez <nvazquez1297@gmail.com> | 2017-09-21 16:35:23 -0400 |
| commit | 13221770a30d4bd56df9e8db6dc7fd95da56f8fc (patch) | |
| tree | 0fd1f8eb232aa4b55204f7c3213c598db96a7914 | |
| parent | 1b55d19479eabcb5d6cbda651187c7004aa28f7f (diff) | |
| download | rust-13221770a30d4bd56df9e8db6dc7fd95da56f8fc.tar.gz rust-13221770a30d4bd56df9e8db6dc7fd95da56f8fc.zip | |
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.
| -rw-r--r-- | src/libcore/array.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 6a7926fecde..5f222e249ea 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -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) { |
