Skip to content

Commit 1a6f1eb

Browse files
committed
shootout-reverse-complement: reimplement TwoSideIter using pointers
1 parent b8786a5 commit 1a6f1eb

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

src/test/bench/shootout-reverse-complement.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ fn main() {
9696
}
9797

9898
// reverse complement, as
99-
// seq.reverse(); for c in seq.iter_mut() {*c = complements[*c]}
99+
// seq.reverse(); for c in seq.iter_mut() { *c = complements[*c] }
100100
// but faster:
101-
for (front, back) in TwoSideIterator::new(seq) {
101+
for (front, back) in two_side_iter(seq) {
102102
let tmp = complements[*front as uint];
103103
*front = complements[*back as uint];
104104
*back = tmp;
@@ -112,30 +112,39 @@ fn main() {
112112
stdout().write(data.as_slice()).unwrap();
113113
}
114114

115-
pub struct TwoSideIterator<'a, T: 'a> {
116-
last: uint,
117-
nb: uint,
118-
cur: uint,
119-
slice: &'a mut [T]
115+
pub struct TwoSideIter<'a, T: 'a> {
116+
first: *mut T,
117+
last: *mut T,
118+
marker: std::kinds::marker::ContravariantLifetime<'a>,
119+
marker2: std::kinds::marker::NoCopy
120120
}
121-
impl<'a, T> TwoSideIterator<'a, T> {
122-
pub fn new(s: &'a mut [T]) -> TwoSideIterator<'a, T> {
123-
TwoSideIterator {
124-
last: s.len() - 1,
125-
nb: s.len() / 2,
126-
cur: 0,
127-
slice: s
128-
}
121+
122+
pub fn two_side_iter<'a, T>(slice: &'a mut [T]) -> TwoSideIter<'a, T> {
123+
let len = slice.len();
124+
let first = slice.as_mut_ptr();
125+
let last = if len == 0 {
126+
first
127+
} else {
128+
unsafe { first.offset(len as int - 1) }
129+
};
130+
131+
TwoSideIter {
132+
first: first,
133+
last: last,
134+
marker: std::kinds::marker::ContravariantLifetime,
135+
marker2: std::kinds::marker::NoCopy
129136
}
130137
}
131-
impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIterator<'a, T> {
138+
139+
impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIter<'a, T> {
132140
fn next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
133-
if self.cur >= self.nb { return None; }
134-
let res = unsafe {
135-
(std::mem::transmute(self.slice.unsafe_mut(self.cur)),
136-
std::mem::transmute(self.slice.unsafe_mut(self.last - self.cur)))
137-
};
138-
self.cur += 1;
139-
Some(res)
141+
if self.first < self.last {
142+
let result = unsafe { (&mut *self.first, &mut *self.last) };
143+
self.first = unsafe { self.first.offset(1) };
144+
self.last = unsafe { self.last.offset(-1) };
145+
Some(result)
146+
} else {
147+
None
148+
}
140149
}
141150
}

0 commit comments

Comments
 (0)