Skip to content

Commit e98510e

Browse files
committed
Add a new value iterator that yields values rather than Ptrs
Cloning Ptr isn't cheap, so this is a nice alternative Optimize a few rules to use this new iterator
1 parent 01d3f76 commit e98510e

12 files changed

Lines changed: 691 additions & 865 deletions

File tree

libcc2rs/src/rc.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,40 @@ impl<T> Iterator for Ptr<T> {
631631
}
632632
}
633633

634+
// Ptr iterator that yields values instead of pointers.
635+
// It's more efficient and it's useful to implement idiomatic iterator patterns
636+
pub struct PtrValueIter<T> {
637+
ptr: Ptr<T>,
638+
n: usize,
639+
}
640+
641+
impl<T> PtrValueIter<T> {
642+
pub fn new(ptr: Ptr<T>, n: usize) -> Self {
643+
Self { ptr, n }
644+
}
645+
}
646+
647+
impl<T: Clone + ByteRepr> Iterator for PtrValueIter<T> {
648+
type Item = T;
649+
650+
fn next(&mut self) -> Option<Self::Item> {
651+
if self.n > 0 {
652+
let value = self.ptr.read();
653+
self.ptr += 1;
654+
self.n -= 1;
655+
Some(value)
656+
} else {
657+
None
658+
}
659+
}
660+
661+
fn size_hint(&self) -> (usize, Option<usize>) {
662+
(self.n, Some(self.n))
663+
}
664+
}
665+
666+
impl<T: Clone + ByteRepr> ExactSizeIterator for PtrValueIter<T> {}
667+
634668
pub struct StringIterator<T> {
635669
ptr: Ptr<T>,
636670
}
@@ -697,7 +731,7 @@ macro_rules! impl_ptr_add_sub_assign {
697731
}
698732
)+ }
699733
}
700-
impl_ptr_add_sub_assign!(i32, u32, u64, isize);
734+
impl_ptr_add_sub_assign!(i32, u32, u64, isize, usize);
701735

702736
macro_rules! impl_ptr_add_sub {
703737
($($rhs:ty),+) => { $(
@@ -723,7 +757,7 @@ macro_rules! impl_ptr_add_sub {
723757
}
724758
)+ }
725759
}
726-
impl_ptr_add_sub!(i32, u32, u64, isize);
760+
impl_ptr_add_sub!(i32, u32, u64, isize, usize);
727761

728762
impl<T> PostfixInc for Ptr<T> {
729763
#[inline]
@@ -1005,7 +1039,7 @@ impl Ptr<u8> {
10051039
}
10061040

10071041
pub fn to_rust_string(&self) -> String {
1008-
let bytes: Vec<u8> = self.to_string_iterator().map(|p| p.read()).collect();
1042+
let bytes: Vec<u8> = self.to_c_string_iterator().collect();
10091043
String::from_utf8_lossy(&bytes).into_owned()
10101044
}
10111045
}

0 commit comments

Comments
 (0)