From 161243748a94bbb7fccb86baae315aa402dc61f4 Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 10:12:35 +0800 Subject: [PATCH 1/7] chore(rustfmt): deprecated `fn_args_layout` -> `fn_args_layout` See also: --- rustfmt.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 777bb3d..e312d17 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,7 +1,7 @@ # Stable edition = "2018" -fn_args_layout = "Compressed" +fn_params_layout = "Compressed" max_width = 80 tab_spaces = 2 use_field_init_shorthand = true @@ -11,4 +11,4 @@ use_small_heuristics = "Max" # Unstable format_code_in_doc_comments = true wrap_comments = true -imports_granularity="Crate" +imports_granularity = "Crate" From d19d77f28b4f225bc6bc0d6b88ce20aee9135a7c Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 11:42:55 +0800 Subject: [PATCH 2/7] feat(TinyVec): add `into_vec()` & `into_boxed_slice()` --- benches/smallvec.rs | 37 +++++++------- src/tinyvec.rs | 116 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 17 deletions(-) diff --git a/benches/smallvec.rs b/benches/smallvec.rs index 504ffaf..1defc7f 100644 --- a/benches/smallvec.rs +++ b/benches/smallvec.rs @@ -3,27 +3,30 @@ //! All the following commentary is based on the latest nightly at the time: //! rustc 1.55.0 (c8dfcfe04 2021-09-06). //! -//! Some of these benchmarks are just a few instructions, so we put our own for loop inside -//! the criterion::Bencher::iter call. This seems to improve the stability of measurements, and it -//! has the wonderful side effect of making the emitted assembly easier to follow. Some of these -//! benchmarks are totally inlined so that there are no calls at all in the hot path, so finding +//! Some of these benchmarks are just a few instructions, so we put our own for +//! loop inside the criterion::Bencher::iter call. This seems to improve the +//! stability of measurements, and it has the wonderful side effect of making +//! the emitted assembly easier to follow. Some of these benchmarks are totally +//! inlined so that there are no calls at all in the hot path, so finding //! this for loop is an easy way to find your way around the emitted assembly. //! -//! The clear method is cheaper to call for arrays of elements without a Drop impl, so wherever -//! possible we reuse a single object in the benchmark loop, with a clear + black_box on each -//! iteration in an attempt to not make that visible to the optimizer. +//! The clear method is cheaper to call for arrays of elements without a Drop +//! impl, so wherever possible we reuse a single object in the benchmark loop, +//! with a clear + black_box on each iteration in an attempt to not make that +//! visible to the optimizer. //! -//! We always call black_box(&v), instead of v = black_box(v) because the latter does a move of the -//! inline array, which is linear in the size of the array and thus varies based on the array type -//! being benchmarked, and this move can be more expensive than the function we're trying to -//! benchmark. -//! -//! We also black_box the input to each method call. This has a significant effect on the assembly -//! emitted, for example if we do not black_box the range we iterate over in the ::push benchmarks, -//! the loop is unrolled. It's not entirely clear if it's better to black_box the iterator that -//! yields the items being pushed, or to black_box at a deeper level: v.push(black_box(i)) for -//! example. Anecdotally, it seems like the latter approach produces unreasonably bad assembly. +//! We always call black_box(&v), instead of v = black_box(v) because the latter +//! does a move of the inline array, which is linear in the size of the array +//! and thus varies based on the array type being benchmarked, and this move can +//! be more expensive than the function we're trying to benchmark. //! +//! We also black_box the input to each method call. This has a significant +//! effect on the assembly emitted, for example if we do not black_box the range +//! we iterate over in the ::push benchmarks, the loop is unrolled. It's not +//! entirely clear if it's better to black_box the iterator that yields the +//! items being pushed, or to black_box at a deeper level: v.push(black_box(i)) +//! for example. Anecdotally, it seems like the latter approach produces +//! unreasonably bad assembly. use criterion::{black_box, criterion_group, criterion_main, Criterion}; use smallvec::SmallVec; diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 953a47a..e1e895a 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -528,6 +528,67 @@ impl TinyVec { TinyVec::Heap(Vec::with_capacity(cap)) } } + + /// Converts a `TinyVec<[T; N]>` into a `Box`. + /// + /// - For `TinyVec::Heap(Vec)`, it takes the `Vec` and converts it into + /// a `Box<[T]>` without heap reallocation. + /// - For `TinyVec::Inline(inner_data)`, it first converts the `inner_data` to + /// `Vec`, then into a `Box<[T]>`. Requiring only a single heap + /// allocation. + /// + /// ## Example + /// + /// ``` + /// use core::mem::size_of_val as mem_size_of; + /// use tinyvec::TinyVec; + /// + /// // Initialize TinyVec with 204800 elements (exceeding inline capacity) + /// let v: TinyVec<[_; 102400]> = (0..204800) + /// .map(|_| 0u8) + /// .collect(); + /// + /// assert!(v.is_heap()); + /// assert_eq!(mem_size_of(&v), 102408); // mem size of TinyVec<[u8; N]>: N+8 + /// assert_eq!(v.len(), 204800); + /// + /// let boxed = v.into_boxed_slice(); + /// assert_eq!(mem_size_of(&boxed), 16); // mem size of Box<[u8]>: 16 bytes (fat pointer) + /// assert_eq!(boxed.len(), 204800); + /// ``` + #[inline] + #[must_use] + pub fn into_boxed_slice(self) -> alloc::boxed::Box<[A::Item]> { + self.into_vec().into_boxed_slice() + } + + /// Converts a `TinyVec<[T; N]>` into a `Vec`. + /// + /// `v.into_vec()` is equivalent to `Into::>::into(v)`. + /// + /// - For `TinyVec::Inline(_)`, `.into()` **does not** offer a performance + /// advantage over `.to_vec()`. + /// - For `TinyVec::Heap(vec_data)`, `.into()` will take `vec_data` without + /// heap reallocation. + /// + /// ## Example + /// + /// ``` + /// use tinyvec::TinyVec; + /// + /// let v = TinyVec::from([0u8; 8]); + /// let v2 = v.clone(); + /// + /// let vec = v.into_vec(); + /// let vec2: Vec<_> = v2.into(); + /// + /// assert_eq!(vec, vec2); + /// ``` + #[inline] + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } } impl TinyVec { @@ -1332,6 +1393,61 @@ impl FromIterator for TinyVec { } } +impl Into> for TinyVec { + /// Converts a `TinyVec` into a `Vec`. + /// + /// ## Examples + /// + /// ### Inline to Vec + /// + /// For `TinyVec::Inline(_)`, + /// `.into()` **does not** offer a performance advantage over `.to_vec()`. + /// + /// ``` + /// use core::mem::size_of_val as mem_size_of; + /// use tinyvec::TinyVec; + /// + /// let v = TinyVec::from([0u8; 120]); + /// assert_eq!(mem_size_of(&v), 128); + /// + /// let vec: Vec<_> = v.into(); + /// assert_eq!(mem_size_of(&vec), 24); + /// ``` + /// + /// ### Heap into Vec + /// + /// For `TinyVec::Heap(vec_data)`, + /// `.into()` will take `vec_data` without heap reallocation. + /// + /// ``` + /// use core::{ + /// any::type_name_of_val as type_of, mem::size_of_val as mem_size_of, + /// }; + /// use tinyvec::TinyVec; + /// + /// const fn from_heap(owned: Vec) -> TinyVec<[T; 1]> { + /// TinyVec::Heap(owned) + /// } + /// + /// let v = from_heap(vec![0u8; 10240]); + /// assert_eq!(v.len(), 10240); + /// assert_eq!(mem_size_of(&v), 24); + /// assert!(type_of(&v).ends_with("TinyVec<[u8; 1]>")); + /// + /// let vec: Vec<_> = v.into(); + /// assert_eq!(mem_size_of(&vec), 24); + /// assert!(type_of(&vec).ends_with("Vec")); + /// ``` + #[inline] + #[must_use] + fn into(self) -> Vec { + match self { + Self::Heap(inner) => inner, + Self::Inline(mut inner) => inner.drain_to_vec(), + } + } +} + /// Iterator for consuming an `TinyVec` and returning owned elements. #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub enum TinyVecIterator { From 51559bad7e55337276ac7dbf9560a09304b8e430 Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 12:27:49 +0800 Subject: [PATCH 3/7] docs(into_boxed_slice): `Box` -> `Box<[T]>` --- src/tinyvec.rs | 77 +++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/tinyvec.rs b/src/tinyvec.rs index e1e895a..652dba9 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -529,7 +529,7 @@ impl TinyVec { } } - /// Converts a `TinyVec<[T; N]>` into a `Box`. + /// Converts a `TinyVec<[T; N]>` into a `Box<[T]>`. /// /// - For `TinyVec::Heap(Vec)`, it takes the `Vec` and converts it into /// a `Box<[T]>` without heap reallocation. @@ -559,7 +559,9 @@ impl TinyVec { #[inline] #[must_use] pub fn into_boxed_slice(self) -> alloc::boxed::Box<[A::Item]> { - self.into_vec().into_boxed_slice() + self + .into_vec() + .into_boxed_slice() } /// Converts a `TinyVec<[T; N]>` into a `Vec`. @@ -769,7 +771,9 @@ impl TinyVec { F: FnMut(&mut A::Item, &mut A::Item) -> bool, { let len = { - let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); + let (dedup, _) = self + .as_mut_slice() + .partition_dedup_by(same_bucket); dedup.len() }; self.truncate(len); @@ -810,9 +814,7 @@ impl TinyVec { /// assert_eq!(tv.as_slice(), &[]); /// ``` #[inline] - pub fn drain>( - &mut self, range: R, - ) -> TinyVecDrain<'_, A> { + pub fn drain>(&mut self, range: R) -> TinyVecDrain<'_, A> { match self { TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)), TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)), @@ -901,7 +903,9 @@ impl TinyVec { if let Some(x) = arr.try_insert(index, item) { let mut v = Vec::with_capacity(arr.len() * 2); - let mut it = arr.iter_mut().map(core::mem::take); + let mut it = arr + .iter_mut() + .map(core::mem::take); v.extend(it.by_ref().take(index)); v.push(x); v.extend(it); @@ -1083,12 +1087,7 @@ impl TinyVec { Bound::Excluded(x) => *x, Bound::Unbounded => self.len(), }; - assert!( - start <= end, - "TinyVec::splice> Illegal range, {} to {}", - start, - end - ); + assert!(start <= end, "TinyVec::splice> Illegal range, {} to {}", start, end); assert!( end <= self.len(), "TinyVec::splice> Range ends at {} but length is only {}!", @@ -1192,15 +1191,15 @@ where if self.removal_start < self.removal_end { match self.replacement.next() { Some(replacement) => { - let removed = core::mem::replace( - &mut self.parent[self.removal_start], - replacement, - ); + let removed = + core::mem::replace(&mut self.parent[self.removal_start], replacement); self.removal_start += 1; Some(removed) } None => { - let removed = self.parent.remove(self.removal_start); + let removed = self + .parent + .remove(self.removal_start); self.removal_end -= 1; Some(removed) } @@ -1245,15 +1244,15 @@ where if self.removal_start < self.removal_end { match self.replacement.next_back() { Some(replacement) => { - let removed = core::mem::replace( - &mut self.parent[self.removal_end - 1], - replacement, - ); + let removed = + core::mem::replace(&mut self.parent[self.removal_end - 1], replacement); self.removal_end -= 1; Some(removed) } None => { - let removed = self.parent.remove(self.removal_end - 1); + let removed = self + .parent + .remove(self.removal_end - 1); self.removal_end -= 1; Some(removed) } @@ -1264,9 +1263,7 @@ where } } -impl<'p, A: Array, I: Iterator> Drop - for TinyVecSplice<'p, A, I> -{ +impl<'p, A: Array, I: Iterator> Drop for TinyVecSplice<'p, A, I> { #[inline] fn drop(&mut self) { for _ in self.by_ref() {} @@ -1275,7 +1272,9 @@ impl<'p, A: Array, I: Iterator> Drop self.parent.reserve(lower_bound); for replacement in self.replacement.by_ref() { - self.parent.insert(self.removal_end, replacement); + self + .parent + .insert(self.removal_end, replacement); self.removal_end += 1; } } @@ -1519,7 +1518,9 @@ where { #[allow(clippy::missing_inline_in_public_items)] fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish() + f.debug_tuple("TinyVecIterator") + .field(&self.as_slice()) + .finish() } } @@ -1563,7 +1564,9 @@ where #[inline] #[must_use] fn eq(&self, other: &Self) -> bool { - self.as_slice().eq(other.as_slice()) + self + .as_slice() + .eq(other.as_slice()) } } impl Eq for TinyVec where A::Item: Eq {} @@ -1575,7 +1578,9 @@ where #[inline] #[must_use] fn partial_cmp(&self, other: &Self) -> Option { - self.as_slice().partial_cmp(other.as_slice()) + self + .as_slice() + .partial_cmp(other.as_slice()) } } impl Ord for TinyVec @@ -1585,7 +1590,9 @@ where #[inline] #[must_use] fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.as_slice().cmp(other.as_slice()) + self + .as_slice() + .cmp(other.as_slice()) } } @@ -1596,7 +1603,9 @@ where #[inline] #[must_use] fn eq(&self, other: &&A) -> bool { - self.as_slice().eq(other.as_slice()) + self + .as_slice() + .eq(other.as_slice()) } } @@ -1843,9 +1852,7 @@ where { type Value = TinyVec; - fn expecting( - &self, formatter: &mut core::fmt::Formatter, - ) -> core::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("a sequence") } From b22b21c5d9100bb516bf75e2f4303da5f2cf16df Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 12:33:37 +0800 Subject: [PATCH 4/7] docs(into_boxed_slice): smaller array sizes --- src/tinyvec.rs | 89 +++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 652dba9..33851cb 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -543,25 +543,23 @@ impl TinyVec { /// use core::mem::size_of_val as mem_size_of; /// use tinyvec::TinyVec; /// - /// // Initialize TinyVec with 204800 elements (exceeding inline capacity) - /// let v: TinyVec<[_; 102400]> = (0..204800) + /// // Initialize TinyVec with 240 elements (exceeding inline capacity) + /// let v: TinyVec<[_; 120]> = (0..240) /// .map(|_| 0u8) /// .collect(); /// /// assert!(v.is_heap()); - /// assert_eq!(mem_size_of(&v), 102408); // mem size of TinyVec<[u8; N]>: N+8 - /// assert_eq!(v.len(), 204800); + /// assert_eq!(mem_size_of(&v), 128); // mem size of TinyVec<[u8; N]>: N+8 + /// assert_eq!(v.len(), 240); /// /// let boxed = v.into_boxed_slice(); /// assert_eq!(mem_size_of(&boxed), 16); // mem size of Box<[u8]>: 16 bytes (fat pointer) - /// assert_eq!(boxed.len(), 204800); + /// assert_eq!(boxed.len(), 240); /// ``` #[inline] #[must_use] pub fn into_boxed_slice(self) -> alloc::boxed::Box<[A::Item]> { - self - .into_vec() - .into_boxed_slice() + self.into_vec().into_boxed_slice() } /// Converts a `TinyVec<[T; N]>` into a `Vec`. @@ -771,9 +769,7 @@ impl TinyVec { F: FnMut(&mut A::Item, &mut A::Item) -> bool, { let len = { - let (dedup, _) = self - .as_mut_slice() - .partition_dedup_by(same_bucket); + let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); dedup.len() }; self.truncate(len); @@ -814,7 +810,9 @@ impl TinyVec { /// assert_eq!(tv.as_slice(), &[]); /// ``` #[inline] - pub fn drain>(&mut self, range: R) -> TinyVecDrain<'_, A> { + pub fn drain>( + &mut self, range: R, + ) -> TinyVecDrain<'_, A> { match self { TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)), TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)), @@ -903,9 +901,7 @@ impl TinyVec { if let Some(x) = arr.try_insert(index, item) { let mut v = Vec::with_capacity(arr.len() * 2); - let mut it = arr - .iter_mut() - .map(core::mem::take); + let mut it = arr.iter_mut().map(core::mem::take); v.extend(it.by_ref().take(index)); v.push(x); v.extend(it); @@ -1087,7 +1083,12 @@ impl TinyVec { Bound::Excluded(x) => *x, Bound::Unbounded => self.len(), }; - assert!(start <= end, "TinyVec::splice> Illegal range, {} to {}", start, end); + assert!( + start <= end, + "TinyVec::splice> Illegal range, {} to {}", + start, + end + ); assert!( end <= self.len(), "TinyVec::splice> Range ends at {} but length is only {}!", @@ -1191,15 +1192,15 @@ where if self.removal_start < self.removal_end { match self.replacement.next() { Some(replacement) => { - let removed = - core::mem::replace(&mut self.parent[self.removal_start], replacement); + let removed = core::mem::replace( + &mut self.parent[self.removal_start], + replacement, + ); self.removal_start += 1; Some(removed) } None => { - let removed = self - .parent - .remove(self.removal_start); + let removed = self.parent.remove(self.removal_start); self.removal_end -= 1; Some(removed) } @@ -1244,15 +1245,15 @@ where if self.removal_start < self.removal_end { match self.replacement.next_back() { Some(replacement) => { - let removed = - core::mem::replace(&mut self.parent[self.removal_end - 1], replacement); + let removed = core::mem::replace( + &mut self.parent[self.removal_end - 1], + replacement, + ); self.removal_end -= 1; Some(removed) } None => { - let removed = self - .parent - .remove(self.removal_end - 1); + let removed = self.parent.remove(self.removal_end - 1); self.removal_end -= 1; Some(removed) } @@ -1263,7 +1264,9 @@ where } } -impl<'p, A: Array, I: Iterator> Drop for TinyVecSplice<'p, A, I> { +impl<'p, A: Array, I: Iterator> Drop + for TinyVecSplice<'p, A, I> +{ #[inline] fn drop(&mut self) { for _ in self.by_ref() {} @@ -1272,9 +1275,7 @@ impl<'p, A: Array, I: Iterator> Drop for TinyVecSplice<'p, A, I> self.parent.reserve(lower_bound); for replacement in self.replacement.by_ref() { - self - .parent - .insert(self.removal_end, replacement); + self.parent.insert(self.removal_end, replacement); self.removal_end += 1; } } @@ -1428,8 +1429,8 @@ impl Into> for TinyVec { /// TinyVec::Heap(owned) /// } /// - /// let v = from_heap(vec![0u8; 10240]); - /// assert_eq!(v.len(), 10240); + /// let v = from_heap(vec![0u8; 120]); + /// assert_eq!(v.len(), 120); /// assert_eq!(mem_size_of(&v), 24); /// assert!(type_of(&v).ends_with("TinyVec<[u8; 1]>")); /// @@ -1518,9 +1519,7 @@ where { #[allow(clippy::missing_inline_in_public_items)] fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - f.debug_tuple("TinyVecIterator") - .field(&self.as_slice()) - .finish() + f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish() } } @@ -1564,9 +1563,7 @@ where #[inline] #[must_use] fn eq(&self, other: &Self) -> bool { - self - .as_slice() - .eq(other.as_slice()) + self.as_slice().eq(other.as_slice()) } } impl Eq for TinyVec where A::Item: Eq {} @@ -1578,9 +1575,7 @@ where #[inline] #[must_use] fn partial_cmp(&self, other: &Self) -> Option { - self - .as_slice() - .partial_cmp(other.as_slice()) + self.as_slice().partial_cmp(other.as_slice()) } } impl Ord for TinyVec @@ -1590,9 +1585,7 @@ where #[inline] #[must_use] fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self - .as_slice() - .cmp(other.as_slice()) + self.as_slice().cmp(other.as_slice()) } } @@ -1603,9 +1596,7 @@ where #[inline] #[must_use] fn eq(&self, other: &&A) -> bool { - self - .as_slice() - .eq(other.as_slice()) + self.as_slice().eq(other.as_slice()) } } @@ -1852,7 +1843,9 @@ where { type Value = TinyVec; - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + fn expecting( + &self, formatter: &mut core::fmt::Formatter, + ) -> core::fmt::Result { formatter.write_str("a sequence") } From a2b24d335216f4084859ece4fed5d76a77f7dc1b Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 12:50:38 +0800 Subject: [PATCH 5/7] docs(tinyvec array sizes): 120 -> 128 --- src/tinyvec.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 33851cb..16fcbd4 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -544,12 +544,12 @@ impl TinyVec { /// use tinyvec::TinyVec; /// /// // Initialize TinyVec with 240 elements (exceeding inline capacity) - /// let v: TinyVec<[_; 120]> = (0..240) + /// let v: TinyVec<[_; 128]> = (0..240) /// .map(|_| 0u8) /// .collect(); /// /// assert!(v.is_heap()); - /// assert_eq!(mem_size_of(&v), 128); // mem size of TinyVec<[u8; N]>: N+8 + /// assert_eq!(mem_size_of(&v), 136); // mem size of TinyVec<[u8; N]>: N+8 /// assert_eq!(v.len(), 240); /// /// let boxed = v.into_boxed_slice(); @@ -1407,8 +1407,8 @@ impl Into> for TinyVec { /// use core::mem::size_of_val as mem_size_of; /// use tinyvec::TinyVec; /// - /// let v = TinyVec::from([0u8; 120]); - /// assert_eq!(mem_size_of(&v), 128); + /// let v = TinyVec::from([0u8; 128]); + /// assert_eq!(mem_size_of(&v), 136); /// /// let vec: Vec<_> = v.into(); /// assert_eq!(mem_size_of(&vec), 24); @@ -1429,8 +1429,8 @@ impl Into> for TinyVec { /// TinyVec::Heap(owned) /// } /// - /// let v = from_heap(vec![0u8; 120]); - /// assert_eq!(v.len(), 120); + /// let v = from_heap(vec![0u8; 128]); + /// assert_eq!(v.len(), 128); /// assert_eq!(mem_size_of(&v), 24); /// assert!(type_of(&v).ends_with("TinyVec<[u8; 1]>")); /// From af02db9258b9addbdf11b6dd69ef52226749ebdd Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 13:20:57 +0800 Subject: [PATCH 6/7] docs(into_boxed_slice): range (`..`) -> `..=` --- src/tinyvec.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 16fcbd4..9823382 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -543,18 +543,16 @@ impl TinyVec { /// use core::mem::size_of_val as mem_size_of; /// use tinyvec::TinyVec; /// - /// // Initialize TinyVec with 240 elements (exceeding inline capacity) - /// let v: TinyVec<[_; 128]> = (0..240) - /// .map(|_| 0u8) - /// .collect(); + /// // Initialize TinyVec with 256 elements (exceeding inline capacity) + /// let v: TinyVec<[_; 128]> = (0u8..=255).collect(); /// /// assert!(v.is_heap()); /// assert_eq!(mem_size_of(&v), 136); // mem size of TinyVec<[u8; N]>: N+8 - /// assert_eq!(v.len(), 240); + /// assert_eq!(v.len(), 256); /// /// let boxed = v.into_boxed_slice(); /// assert_eq!(mem_size_of(&boxed), 16); // mem size of Box<[u8]>: 16 bytes (fat pointer) - /// assert_eq!(boxed.len(), 240); + /// assert_eq!(boxed.len(), 256); /// ``` #[inline] #[must_use] From 777b66f63bea263a4687b5c187927515a4ce01af Mon Sep 17 00:00:00 2001 From: 2moe Date: Thu, 20 Feb 2025 13:38:04 +0800 Subject: [PATCH 7/7] docs(TinyVec::into_vec): `into()` -> `.into_vec()` --- src/tinyvec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 9823382..1458047 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -564,10 +564,10 @@ impl TinyVec { /// /// `v.into_vec()` is equivalent to `Into::>::into(v)`. /// - /// - For `TinyVec::Inline(_)`, `.into()` **does not** offer a performance + /// - For `TinyVec::Inline(_)`, `.into_vec()` **does not** offer a performance /// advantage over `.to_vec()`. - /// - For `TinyVec::Heap(vec_data)`, `.into()` will take `vec_data` without - /// heap reallocation. + /// - For `TinyVec::Heap(vec_data)`, `.into_vec()` will take `vec_data` + /// without heap reallocation. /// /// ## Example ///