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;
#[cfg(any(feature = "std", feature = "collections"))]
use private::de::size_hint;
////////////////////////////////////////////////////////////////////////////////
struct UnitVisitor;
@ -344,7 +347,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
where
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);
while let Some(value) = try!(seq.next_element()) {
@ -557,16 +560,16 @@ macro_rules! seq_impl {
seq_impl!(
BinaryHeap<T>,
BinaryHeapVisitor<T: Ord>,
visitor,
seq,
BinaryHeap::new(),
BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
BinaryHeap::push);
#[cfg(any(feature = "std", feature = "collections"))]
seq_impl!(
BTreeSet<T>,
BTreeSetVisitor<T: Eq + Ord>,
visitor,
seq,
BTreeSet::new(),
BTreeSet::new(),
BTreeSet::insert);
@ -575,7 +578,7 @@ seq_impl!(
seq_impl!(
LinkedList<T>,
LinkedListVisitor,
visitor,
seq,
LinkedList::new(),
LinkedList::new(),
LinkedList::push_back);
@ -585,27 +588,27 @@ seq_impl!(
HashSet<T, S>,
HashSetVisitor<T: Eq + Hash,
S: BuildHasher + Default>,
visitor,
seq,
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);
#[cfg(any(feature = "std", feature = "collections"))]
seq_impl!(
Vec<T>,
VecVisitor,
visitor,
seq,
Vec::new(),
Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
Vec::push);
#[cfg(any(feature = "std", feature = "collections"))]
seq_impl!(
VecDeque<T>,
VecDequeVisitor,
visitor,
seq,
VecDeque::new(),
VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
VecDeque::push_back);
////////////////////////////////////////////////////////////////////////////////
@ -865,7 +868,7 @@ macro_rules! map_impl {
map_impl!(
BTreeMap<K, V>,
BTreeMapVisitor<K: Ord>,
visitor,
map,
BTreeMap::new(),
BTreeMap::new());
@ -874,9 +877,9 @@ map_impl!(
HashMap<K, V, S>,
HashMapVisitor<K: Eq + Hash,
S: BuildHasher + Default>,
visitor,
map,
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)
}
/// Return the lower and upper bound of items remaining in the sequence.
/// Returns the number of elements remaining in the sequence, if known.
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
fn size_hint(&self) -> Option<usize> {
None
}
}
@ -1406,7 +1406,7 @@ where
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
fn size_hint(&self) -> Option<usize> {
(**self).size_hint()
}
}
@ -1504,10 +1504,10 @@ pub trait MapAccess<'de> {
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]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
fn size_hint(&self) -> Option<usize> {
None
}
}
@ -1572,7 +1572,7 @@ where
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
fn size_hint(&self) -> Option<usize> {
(**self).size_hint()
}
}

View File

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

View File

@ -187,6 +187,29 @@ where
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"))]
mod content {
// 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,
EnumAccess, Unexpected};
use super::size_hint;
/// Used from generated code to buffer the contents of the Deserializer when
/// deserializing untagged enums and internally tagged enums.
@ -428,7 +452,7 @@ mod content {
where
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()) {
vec.push(e);
}
@ -439,7 +463,7 @@ mod content {
where
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()) {
vec.push(kv);
}
@ -764,7 +788,7 @@ mod content {
V: MapAccess<'de>,
{
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) =
try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
match k {
@ -1153,8 +1177,8 @@ mod content {
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
fn size_hint(&self) -> Option<usize> {
size_hint::from_bounds(&self.iter)
}
}
@ -1209,8 +1233,8 @@ mod content {
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
fn size_hint(&self) -> Option<usize> {
size_hint::from_bounds(&self.iter)
}
}
@ -1546,8 +1570,8 @@ mod content {
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
fn size_hint(&self) -> Option<usize> {
size_hint::from_bounds(&self.iter)
}
}
@ -1603,8 +1627,8 @@ mod content {
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
fn size_hint(&self) -> Option<usize> {
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)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len.unwrap_or(0);
(len, self.len)
fn size_hint(&self) -> Option<usize> {
self.len
}
}
@ -439,9 +438,8 @@ impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> {
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len.unwrap_or(0);
(len, self.len)
fn size_hint(&self) -> Option<usize> {
self.len
}
}