#![doc(html_root_url = "https://docs.rs/slice-of-array/0.2.1")]
#[cfg(test)]
#[macro_use]
extern crate version_sync;
pub mod prelude {
pub use super::SliceFlatExt;
pub use super::SliceNestExt;
pub use super::SliceArrayExt;
}
pub unsafe trait IsSliceomorphic: Sized {
type Element;
const LEN: usize;
}
macro_rules! impl_approved_array {
($($n:tt)+) => {$(
unsafe impl<T> IsSliceomorphic for [T; $n] {
type Element = T;
const LEN: usize = $n;
}
)+};
}
impl_approved_array!{
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31 32 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
256
512
1024
2048
4096
8192
1000
10000
}
fn validate_some_assumptions<V: IsSliceomorphic>() {
use ::std::mem::{align_of, size_of};
assert_eq!(
align_of::<V::Element>(),
align_of::<V>());
assert_eq!(
V::LEN * size_of::<V::Element>(),
size_of::<V>());
}
pub trait SliceFlatExt<T> {
fn flat(&self) -> &[T];
fn flat_mut(&mut self) -> &mut [T];
}
pub trait SliceNestExt<T> {
fn nest<V: IsSliceomorphic<Element=T>>(&self) -> &[V];
fn nest_mut<V: IsSliceomorphic<Element=T>>(&mut self) -> &mut [V];
}
pub trait SliceArrayExt<T> {
fn as_array<V: IsSliceomorphic<Element=T>>(&self) -> &V;
fn as_mut_array<V: IsSliceomorphic<Element=T>>(&mut self) -> &mut V;
fn to_array<V: IsSliceomorphic<Element=T>>(&self) -> V where V: Clone
{ self.as_array::<V>().clone() }
}
impl<V: IsSliceomorphic> SliceFlatExt<V::Element> for [V] {
fn flat(&self) -> &[V::Element] {
unsafe {
validate_some_assumptions::<V>();
::std::slice::from_raw_parts(
self.as_ptr() as *const _,
self.len() * V::LEN,
)
}
}
fn flat_mut(&mut self) -> &mut [V::Element] {
unsafe {
validate_some_assumptions::<V>();
::std::slice::from_raw_parts_mut(
self.as_mut_ptr() as *mut _,
self.len() * V::LEN,
)
}
}
}
impl<T> SliceNestExt<T> for [T] {
fn nest<V: IsSliceomorphic<Element=T>>(&self) -> &[V] {
validate_some_assumptions::<V>();
assert_eq!(0, self.len() % V::LEN,
"cannot view slice of length {} as &[[_; {}]]",
self.len(), V::LEN);
unsafe { ::std::slice::from_raw_parts(
self.as_ptr() as *const _,
self.len() / V::LEN,
)}
}
fn nest_mut<V: IsSliceomorphic<Element=T>>(&mut self) -> &mut [V] {
validate_some_assumptions::<V>();
assert_eq!(0, self.len() % V::LEN,
"cannot view slice of length {} as &mut [[_; {}]]",
self.len(), V::LEN);
unsafe { ::std::slice::from_raw_parts_mut(
self.as_ptr() as *mut _,
self.len() / V::LEN,
)}
}
}
impl<T> SliceArrayExt<T> for [T] {
fn as_array<V: IsSliceomorphic<Element=T>>(&self) -> &V {
assert_eq!(self.len(), V::LEN,
"cannot view slice of length {} as &[_; {}]",
self.len(), V::LEN);
&self.nest()[0]
}
fn as_mut_array<V: IsSliceomorphic<Element=T>>(&mut self) -> &mut V {
assert_eq!(self.len(), V::LEN,
"cannot view slice of length {} as &mut [_; {}]",
self.len(), V::LEN);
&mut self.nest_mut()[0]
}
}
#[cfg(test)]
mod tests {
pub use super::prelude::*;
#[test]
fn inference_lattice() {
let mut v = vec![(); 9];
{ let _: &[[(); 3]; 3] = v.nest().as_array(); }
{ let _: &[[[(); 3]; 3]] = v.nest().nest(); }
{ let _: &mut [[(); 3]; 3] = v.nest_mut().as_mut_array(); }
{ let _: &mut [[[(); 3]; 3]] = v.nest_mut().nest_mut(); }
{ let _: [[(); 3]; 3] = v.nest().to_array(); }
{ let _: Vec<[(); 3]> = v.nest().to_vec(); }
}
mod failures {
use super::super::*;
#[test]
#[should_panic(expected = "cannot view slice of length 8")]
fn fail_nest_not_multiple() {
let v = vec![(); 8];
let _: &[[(); 3]] = v.nest();
}
#[test]
#[should_panic(expected = "cannot view slice of length 8")]
fn nest_mut_not_multiple() {
let mut v = vec![(); 8];
let _: &mut [[(); 3]] = v.nest_mut();
}
#[test]
#[should_panic(expected = "cannot view slice of length 1")]
fn as_array_too_small() {
let v = vec![(); 1];
let _: &[(); 3] = v.as_array();
}
#[test]
#[should_panic(expected = "cannot view slice of length 6")]
fn as_array_too_large() {
let v = vec![(); 6];
let _: &[(); 3] = v.as_array();
}
#[test]
#[should_panic(expected = "cannot view slice of length 1")]
fn as_mut_array_too_small() {
let mut v = vec![(); 1];
let _: &mut [(); 3] = v.as_mut_array();
}
#[test]
#[should_panic(expected = "cannot view slice of length 6")]
fn as_mut_array_too_large() {
let mut v = vec![(); 6];
let _: &mut [(); 3] = v.as_mut_array();
}
}
mod dox {
#[test]
fn test_readme_version() {
assert_markdown_deps_updated!("README.md");
}
#[test]
fn test_html_root_url() {
assert_html_root_url_updated!("lib.rs");
}
}
}