зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1493435 - Update smallvec crate and enable the union feature. r=emilio
We had a mix of 0.6.2 and 0.6.5 (which is the current release), this unifies to the latest version. It also enables the union feature which removes the discriminant, reducing memory usage. This cherry-picks servo/servo#21746.
This commit is contained in:
Родитель
f8161bc611
Коммит
52ad6442dc
|
@ -477,7 +477,7 @@ dependencies = [
|
|||
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -732,7 +732,7 @@ name = "fallible"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"hashglobe 0.1.0",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -863,7 +863,7 @@ dependencies = [
|
|||
"parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.20.0",
|
||||
"servo_arc 0.1.1",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"style 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
]
|
||||
|
@ -1254,7 +1254,7 @@ dependencies = [
|
|||
"selectors 0.20.0",
|
||||
"servo_arc 0.1.1",
|
||||
"smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1598,7 +1598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1945,7 +1945,7 @@ dependencies = [
|
|||
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_arc 0.1.1",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2037,7 +2037,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.3"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2131,7 +2131,7 @@ dependencies = [
|
|||
"selectors 0.20.0",
|
||||
"servo_arc 0.1.1",
|
||||
"smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"style_derive 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2184,7 +2184,7 @@ dependencies = [
|
|||
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.20.0",
|
||||
"size_of_test 0.0.1",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"style 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
]
|
||||
|
@ -2655,7 +2655,7 @@ dependencies = [
|
|||
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.57.2",
|
||||
|
@ -3016,7 +3016,7 @@ dependencies = [
|
|||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
|
||||
"checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c"
|
||||
"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
|
||||
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
|
||||
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
||||
|
|
|
@ -10,7 +10,7 @@ name = "fallible"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
smallvec = "0.6.2"
|
||||
smallvec = { version = "0.6", features = ["std", "union"] }
|
||||
hashglobe = { path = "../hashglobe" }
|
||||
|
||||
# This crate effectively does nothing except if the `known_system_malloc`
|
||||
|
|
|
@ -37,7 +37,7 @@ serde_bytes = { version = "0.10", optional = true }
|
|||
servo_arc = { path = "../servo_arc" }
|
||||
servo_channel = { path = "../channel", optional = true }
|
||||
smallbitvec = "2.1.0"
|
||||
smallvec = "0.6"
|
||||
smallvec = { version = "0.6", features = ["std", "union"] }
|
||||
string_cache = { version = "0.7", optional = true }
|
||||
thin-slice = "0.1.0"
|
||||
time = { version = "0.1.17", optional = true }
|
||||
|
|
|
@ -28,7 +28,7 @@ fxhash = "0.2"
|
|||
phf = "0.7.18"
|
||||
precomputed-hash = "0.1"
|
||||
servo_arc = { version = "0.1", path = "../servo_arc" }
|
||||
smallvec = "0.6.2"
|
||||
smallvec = { version = "0.6", features = ["std", "union"] }
|
||||
thin-slice = "0.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -63,7 +63,7 @@ servo_atoms = {path = "../atoms", optional = true}
|
|||
servo_channel = {path = "../channel", optional = true}
|
||||
servo_config = {path = "../config", optional = true}
|
||||
smallbitvec = "2.1.1"
|
||||
smallvec = "0.6.2"
|
||||
smallvec = { version = "0.6", features = ["std", "union"] }
|
||||
string_cache = { version = "0.7", optional = true }
|
||||
style_derive = {path = "../style_derive"}
|
||||
style_traits = {path = "../style_traits"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{".travis.yml":"1fb562c82e3ba8668667016eb5be043130a943a3e22c2c692dfcefd23bb07028","Cargo.toml":"2f8fa5e2e7894727dab3b256f93c739ee2fdd715cad0ea18b466330325dc6c90","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"1bc64a621160a291c86b8770f3eeaa45a31c31d91c2a071f39981c14fdacb035","benches/bench.rs":"bf8c9a06dad072e14e844daf43895c41d632db183f33fa6de53a43d3677a7375","lib.rs":"dd8993f008a5512d33a74d5e141a4d9d6294baa11174bfeeec2251d731d51957"},"package":"26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"}
|
||||
{"files":{".travis.yml":"106d159f3fbe3ad49ebc631f9707baedf6adb012e5210443919232db5375fa7b","Cargo.toml":"7d0640e384cf1d81593bd049f6bf5b1dcf129db200f4f21b18c06b6bdb5d67a3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"1bc64a621160a291c86b8770f3eeaa45a31c31d91c2a071f39981c14fdacb035","benches/bench.rs":"9dca7122a3dcb2c099e49807e4d3b8f01d9220e2b3db0a54e9901ee74392866f","lib.rs":"513374844e0fc3bc332f5172de3a604acab160e02f576f7d9eaebe64149588a9"},"package":"153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"}
|
|
@ -1,13 +1,16 @@
|
|||
language: rust
|
||||
rust:
|
||||
- 1.20.0
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
script: |
|
||||
cargo build --verbose &&
|
||||
cargo test --verbose &&
|
||||
cargo test --verbose --features serde &&
|
||||
([ $TRAVIS_RUST_VERSION != nightly ] || cargo check --verbose --no-default-features) &&
|
||||
([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --features union) &&
|
||||
([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --all-features) &&
|
||||
([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
|
||||
notifications:
|
||||
webhooks: http://build.servo.org:54856/travis
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
[package]
|
||||
name = "smallvec"
|
||||
version = "0.6.3"
|
||||
version = "0.6.5"
|
||||
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
||||
description = "'Small vector' optimization: store up to a small number of items on the stack"
|
||||
documentation = "http://doc.servo.org/smallvec/"
|
||||
|
|
|
@ -17,6 +17,7 @@ trait Vector<T>: for<'a> From<&'a [T]> + Extend<T> + ExtendFromSlice<T> {
|
|||
fn remove(&mut self, p: usize) -> T;
|
||||
fn insert(&mut self, n: usize, val: T);
|
||||
fn from_elem(val: T, n: usize) -> Self;
|
||||
fn from_elems(val: &[T]) -> Self;
|
||||
}
|
||||
|
||||
impl<T: Copy> Vector<T> for Vec<T> {
|
||||
|
@ -43,6 +44,10 @@ impl<T: Copy> Vector<T> for Vec<T> {
|
|||
fn from_elem(val: T, n: usize) -> Self {
|
||||
vec![val; n]
|
||||
}
|
||||
|
||||
fn from_elems(val: &[T]) -> Self {
|
||||
val.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> Vector<T> for SmallVec<[T; VEC_SIZE]> {
|
||||
|
@ -69,6 +74,10 @@ impl<T: Copy> Vector<T> for SmallVec<[T; VEC_SIZE]> {
|
|||
fn from_elem(val: T, n: usize) -> Self {
|
||||
smallvec![val; n]
|
||||
}
|
||||
|
||||
fn from_elems(val: &[T]) -> Self {
|
||||
SmallVec::from_slice(val)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! make_benches {
|
||||
|
@ -92,6 +101,8 @@ make_benches! {
|
|||
bench_remove_small => gen_remove(VEC_SIZE as _),
|
||||
bench_extend => gen_extend(SPILLED_SIZE as _),
|
||||
bench_extend_small => gen_extend(VEC_SIZE as _),
|
||||
bench_from_iter => gen_from_iter(SPILLED_SIZE as _),
|
||||
bench_from_iter_small => gen_from_iter(VEC_SIZE as _),
|
||||
bench_from_slice => gen_from_slice(SPILLED_SIZE as _),
|
||||
bench_from_slice_small => gen_from_slice(VEC_SIZE as _),
|
||||
bench_extend_from_slice => gen_extend_from_slice(SPILLED_SIZE as _),
|
||||
|
@ -112,6 +123,8 @@ make_benches! {
|
|||
bench_remove_vec_small => gen_remove(VEC_SIZE as _),
|
||||
bench_extend_vec => gen_extend(SPILLED_SIZE as _),
|
||||
bench_extend_vec_small => gen_extend(VEC_SIZE as _),
|
||||
bench_from_iter_vec => gen_from_iter(SPILLED_SIZE as _),
|
||||
bench_from_iter_vec_small => gen_from_iter(VEC_SIZE as _),
|
||||
bench_from_slice_vec => gen_from_slice(SPILLED_SIZE as _),
|
||||
bench_from_slice_vec_small => gen_from_slice(VEC_SIZE as _),
|
||||
bench_extend_from_slice_vec => gen_extend_from_slice(SPILLED_SIZE as _),
|
||||
|
@ -179,7 +192,7 @@ fn gen_extend<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
|||
});
|
||||
}
|
||||
|
||||
fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
fn gen_from_iter<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
let vec = V::from(&v);
|
||||
|
@ -187,6 +200,14 @@ fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
|||
});
|
||||
}
|
||||
|
||||
fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
let vec = V::from_elems(&v);
|
||||
vec
|
||||
});
|
||||
}
|
||||
|
||||
fn gen_extend_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
|
|
|
@ -113,11 +113,20 @@ use std::marker::PhantomData;
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! smallvec {
|
||||
// count helper: transform any expression into 1
|
||||
(@one $x:expr) => (1usize);
|
||||
($elem:expr; $n:expr) => ({
|
||||
SmallVec::from_elem($elem, $n)
|
||||
$crate::SmallVec::from_elem($elem, $n)
|
||||
});
|
||||
($($x:expr),*$(,)*) => ({
|
||||
SmallVec::from_slice(&[$($x),*])
|
||||
let count = 0usize $(+ smallvec!(@one $x))*;
|
||||
let mut vec = $crate::SmallVec::new();
|
||||
if count <= vec.inline_size() {
|
||||
$(vec.push($x);)*
|
||||
vec
|
||||
} else {
|
||||
$crate::SmallVec::from_vec(vec![$($x,)*])
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -231,14 +240,7 @@ impl<'a, T: 'a> Iterator for Drain<'a,T> {
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<T> {
|
||||
match self.iter.next() {
|
||||
None => None,
|
||||
Some(reference) => {
|
||||
unsafe {
|
||||
Some(ptr::read(reference))
|
||||
}
|
||||
}
|
||||
}
|
||||
self.iter.next().map(|reference| unsafe { ptr::read(reference) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -250,14 +252,7 @@ impl<'a, T: 'a> Iterator for Drain<'a,T> {
|
|||
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<T> {
|
||||
match self.iter.next_back() {
|
||||
None => None,
|
||||
Some(reference) => {
|
||||
unsafe {
|
||||
Some(ptr::read(reference))
|
||||
}
|
||||
}
|
||||
}
|
||||
self.iter.next_back().map(|reference| unsafe { ptr::read(reference) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +287,8 @@ impl<A: Array> SmallVecData<A> {
|
|||
SmallVecData { inline }
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn into_inline(self) -> A { self.inline }
|
||||
#[inline]
|
||||
unsafe fn heap(&self) -> (*mut A::Item, usize) {
|
||||
self.heap
|
||||
}
|
||||
|
@ -332,6 +329,13 @@ impl<A: Array> SmallVecData<A> {
|
|||
SmallVecData::Inline(ManuallyDrop::new(inline))
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn into_inline(self) -> A {
|
||||
match self {
|
||||
SmallVecData::Inline(a) => ManuallyDrop::into_inner(a),
|
||||
_ => debug_unreachable!(),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn heap(&self) -> (*mut A::Item, usize) {
|
||||
match *self {
|
||||
SmallVecData::Heap(data) => data,
|
||||
|
@ -476,6 +480,47 @@ impl<A: Array> SmallVec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `SmallVec` on the stack from an `A` without
|
||||
/// copying elements. Also sets the length, which must be less or
|
||||
/// equal to the size of `buf`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use smallvec::SmallVec;
|
||||
///
|
||||
/// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
|
||||
/// let small_vec: SmallVec<_> = SmallVec::from_buf_and_len(buf, 5);
|
||||
///
|
||||
/// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn from_buf_and_len(buf: A, len: usize) -> SmallVec<A> {
|
||||
assert!(len <= A::size());
|
||||
unsafe { SmallVec::from_buf_and_len_unchecked(buf, len) }
|
||||
}
|
||||
|
||||
/// Constructs a new `SmallVec` on the stack from an `A` without
|
||||
/// copying elements. Also sets the length. The user is responsible
|
||||
/// for ensuring that `len <= A::size()`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use smallvec::SmallVec;
|
||||
///
|
||||
/// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
|
||||
/// let small_vec: SmallVec<_> = unsafe {
|
||||
/// SmallVec::from_buf_and_len_unchecked(buf, 5)
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub unsafe fn from_buf_and_len_unchecked(buf: A, len: usize) -> SmallVec<A> {
|
||||
SmallVec {
|
||||
capacity: len,
|
||||
data: SmallVecData::from_inline(buf),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Sets the length of a vector.
|
||||
///
|
||||
/// This will explicitly set the size of the vector, without actually
|
||||
|
@ -565,7 +610,7 @@ impl<A: Array> SmallVec<A> {
|
|||
unsafe {
|
||||
let (_, &mut len, cap) = self.triple_mut();
|
||||
if len == cap {
|
||||
self.grow(cmp::max(cap * 2, 1))
|
||||
self.reserve(1);
|
||||
}
|
||||
let (ptr, len_ptr, _) = self.triple_mut();
|
||||
*len_ptr = len + 1;
|
||||
|
@ -593,15 +638,14 @@ impl<A: Array> SmallVec<A> {
|
|||
pub fn grow(&mut self, new_cap: usize) {
|
||||
unsafe {
|
||||
let (ptr, &mut len, cap) = self.triple_mut();
|
||||
let spilled = self.spilled();
|
||||
let unspilled = !self.spilled();
|
||||
assert!(new_cap >= len);
|
||||
if new_cap <= self.inline_size() {
|
||||
if !spilled {
|
||||
if unspilled {
|
||||
return;
|
||||
}
|
||||
self.data = SmallVecData::from_inline(mem::uninitialized());
|
||||
ptr::copy_nonoverlapping(ptr, self.data.inline_mut().ptr_mut(), len);
|
||||
deallocate(ptr, cap);
|
||||
} else if new_cap != cap {
|
||||
let mut vec = Vec::with_capacity(new_cap);
|
||||
let new_alloc = vec.as_mut_ptr();
|
||||
|
@ -609,10 +653,11 @@ impl<A: Array> SmallVec<A> {
|
|||
ptr::copy_nonoverlapping(ptr, new_alloc, len);
|
||||
self.data = SmallVecData::from_heap(new_alloc, len);
|
||||
self.capacity = new_cap;
|
||||
if spilled {
|
||||
deallocate(ptr, cap);
|
||||
if unspilled {
|
||||
return;
|
||||
}
|
||||
}
|
||||
deallocate(ptr, cap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,6 +668,7 @@ impl<A: Array> SmallVec<A> {
|
|||
/// If the new capacity would overflow `usize` then it will be set to `usize::max_value()`
|
||||
/// instead. (This means that inserting `additional` new elements is not guaranteed to be
|
||||
/// possible after calling this function.)
|
||||
#[inline]
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
// prefer triple_mut() even if triple() would work
|
||||
// so that the optimizer removes duplicated calls to it
|
||||
|
@ -816,6 +862,22 @@ impl<A: Array> SmallVec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert the SmallVec into an `A` if possible. Otherwise return `Err(Self)`.
|
||||
///
|
||||
/// This method returns `Err(Self)` if the SmallVec is too short (and the `A` contains uninitialized elements),
|
||||
/// or if the SmallVec is too long (and all the elements were spilled to the heap).
|
||||
pub fn into_inner(self) -> Result<A, Self> {
|
||||
if self.spilled() || self.len() != A::size() {
|
||||
Err(self)
|
||||
} else {
|
||||
unsafe {
|
||||
let data = ptr::read(&self.data);
|
||||
mem::forget(self);
|
||||
Ok(data.into_inline())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
|
||||
|
@ -884,9 +946,25 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
|
|||
///
|
||||
/// For slices of `Copy` types, this is more efficient than `SmallVec::from(slice)`.
|
||||
pub fn from_slice(slice: &[A::Item]) -> Self {
|
||||
let mut vec = Self::new();
|
||||
vec.extend_from_slice(slice);
|
||||
vec
|
||||
let len = slice.len();
|
||||
if len <= A::size() {
|
||||
SmallVec {
|
||||
capacity: len,
|
||||
data: SmallVecData::from_inline(unsafe {
|
||||
let mut data: A = mem::uninitialized();
|
||||
ptr::copy_nonoverlapping(slice.as_ptr(), data.ptr_mut(), len);
|
||||
data
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let mut b = slice.to_vec();
|
||||
let ptr = b.as_mut_ptr();
|
||||
mem::forget(b);
|
||||
SmallVec {
|
||||
capacity: len,
|
||||
data: SmallVecData::from_heap(ptr, len),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy elements from a slice into the vector at position `index`, shifting any following
|
||||
|
@ -1175,7 +1253,7 @@ impl<A: Array> Extend<A::Item> for SmallVec<A> {
|
|||
|
||||
impl<A: Array> fmt::Debug for SmallVec<A> where A::Item: fmt::Debug {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", &**self)
|
||||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1679,6 +1757,7 @@ mod tests {
|
|||
assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
// https://github.com/servo/rust-smallvec/issues/96
|
||||
fn test_insert_many_panic() {
|
||||
|
@ -1949,6 +2028,18 @@ mod tests {
|
|||
assert_eq!(vec.into_vec(), vec![0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_inner() {
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
|
||||
assert_eq!(vec.into_inner(), Ok([0, 1]));
|
||||
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..1);
|
||||
assert_eq!(vec.clone().into_inner(), Err(vec));
|
||||
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
|
||||
assert_eq!(vec.clone().into_inner(), Err(vec));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_vec() {
|
||||
let vec = vec![];
|
||||
|
@ -2070,10 +2161,10 @@ mod tests {
|
|||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_serde() {
|
||||
use self::bincode::{serialize, deserialize, Bounded};
|
||||
use self::bincode::{config, deserialize};
|
||||
let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
|
||||
small_vec.push(1);
|
||||
let encoded = serialize(&small_vec, Bounded(100)).unwrap();
|
||||
let encoded = config().limit(100).serialize(&small_vec).unwrap();
|
||||
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
|
||||
assert_eq!(small_vec, decoded);
|
||||
small_vec.push(2);
|
||||
|
@ -2081,7 +2172,7 @@ mod tests {
|
|||
small_vec.push(3);
|
||||
small_vec.push(4);
|
||||
// Check again after spilling.
|
||||
let encoded = serialize(&small_vec, Bounded(100)).unwrap();
|
||||
let encoded = config().limit(100).serialize(&small_vec).unwrap();
|
||||
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
|
||||
assert_eq!(small_vec, decoded);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче