shootout-reverse-complement: reimplement TwoSideIter using pointers
This commit is contained in:
@@ -96,9 +96,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reverse complement, as
|
// reverse complement, as
|
||||||
// seq.reverse(); for c in seq.iter_mut() {*c = complements[*c]}
|
// seq.reverse(); for c in seq.iter_mut() { *c = complements[*c] }
|
||||||
// but faster:
|
// but faster:
|
||||||
for (front, back) in TwoSideIterator::new(seq) {
|
for (front, back) in two_side_iter(seq) {
|
||||||
let tmp = complements[*front as uint];
|
let tmp = complements[*front as uint];
|
||||||
*front = complements[*back as uint];
|
*front = complements[*back as uint];
|
||||||
*back = tmp;
|
*back = tmp;
|
||||||
@@ -112,30 +112,39 @@ fn main() {
|
|||||||
stdout().write(data.as_slice()).unwrap();
|
stdout().write(data.as_slice()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TwoSideIterator<'a, T: 'a> {
|
pub struct TwoSideIter<'a, T: 'a> {
|
||||||
last: uint,
|
first: *mut T,
|
||||||
nb: uint,
|
last: *mut T,
|
||||||
cur: uint,
|
marker: std::kinds::marker::ContravariantLifetime<'a>,
|
||||||
slice: &'a mut [T]
|
marker2: std::kinds::marker::NoCopy
|
||||||
}
|
}
|
||||||
impl<'a, T> TwoSideIterator<'a, T> {
|
|
||||||
pub fn new(s: &'a mut [T]) -> TwoSideIterator<'a, T> {
|
pub fn two_side_iter<'a, T>(slice: &'a mut [T]) -> TwoSideIter<'a, T> {
|
||||||
TwoSideIterator {
|
let len = slice.len();
|
||||||
last: s.len() - 1,
|
let first = slice.as_mut_ptr();
|
||||||
nb: s.len() / 2,
|
let last = if len == 0 {
|
||||||
cur: 0,
|
first
|
||||||
slice: s
|
} else {
|
||||||
|
unsafe { first.offset(len as int - 1) }
|
||||||
|
};
|
||||||
|
|
||||||
|
TwoSideIter {
|
||||||
|
first: first,
|
||||||
|
last: last,
|
||||||
|
marker: std::kinds::marker::ContravariantLifetime,
|
||||||
|
marker2: std::kinds::marker::NoCopy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIter<'a, T> {
|
||||||
|
fn next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
|
||||||
|
if self.first < self.last {
|
||||||
|
let result = unsafe { (&mut *self.first, &mut *self.last) };
|
||||||
|
self.first = unsafe { self.first.offset(1) };
|
||||||
|
self.last = unsafe { self.last.offset(-1) };
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIterator<'a, T> {
|
|
||||||
fn next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
|
|
||||||
if self.cur >= self.nb { return None; }
|
|
||||||
let res = unsafe {
|
|
||||||
(std::mem::transmute(self.slice.unsafe_mut(self.cur)),
|
|
||||||
std::mem::transmute(self.slice.unsafe_mut(self.last - self.cur)))
|
|
||||||
};
|
|
||||||
self.cur += 1;
|
|
||||||
Some(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user