Simplify size_hint to Option<usize>

This commit is contained in:
David Tolnay 2017-04-14 13:27:42 -07:00
parent 637332de2d
commit 0c5db90de8
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
5 changed files with 78 additions and 53 deletions

View File

@ -16,6 +16,9 @@ use de::MapAccess;
use de::from_primitive::FromPrimitive; use de::from_primitive::FromPrimitive;
#[cfg(any(feature = "std", feature = "collections"))]
use private::de::size_hint;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct UnitVisitor; struct UnitVisitor;
@ -344,7 +347,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let len = cmp::min(seq.size_hint().0, 4096); let len = size_hint::cautious(seq.size_hint());
let mut values = Vec::with_capacity(len); let mut values = Vec::with_capacity(len);
while let Some(value) = try!(seq.next_element()) { while let Some(value) = try!(seq.next_element()) {
@ -557,16 +560,16 @@ macro_rules! seq_impl {
seq_impl!( seq_impl!(
BinaryHeap<T>, BinaryHeap<T>,
BinaryHeapVisitor<T: Ord>, BinaryHeapVisitor<T: Ord>,
visitor, seq,
BinaryHeap::new(), BinaryHeap::new(),
BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)), BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
BinaryHeap::push); BinaryHeap::push);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
BTreeSet<T>, BTreeSet<T>,
BTreeSetVisitor<T: Eq + Ord>, BTreeSetVisitor<T: Eq + Ord>,
visitor, seq,
BTreeSet::new(), BTreeSet::new(),
BTreeSet::new(), BTreeSet::new(),
BTreeSet::insert); BTreeSet::insert);
@ -575,7 +578,7 @@ seq_impl!(
seq_impl!( seq_impl!(
LinkedList<T>, LinkedList<T>,
LinkedListVisitor, LinkedListVisitor,
visitor, seq,
LinkedList::new(), LinkedList::new(),
LinkedList::new(), LinkedList::new(),
LinkedList::push_back); LinkedList::push_back);
@ -585,27 +588,27 @@ seq_impl!(
HashSet<T, S>, HashSet<T, S>,
HashSetVisitor<T: Eq + Hash, HashSetVisitor<T: Eq + Hash,
S: BuildHasher + Default>, S: BuildHasher + Default>,
visitor, seq,
HashSet::with_hasher(S::default()), HashSet::with_hasher(S::default()),
HashSet::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default()), HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
HashSet::insert); HashSet::insert);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
Vec<T>, Vec<T>,
VecVisitor, VecVisitor,
visitor, seq,
Vec::new(), Vec::new(),
Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)), Vec::with_capacity(size_hint::cautious(seq.size_hint())),
Vec::push); Vec::push);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
VecDeque<T>, VecDeque<T>,
VecDequeVisitor, VecDequeVisitor,
visitor, seq,
VecDeque::new(), VecDeque::new(),
VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)), VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
VecDeque::push_back); VecDeque::push_back);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -865,7 +868,7 @@ macro_rules! map_impl {
map_impl!( map_impl!(
BTreeMap<K, V>, BTreeMap<K, V>,
BTreeMapVisitor<K: Ord>, BTreeMapVisitor<K: Ord>,
visitor, map,
BTreeMap::new(), BTreeMap::new(),
BTreeMap::new()); BTreeMap::new());
@ -874,9 +877,9 @@ map_impl!(
HashMap<K, V, S>, HashMap<K, V, S>,
HashMapVisitor<K: Eq + Hash, HashMapVisitor<K: Eq + Hash,
S: BuildHasher + Default>, S: BuildHasher + Default>,
visitor, map,
HashMap::with_hasher(S::default()), HashMap::with_hasher(S::default()),
HashMap::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default())); HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -1376,10 +1376,10 @@ pub trait SeqAccess<'de> {
self.next_element_seed(PhantomData) self.next_element_seed(PhantomData)
} }
/// Return the lower and upper bound of items remaining in the sequence. /// Returns the number of elements remaining in the sequence, if known.
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
(0, None) None
} }
} }
@ -1406,7 +1406,7 @@ where
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
(**self).size_hint() (**self).size_hint()
} }
} }
@ -1504,10 +1504,10 @@ pub trait MapAccess<'de> {
self.next_entry_seed(PhantomData, PhantomData) self.next_entry_seed(PhantomData, PhantomData)
} }
/// Return the lower and upper bound of items remaining in the sequence. /// Returns the number of entries remaining in the map, if known.
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
(0, None) None
} }
} }
@ -1572,7 +1572,7 @@ where
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
(**self).size_hint() (**self).size_hint()
} }
} }

View File

@ -11,6 +11,7 @@
use lib::*; use lib::*;
use de::{self, IntoDeserializer, Expected, SeqAccess}; use de::{self, IntoDeserializer, Expected, SeqAccess};
use private::de::size_hint;
use self::private::{First, Second}; use self::private::{First, Second};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -545,8 +546,8 @@ where
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -799,8 +800,8 @@ where
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -827,8 +828,8 @@ where
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -910,7 +911,7 @@ where
if pair_visitor.1.is_none() { if pair_visitor.1.is_none() {
Ok(pair) Ok(pair)
} else { } else {
let remaining = pair_visitor.size_hint().0; let remaining = pair_visitor.size_hint().unwrap();
// First argument is the number of elements in the data, second // First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize. // argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining))) Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining)))
@ -954,15 +955,14 @@ where
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
let len = if self.0.is_some() { if self.0.is_some() {
2 Some(2)
} else if self.1.is_some() { } else if self.1.is_some() {
1 Some(1)
} else { } else {
0 Some(0)
}; }
(len, Some(len))
} }
} }

View File

@ -187,6 +187,29 @@ where
deserializer.deserialize_str(CowBytesVisitor) deserializer.deserialize_str(CowBytesVisitor)
} }
pub mod size_hint {
use lib::*;
pub fn from_bounds<I>(iter: &I) -> Option<usize>
where I: Iterator
{
helper(iter.size_hint())
}
pub fn cautious(hint: Option<usize>) -> usize {
cmp::min(hint.unwrap_or(0), 4096)
}
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
match bounds {
(lower, Some(upper)) if lower == upper => {
Some(upper)
}
_ => None,
}
}
}
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
mod content { mod content {
// This module is private and nothing here should be used outside of // This module is private and nothing here should be used outside of
@ -203,6 +226,7 @@ mod content {
use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, MapAccess, use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, MapAccess,
EnumAccess, Unexpected}; EnumAccess, Unexpected};
use super::size_hint;
/// Used from generated code to buffer the contents of the Deserializer when /// Used from generated code to buffer the contents of the Deserializer when
/// deserializing untagged enums and internally tagged enums. /// deserializing untagged enums and internally tagged enums.
@ -428,7 +452,7 @@ mod content {
where where
V: SeqAccess<'de>, V: SeqAccess<'de>,
{ {
let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
while let Some(e) = try!(visitor.next_element()) { while let Some(e) = try!(visitor.next_element()) {
vec.push(e); vec.push(e);
} }
@ -439,7 +463,7 @@ mod content {
where where
V: MapAccess<'de>, V: MapAccess<'de>,
{ {
let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
while let Some(kv) = try!(visitor.next_entry()) { while let Some(kv) = try!(visitor.next_entry()) {
vec.push(kv); vec.push(kv);
} }
@ -764,7 +788,7 @@ mod content {
V: MapAccess<'de>, V: MapAccess<'de>,
{ {
let mut tag = None; let mut tag = None;
let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
while let Some(k) = while let Some(k) =
try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
match k { match k {
@ -1153,8 +1177,8 @@ mod content {
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -1209,8 +1233,8 @@ mod content {
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -1546,8 +1570,8 @@ mod content {
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }
@ -1603,8 +1627,8 @@ mod content {
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
self.iter.size_hint() size_hint::from_bounds(&self.iter)
} }
} }

View File

@ -404,9 +404,8 @@ impl<'de, 'a> SeqAccess<'de> for DeserializerSeqVisitor<'a, 'de> {
seed.deserialize(&mut *self.de).map(Some) seed.deserialize(&mut *self.de).map(Some)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
let len = self.len.unwrap_or(0); self.len
(len, self.len)
} }
} }
@ -439,9 +438,8 @@ impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> {
seed.deserialize(&mut *self.de) seed.deserialize(&mut *self.de)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> Option<usize> {
let len = self.len.unwrap_or(0); self.len
(len, self.len)
} }
} }