Skip to content

Instantly share code, notes, and snippets.

@XMPPwocky
Created January 8, 2015 18:01
Show Gist options
  • Save XMPPwocky/750f911d9ce2171d3b6e to your computer and use it in GitHub Desktop.
Save XMPPwocky/750f911d9ce2171d3b6e to your computer and use it in GitHub Desktop.
use std::ops::{Index, IndexMut};
macro_rules! fastidx_arr(
($contents: expr) => (
unsafe {
FastIdxArr::new($contents, || ())
}
)
);
pub struct FastIdxArr<T, Phantom: Fn() -> ()> {
contents: Box<[T]>
}
impl<T, Phantom: Fn() -> ()> FastIdxArr<T, Phantom> {
pub unsafe fn new(contents: Box<[T]>, _: Phantom) -> FastIdxArr<T, Phantom> {
FastIdxArr {
contents: contents
}
}
pub fn fast_index(&self, idx: uint) -> Result<FastArrIdx<T, Phantom>, ()> {
if idx < self.contents.len() {
Ok(FastArrIdx { idx: idx })
} else {
Err(())
}
}
}
pub struct FastArrIdx<T, Phantom> {
idx: uint
}
impl<T, Phantom> Index<FastArrIdx<T, Phantom>> for FastIdxArr<T, Phantom> {
type Output = T;
fn index<'a>(&'a self, index: &FastArrIdx<T, Phantom>) -> &'a T {
unsafe {
self.contents.get_unchecked(index.idx)
}
}
}
impl<T, Phantom> IndexMut<FastArrIdx<T, Phantom>> for FastIdxArr<T, Phantom> {
type Output = T;
fn index_mut<'a>(&'a mut self, index: &FastArrIdx<T, Phantom>) -> &'a mut T {
unsafe {
self.contents.get_unchecked_mut(index.idx)
}
}
}
#[test]
fn simple() {
let arr = fastidx_arr!(vec![1u32, 2, 3].into_boxed_slice());
let idx = arr.fast_index(1).unwrap();
assert_eq!(arr[idx], 2);
}
#[test]
#[should_fail]
fn out_of_bounds() {
let arr = fastidx_arr!(vec![1u32, 2, 3].into_boxed_slice());
arr.fast_index(3).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment