mirror of
https://github.com/openharmony/third_party_rust_tinyvec.git
synced 2026-07-19 14:23:33 -04:00
fixed a truncate bug
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
/// A trait for types that can be the backing store of an [`ArrayishVec`].
|
||||
/// A trait for types that can be the backing store of an
|
||||
/// [`ArrayishVec`](ArrayishVec::<A>).
|
||||
///
|
||||
/// You are not generally expected to need to implement this yourself. You can
|
||||
/// if you want I guess. Impls are provided for arrays of length `0..=32`, 33,
|
||||
|
||||
+73
-31
@@ -1,5 +1,20 @@
|
||||
use super::*;
|
||||
|
||||
/// Helper to make an `ArrayishVec`.
|
||||
///
|
||||
/// You specify the backing array type, and optionally give all the elements you
|
||||
/// want to initially place into the array.
|
||||
///
|
||||
/// As an unfortunate restriction, the backing array type must support `Default`
|
||||
/// for it to work with this macro.
|
||||
///
|
||||
/// ```rust
|
||||
/// use tinyvec::*;
|
||||
///
|
||||
/// let empty_av = arr_vec!([u8; 16]);
|
||||
///
|
||||
/// let some_ints = arr_vec!([i32; 4], 1, 2, 3);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! arr_vec {
|
||||
($array_type:ty) => {
|
||||
@@ -17,6 +32,11 @@ macro_rules! arr_vec {
|
||||
};
|
||||
}
|
||||
|
||||
/// An array-backed vector-like data structure.
|
||||
///
|
||||
/// * Fixed capacity (based on array size)
|
||||
/// * Variable length
|
||||
/// * All of the array memory is always initialized.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ArrayishVec<A: Arrayish> {
|
||||
@@ -59,6 +79,7 @@ impl<A: Arrayish, I: SliceIndex<[A::Item]>> IndexMut<I> for ArrayishVec<A> {
|
||||
}
|
||||
|
||||
impl<A: Arrayish> ArrayishVec<A> {
|
||||
/// Move all values from `other` into this vec.
|
||||
#[inline]
|
||||
pub fn append(&mut self, other: &mut Self) {
|
||||
let final_len = self.len + other.len;
|
||||
@@ -74,36 +95,52 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
other.len = 0;
|
||||
}
|
||||
|
||||
/// A mutable pointer to the backing array.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// This pointer has provenance over the _entire_ backing array.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn as_mut_ptr(&mut self) -> *mut A::Item {
|
||||
self.data.slice_mut().as_mut_ptr()
|
||||
}
|
||||
|
||||
/// Helper for getting the mut slice.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
|
||||
self.deref_mut()
|
||||
}
|
||||
|
||||
/// A const pointer to the backing array.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// This pointer has provenance over the _entire_ backing array.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn as_ptr(&self) -> *const A::Item {
|
||||
self.data.slice().as_ptr()
|
||||
}
|
||||
|
||||
/// Helper for getting the shared slice.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn as_slice(&self) -> &[A::Item] {
|
||||
self.deref()
|
||||
}
|
||||
|
||||
/// The capacity of the `ArrayishVec`.
|
||||
///
|
||||
/// This is fixed based on the array type.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn capacity(&self) -> usize {
|
||||
A::CAPACITY
|
||||
}
|
||||
|
||||
/// Removes all elements from the vec.
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) {
|
||||
self.truncate(0)
|
||||
@@ -196,6 +233,7 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
|
||||
// LATER(Vec): drain_filter #nightly https://github.com/rust-lang/rust/issues/43244
|
||||
|
||||
/// Clone each element of the slice into this vec.
|
||||
#[inline]
|
||||
pub fn extend_from_slice(&mut self, sli: &[A::Item])
|
||||
where
|
||||
@@ -264,18 +302,21 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// If the vec is empty.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len == 0
|
||||
}
|
||||
|
||||
/// The length of the vec (in elements).
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
/// Makes a new, empty vec.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn new() -> Self
|
||||
@@ -285,6 +326,10 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Remove and return the last element of the vec, if there is one.
|
||||
///
|
||||
/// ## Failure
|
||||
/// * If the vec is empty you get `None`.
|
||||
#[inline]
|
||||
pub fn pop(&mut self) -> Option<A::Item> {
|
||||
if self.len > 0 {
|
||||
@@ -297,6 +342,11 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Place an element onto the end of the vec.
|
||||
///
|
||||
/// See also, [`try_push`](ArrayishVec::try_push)
|
||||
/// ## Panics
|
||||
/// * If the length of the vec would overflow the capacity.
|
||||
#[inline(always)]
|
||||
pub fn push(&mut self, val: A::Item) {
|
||||
if self.try_push(val).is_err() {
|
||||
@@ -368,34 +418,6 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize the vec to the new size.
|
||||
///
|
||||
/// If it needs to be longer the length is simply increased (in constant
|
||||
/// time), if it needs to be shorter then it's truncated.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use tinyvec::*;
|
||||
///
|
||||
/// let mut av = arr_vec!([i32; 10], 1, 2, 3);
|
||||
/// av.resize_default(5);
|
||||
/// assert_eq!(av.as_slice(), &[1, 2, 3, 0, 0][..]);
|
||||
///
|
||||
/// let mut av = arr_vec!([i32; 10], 1, 2, 3, 4);
|
||||
/// av.resize_default(2);
|
||||
/// assert_eq!(av.as_slice(), &[1, 2][..]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn resize_default(&mut self, new_len: usize) {
|
||||
use core::cmp::Ordering;
|
||||
match new_len.cmp(&self.len) {
|
||||
Ordering::Less => self.truncate(new_len),
|
||||
Ordering::Equal => (),
|
||||
Ordering::Greater => self.len = new_len,
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize the vec to the new length.
|
||||
///
|
||||
/// If it needs to be longer, it's filled with repeated calls to the provided
|
||||
@@ -527,6 +549,9 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
replace(&mut self[index], i)
|
||||
}
|
||||
|
||||
/// Reduces the vec's length to the given value.
|
||||
///
|
||||
/// If the vec is already shorter than the input, nothing happens.
|
||||
#[inline]
|
||||
pub fn truncate(&mut self, new_len: usize) {
|
||||
if needs_drop::<A::Item>() {
|
||||
@@ -534,7 +559,7 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
self.pop();
|
||||
}
|
||||
} else {
|
||||
self.len = new_len;
|
||||
self.len = self.len.min(new_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,12 +603,15 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
// LATER: try_remove ?
|
||||
}
|
||||
|
||||
// GoodFirstIssue: this entire type is correct but slow.
|
||||
/// Draining iterator for `ArrayishVecDrain`
|
||||
///
|
||||
/// See [`ArrayishVecDrain::drain`](ArrayishVecDrain::<A>::drain)
|
||||
pub struct ArrayishVecDrain<'p, A: Arrayish> {
|
||||
parent: &'p mut ArrayishVec<A>,
|
||||
target_index: usize,
|
||||
target_count: usize,
|
||||
}
|
||||
// GoodFirstIssue: this entire type is correct but slow.
|
||||
// NIGHTLY: vec_drain_as_slice, https://github.com/rust-lang/rust/issues/58957
|
||||
impl<'p, A: Arrayish> Iterator for ArrayishVecDrain<'p, A> {
|
||||
type Item = A::Item;
|
||||
@@ -599,6 +627,7 @@ impl<'p, A: Arrayish> Iterator for ArrayishVecDrain<'p, A> {
|
||||
}
|
||||
}
|
||||
impl<'p, A: Arrayish> Drop for ArrayishVecDrain<'p, A> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
for _ in self {}
|
||||
}
|
||||
@@ -637,6 +666,7 @@ impl<A: Arrayish> BorrowMut<[A::Item]> for ArrayishVec<A> {
|
||||
}
|
||||
|
||||
impl<A: Arrayish> Extend<A::Item> for ArrayishVec<A> {
|
||||
#[inline]
|
||||
fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
|
||||
for t in iter {
|
||||
self.push(t)
|
||||
@@ -649,13 +679,15 @@ impl<A: Arrayish> From<A> for ArrayishVec<A> {
|
||||
#[must_use]
|
||||
/// The output has a length equal to the full array.
|
||||
///
|
||||
/// If you want to select a length, use [`from_array_len`]
|
||||
/// If you want to select a length, use
|
||||
/// [`from_array_len`](ArrayishVec::from_array_len)
|
||||
fn from(data: A) -> Self {
|
||||
Self { len: data.slice().len(), data }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arrayish + Default> FromIterator<A::Item> for ArrayishVec<A> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
|
||||
let mut av = Self::default();
|
||||
@@ -666,6 +698,7 @@ impl<A: Arrayish + Default> FromIterator<A::Item> for ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator for consuming an `ArrayishVec` and returning owned elements.
|
||||
pub struct ArrayishVecIterator<A: Arrayish> {
|
||||
base: usize,
|
||||
len: usize,
|
||||
@@ -803,6 +836,7 @@ impl<A: Arrayish> Binary for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Binary,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -819,6 +853,7 @@ impl<A: Arrayish> Debug for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Debug,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -835,6 +870,7 @@ impl<A: Arrayish> Display for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Display,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -851,6 +887,7 @@ impl<A: Arrayish> LowerExp for ArrayishVec<A>
|
||||
where
|
||||
A::Item: LowerExp,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -867,6 +904,7 @@ impl<A: Arrayish> LowerHex for ArrayishVec<A>
|
||||
where
|
||||
A::Item: LowerHex,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -883,6 +921,7 @@ impl<A: Arrayish> Octal for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Octal,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -899,6 +938,7 @@ impl<A: Arrayish> Pointer for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Pointer,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -915,6 +955,7 @@ impl<A: Arrayish> UpperExp for ArrayishVec<A>
|
||||
where
|
||||
A::Item: UpperExp,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
@@ -931,6 +972,7 @@ impl<A: Arrayish> UpperHex for ArrayishVec<A>
|
||||
where
|
||||
A::Item: UpperHex,
|
||||
{
|
||||
#[allow(clippy::missing_inline_in_public_items)]
|
||||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
|
||||
+37
-1
@@ -4,8 +4,44 @@
|
||||
feature = "nightly_slice_partition_dedup",
|
||||
feature(slice_partition_dedup)
|
||||
)]
|
||||
#![warn(clippy::missing_inline_in_public_items)]
|
||||
#![warn(clippy::must_use_candidate)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! Just, really the littlest Vec you could need. So smol.
|
||||
//! Programmers can have a little vec, as a treat.
|
||||
//!
|
||||
//! ## What This Is
|
||||
//!
|
||||
//! This crate has two main types
|
||||
//!
|
||||
//! * `ArrayishVec`: Like the `ArrayVec` from the
|
||||
//! [arrayvec](https://docs.rs/arrayvec) crate. It's an array backed linear
|
||||
//! data store. If you push too much data it will panic.
|
||||
//! * `TinyVec`: **NOT YET IMPLEMENTED. PLANNED FOR 0.2, SOON(TM)** This will be
|
||||
//! like the `SmallVec` from [smallvec](https://docs.rs/smallvec). It starts
|
||||
//! as an `ArrayishVec`, and when that _would have_ overflowed it will instead
|
||||
//! transition everything into a normal `Vec` on the heap.
|
||||
//!
|
||||
//! ## How Is This Different From Those Other Crates?
|
||||
//!
|
||||
//! It's 100% safe code. Not just "we think this unsafe code is sound so we'll
|
||||
//! give you a safe abstraction". This crate doesn't have a single `unsafe`
|
||||
//! block in it. If you trust the standard library to not trigger UB, then you
|
||||
//! can trust this crate to do the same.
|
||||
//!
|
||||
//! The trade off is that the item type has to implement `Default`, and then the
|
||||
//! "spare space" of the vec is kept as Default instances of the type in
|
||||
//! question, rather than being uninitialized memory.
|
||||
//!
|
||||
//! I haven't benchmarked it, but I _suspect_ that there is a performance loss
|
||||
//! compared to just using `unsafe` and `MaybeUninit` and all that. I mean the
|
||||
//! code probably isn't the best it could possibly by, but _also_ even if it
|
||||
//! were perfectly optimal I suspect that there will still be a performance hit
|
||||
//! compared to not using `MaybeUninit`. That's why we got it into the language
|
||||
//! after all.
|
||||
//!
|
||||
//! Still, if you really want to be sure that there's no UB going on in your
|
||||
//! collection, here you are.
|
||||
|
||||
use core::{
|
||||
borrow::{Borrow, BorrowMut},
|
||||
|
||||
Reference in New Issue
Block a user