@@ -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+
634668pub 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
702736macro_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
728762impl < 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