Skip to content

Commit 3b93934

Browse files
committed
Added set_size_hint method
1 parent 70988ff commit 3b93934

File tree

2 files changed

+87
-6
lines changed

2 files changed

+87
-6
lines changed

src/adaptors/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,3 +1276,49 @@ where
12761276
}
12771277
}
12781278
}
1279+
1280+
/// An iterator adaptor that applies the given `size_hint` to an iterator.
1281+
///
1282+
/// See [`.set_size_hint()`](../trait.Itertools.html#method.set_size_hint.html)
1283+
/// for more information.
1284+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1285+
pub struct SetSizeHint<I> {
1286+
iter: I,
1287+
size_hint: (usize, Option<usize>),
1288+
}
1289+
1290+
/// Create a new `SetSizeHint` iterator adapter
1291+
pub fn set_size_hint<I>(iter: I, min: usize, max: Option<usize>) -> SetSizeHint<I> {
1292+
SetSizeHint { iter, size_hint: (min, max) }
1293+
}
1294+
1295+
impl<I> Iterator for SetSizeHint<I>
1296+
where
1297+
I: Iterator,
1298+
{
1299+
type Item = I::Item;
1300+
1301+
#[inline(always)]
1302+
fn next(&mut self) -> Option<Self::Item> {
1303+
self.iter.next()
1304+
}
1305+
1306+
fn size_hint(&self) -> (usize, Option<usize>) {
1307+
self.size_hint
1308+
}
1309+
}
1310+
1311+
impl<I> ExactSizeIterator for SetSizeHint<I>
1312+
where
1313+
I: ExactSizeIterator,
1314+
{ }
1315+
1316+
impl<I> DoubleEndedIterator for SetSizeHint<I>
1317+
where
1318+
I: DoubleEndedIterator,
1319+
{
1320+
#[inline(always)]
1321+
fn next_back(&mut self) -> Option<Self::Item> {
1322+
self.iter.next_back()
1323+
}
1324+
}

src/lib.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,23 @@ pub use std::iter as __std_iter;
7878
/// The concrete iterator types.
7979
pub mod structs {
8080
pub use adaptors::{
81+
Batching,
82+
Coalesce,
8183
Dedup,
8284
Interleave,
8385
InterleaveShortest,
84-
Product,
85-
PutBack,
86-
Batching,
8786
MapInto,
8887
MapResults,
8988
Merge,
9089
MergeBy,
90+
Positions,
91+
Product,
92+
PutBack,
93+
SetSizeHint,
9194
TakeWhileRef,
92-
WhileSome,
93-
Coalesce,
9495
TupleCombinations,
95-
Positions,
9696
Update,
97+
WhileSome,
9798
};
9899
#[allow(deprecated)]
99100
pub use adaptors::Step;
@@ -1902,6 +1903,40 @@ pub trait Itertools : Iterator {
19021903
v.into_iter()
19031904
}
19041905

1906+
/// Explicitly provide a size hint for an iterator.
1907+
///
1908+
/// This can be useful in situations where the size hint cannot be deduced
1909+
/// automatically, but where the programmer knows the bounds on the number
1910+
/// of elements.
1911+
///
1912+
/// ```
1913+
/// use itertools::{self, Itertools};
1914+
///
1915+
/// let data = vec![1, 2, 6, 7, 2];
1916+
///
1917+
/// let result: Vec<i32> = data.iter()
1918+
/// // The `FlatMap` adapter is not able to deduce the size hint itself
1919+
/// // so `size_hint()` would return `(0, None)`.
1920+
/// .flat_map(|&x| {
1921+
/// let repeats = if x % 2 == 0 { 1 } else { 3 };
1922+
/// itertools::repeat_n(x, repeats)
1923+
/// })
1924+
/// // But we know the bounds on the max and min number of items in the
1925+
/// // resulting iterator, so we can provide that information:
1926+
/// .set_size_hint(data.len(), Some(3 * data.len()))
1927+
/// // The `Vec` should not excessively re-allocate, while collecting
1928+
/// // since it now knows the minimum and maximum number of items.
1929+
/// .collect();
1930+
///
1931+
/// assert_eq!(result, vec![1, 1, 1, 2, 6, 7, 7, 7, 2]);
1932+
/// ```
1933+
///
1934+
fn set_size_hint(self, min: usize, max: Option<usize>) -> SetSizeHint<Self>
1935+
where Self: Sized,
1936+
{
1937+
adaptors::set_size_hint(self, min, max)
1938+
}
1939+
19051940
/// Collect all iterator elements into one of two
19061941
/// partitions. Unlike `Iterator::partition`, each partition may
19071942
/// have a distinct type.

0 commit comments

Comments
 (0)