@@ -26,6 +26,7 @@ use option::{Option, Some, None};
26
26
use ops:: { Add , Mul } ;
27
27
use cmp:: Ord ;
28
28
use clone:: Clone ;
29
+ use uint;
29
30
30
31
/// Conversion from an `Iterator`
31
32
pub trait FromIterator < A , T : Iterator < A > > {
@@ -688,9 +689,14 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<A, T, U> {
688
689
let ( a_lower, a_upper) = self . a . size_hint ( ) ;
689
690
let ( b_lower, b_upper) = self . b . size_hint ( ) ;
690
691
691
- let lower = a_lower + b_lower;
692
+ let lower = if uint:: max_value - a_lower < b_lower {
693
+ uint:: max_value
694
+ } else {
695
+ a_lower + b_lower
696
+ } ;
692
697
693
698
let upper = match ( a_upper, b_upper) {
699
+ ( Some ( x) , Some ( y) ) if uint:: max_value - x < y => Some ( uint:: max_value) ,
694
700
( Some ( x) , Some ( y) ) => Some ( x + y) ,
695
701
_ => None
696
702
} ;
@@ -714,6 +720,23 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<A, T
714
720
_ => None
715
721
}
716
722
}
723
+
724
+ #[ inline]
725
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
726
+ let ( a_lower, a_upper) = self . a . size_hint ( ) ;
727
+ let ( b_lower, b_upper) = self . b . size_hint ( ) ;
728
+
729
+ let lower = cmp:: min ( a_lower, b_lower) ;
730
+
731
+ let upper = match ( a_upper, b_upper) {
732
+ ( Some ( x) , Some ( y) ) => Some ( cmp:: min ( x, y) ) ,
733
+ ( Some ( x) , None ) => Some ( x) ,
734
+ ( None , Some ( y) ) => Some ( y) ,
735
+ ( None , None ) => None
736
+ } ;
737
+
738
+ ( lower, upper)
739
+ }
717
740
}
718
741
719
742
/// An iterator which maps the values of `iter` with `f`
@@ -807,6 +830,11 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<A, T> {
807
830
_ => None
808
831
}
809
832
}
833
+
834
+ #[ inline]
835
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
836
+ self . iter . size_hint ( )
837
+ }
810
838
}
811
839
812
840
/// An iterator which rejects elements while `predicate` is true
@@ -839,6 +867,12 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhileIterator<'self, A, T> {
839
867
}
840
868
}
841
869
}
870
+
871
+ #[ inline]
872
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
873
+ let ( _, upper) = self . iter . size_hint ( ) ;
874
+ ( 0 , upper) // can't know a lower bound, due to the predicate
875
+ }
842
876
}
843
877
844
878
/// An iterator which only accepts elements while `predicate` is true
@@ -867,6 +901,12 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
867
901
}
868
902
}
869
903
}
904
+
905
+ #[ inline]
906
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
907
+ let ( _, upper) = self . iter . size_hint ( ) ;
908
+ ( 0 , upper) // can't know a lower bound, due to the predicate
909
+ }
870
910
}
871
911
872
912
/// An iterator which skips over `n` elements of `iter`.
@@ -900,6 +940,21 @@ impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<A, T> {
900
940
next
901
941
}
902
942
}
943
+
944
+ #[ inline]
945
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
946
+ let ( lower, upper) = self . iter. size_hint( ) ;
947
+
948
+ let lower = if lower >= self . n { lower - self . n } else { 0 } ;
949
+
950
+ let upper = match upper {
951
+ Some ( x) if x >= self . n => Some ( x - self . n) ,
952
+ Some ( _) => Some ( 0 ) ,
953
+ None => None
954
+ } ;
955
+
956
+ ( lower, upper)
957
+ }
903
958
}
904
959
905
960
/// An iterator which only iterates over the first `n` iterations of `iter`.
@@ -920,6 +975,20 @@ impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<A, T> {
920
975
None
921
976
}
922
977
}
978
+
979
+ #[ inline]
980
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
981
+ let ( lower, upper) = self . iter. size_hint( ) ;
982
+
983
+ let lower = cmp:: min( lower, self . n) ;
984
+
985
+ let upper = match upper {
986
+ Some ( x) if x < self . n => Some ( x ) ,
987
+ _ => Some ( self . n)
988
+ } ;
989
+
990
+ ( lower , upper )
991
+ }
923
992
}
924
993
925
994
/// An iterator to maintain state while iterating another iterator
@@ -936,6 +1005,12 @@ impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for ScanIterator<'self, A, B,
936
1005
fn next( & mut self ) -> Option < B > {
937
1006
self . iter. next( ) . chain( |a| ( self . f) ( & mut self . state, a) )
938
1007
}
1008
+
1009
+ #[ inline]
1010
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
1011
+ let ( _, upper) = self . iter. size_hint( ) ;
1012
+ ( 0 , upper) // can't know a lower bound, due to the scan function
1013
+ }
939
1014
}
940
1015
941
1016
/// An iterator that maps each element to an iterator,
@@ -1017,6 +1092,11 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
1017
1092
self . state = self . state. add( & self . step) ; // FIXME: #6050
1018
1093
Some ( result)
1019
1094
}
1095
+
1096
+ #[ inline]
1097
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
1098
+ ( uint:: max_value, None ) // Too bad we can't specify an infinite lower bound
1099
+ }
1020
1100
}
1021
1101
1022
1102
#[ cfg( test) ]
@@ -1232,6 +1312,43 @@ mod tests {
1232
1312
assert_eq ! ( v. slice( 0 , 0 ) . iter( ) . transform( |& x| x) . min( ) , None ) ;
1233
1313
}
1234
1314
1315
+ #[ test]
1316
+ fn test_iterator_size_hint ( ) {
1317
+ let c = Counter : : new( 0 , 1 ) ;
1318
+ let v = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
1319
+ let v2 = & [ 10 , 11 , 12 ] ;
1320
+ let vi = v. iter( ) ;
1321
+
1322
+ assert_eq ! ( c. size_hint( ) , ( uint:: max_value, None ) ) ;
1323
+ assert_eq ! ( vi. size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
1324
+
1325
+ assert_eq ! ( c. take_( 5 ) . size_hint( ) , ( 5 , Some ( 5 ) ) ) ;
1326
+ assert_eq ! ( c. skip( 5 ) . size_hint( ) . second( ) , None ) ;
1327
+ assert_eq ! ( c. take_while( |_| false ) . size_hint( ) , ( 0 , None ) ) ;
1328
+ assert_eq ! ( c. skip_while( |_| false ) . size_hint( ) , ( 0 , None ) ) ;
1329
+ assert_eq ! ( c. enumerate( ) . size_hint( ) , ( uint:: max_value, None ) ) ;
1330
+ assert_eq ! ( c. chain_( vi. transform( |& i| i) ) . size_hint( ) , ( uint:: max_value, None ) ) ;
1331
+ assert_eq ! ( c. zip( vi) . size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
1332
+ assert_eq ! ( c. scan( 0 , |_, _| Some ( 0 ) ) . size_hint( ) , ( 0 , None ) ) ;
1333
+ assert_eq ! ( c. filter( |_| false ) . size_hint( ) , ( 0 , None ) ) ;
1334
+ assert_eq ! ( c. transform( |_| 0 ) . size_hint( ) , ( uint:: max_value, None ) ) ;
1335
+ assert_eq ! ( c. filter_map( |_| Some ( 0 ) ) . size_hint( ) , ( 0 , None ) ) ;
1336
+
1337
+ assert_eq ! ( vi. take_( 5 ) . size_hint( ) , ( 5 , Some ( 5 ) ) ) ;
1338
+ assert_eq ! ( vi. take_( 12 ) . size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
1339
+ assert_eq ! ( vi. skip( 3 ) . size_hint( ) , ( 7 , Some ( 7 ) ) ) ;
1340
+ assert_eq ! ( vi. skip( 12 ) . size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1341
+ assert_eq ! ( vi. take_while( |_| false ) . size_hint( ) , ( 0 , Some ( 10 ) ) ) ;
1342
+ assert_eq ! ( vi. skip_while( |_| false ) . size_hint( ) , ( 0 , Some ( 10 ) ) ) ;
1343
+ assert_eq ! ( vi. enumerate( ) . size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
1344
+ assert_eq ! ( vi. chain_( v2. iter( ) ) . size_hint( ) , ( 13 , Some ( 13 ) ) ) ;
1345
+ assert_eq ! ( vi. zip( v2. iter( ) ) . size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
1346
+ assert_eq ! ( vi. scan( 0 , |_, _| Some ( 0 ) ) . size_hint( ) , ( 0 , Some ( 10 ) ) ) ;
1347
+ assert_eq ! ( vi. filter( |_| false ) . size_hint( ) , ( 0 , Some ( 10 ) ) ) ;
1348
+ assert_eq ! ( vi. transform( |i| i+1 ) . size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
1349
+ assert_eq ! ( vi. filter_map( |_| Some ( 0 ) ) . size_hint( ) , ( 0 , Some ( 10 ) ) ) ;
1350
+ }
1351
+
1235
1352
#[ test]
1236
1353
fn test_collect( ) {
1237
1354
let a = ~[ 1 , 2 , 3 , 4 , 5 ] ;
0 commit comments