mirror of
https://github.com/openharmony/third_party_rust_tinyvec.git
synced 2026-07-21 01:35:22 -04:00
more stuff
This commit is contained in:
+8
-3
@@ -5,18 +5,23 @@ version = "0.0.1-alpha.0"
|
||||
authors = ["Lokathor <zefria@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "Zlib"
|
||||
keywords = ["vec", "no_std", "smol"]
|
||||
keywords = ["vec", "no_std", "no-std", "smol"]
|
||||
categories = ["data-structures", "no-std"]
|
||||
|
||||
[dependencies]
|
||||
# not even std!
|
||||
|
||||
[features]
|
||||
default = ["extern_crate_alloc"]
|
||||
default = ["extern_crate_alloc", "nightly_slice_partition_dedup"]
|
||||
|
||||
# Provide additional types and impls related to the `alloc` trait.
|
||||
# Provide additional types and impls related to the `alloc` crate.
|
||||
extern_crate_alloc = []
|
||||
|
||||
# allow use of nightly feature `slice_partition_dedup`,
|
||||
# will become useless once that is stabilized:
|
||||
# https://github.com/rust-lang/rust/issues/54279
|
||||
nightly_slice_partition_dedup = []
|
||||
|
||||
[badges]
|
||||
appveyor = { repository = "Lokathor/tinyvec" }
|
||||
travis-ci = { repository = "Lokathor/tinyvec" }
|
||||
|
||||
+80
-21
@@ -24,19 +24,19 @@ impl<A: Arrayish> DerefMut for ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arrayish> Index<usize> for ArrayishVec<A> {
|
||||
type Output = A::Item;
|
||||
impl<A: Arrayish, I: SliceIndex<[A::Item]>> Index<I> for ArrayishVec<A> {
|
||||
type Output = <I as SliceIndex<[A::Item]>>::Output;
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
&self.deref()[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arrayish> IndexMut<usize> for ArrayishVec<A> {
|
||||
impl<A: Arrayish, I: SliceIndex<[A::Item]>> IndexMut<I> for ArrayishVec<A> {
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||
&mut self.deref_mut()[index]
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,8 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
panic!("ArrayishVec: overflow!");
|
||||
}
|
||||
let target_slice = &mut self.data.slice_mut()[self.len..final_len];
|
||||
for (target_mut, app_mut) in target_slice.iter_mut().zip(other.deref_mut()) {
|
||||
for (target_mut, app_mut) in target_slice.iter_mut().zip(other.deref_mut())
|
||||
{
|
||||
replace(target_mut, replace(app_mut, A::Item::default()));
|
||||
}
|
||||
self.len = final_len;
|
||||
@@ -91,9 +92,38 @@ impl<A: Arrayish> ArrayishVec<A> {
|
||||
self.truncate(0)
|
||||
}
|
||||
|
||||
// TODO(Vec): dedup
|
||||
// TODO(Vec): dedup_by
|
||||
// TODO(Vec): dedup_by_key
|
||||
#[cfg(feature = "nightly_slice_partition_dedup")]
|
||||
#[inline(always)]
|
||||
pub fn dedup(&mut self)
|
||||
where
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
self.dedup_by(|a, b| a == b)
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly_slice_partition_dedup")]
|
||||
#[inline(always)]
|
||||
pub fn dedup_by<F>(&mut self, same_bucket: F)
|
||||
where
|
||||
F: FnMut(&mut A::Item, &mut A::Item) -> bool,
|
||||
{
|
||||
let len = {
|
||||
let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
|
||||
dedup.len()
|
||||
};
|
||||
self.truncate(len);
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly_slice_partition_dedup")]
|
||||
#[inline(always)]
|
||||
pub fn dedup_by_key<F, K>(&mut self, mut key: F)
|
||||
where
|
||||
F: FnMut(&mut A::Item) -> K,
|
||||
K: PartialEq,
|
||||
{
|
||||
self.dedup_by(|a, b| key(a) == key(b))
|
||||
}
|
||||
|
||||
// TODO(Vec): drain
|
||||
// TODO(Vec): drain_filter #nightly
|
||||
|
||||
@@ -256,8 +286,13 @@ impl<A: Arrayish> BorrowMut<[A::Item]> for ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(Vec): Extend<&'a T>
|
||||
// TODO(Vec): Extend<T>
|
||||
impl<A: Arrayish> Extend<A::Item> for ArrayishVec<A> {
|
||||
fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
|
||||
for t in iter {
|
||||
self.push(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arrayish> From<A> for ArrayishVec<A> {
|
||||
#[inline(always)]
|
||||
@@ -281,9 +316,6 @@ impl<A: Arrayish + Default> FromIterator<A::Item> for ArrayishVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(Vec): Index<I: SliceIndex>
|
||||
// TODO(Vec): IndexMut<I: SliceIndex>
|
||||
|
||||
pub struct ArrayishVecIterator<A: Arrayish> {
|
||||
base: usize,
|
||||
len: usize,
|
||||
@@ -343,19 +375,40 @@ impl<A: Arrayish> PartialEq for ArrayishVec<A>
|
||||
where
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.deref() == other.deref()
|
||||
self.deref().eq(other.deref())
|
||||
}
|
||||
}
|
||||
impl<A: Arrayish> Eq for ArrayishVec<A> where A::Item: Eq {}
|
||||
|
||||
impl<A: Arrayish> PartialOrd for ArrayishVec<A>
|
||||
where
|
||||
A::Item: PartialOrd,
|
||||
{
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
|
||||
self.deref().partial_cmp(other.deref())
|
||||
}
|
||||
}
|
||||
impl<A: Arrayish> Ord for ArrayishVec<A>
|
||||
where
|
||||
A::Item: Ord,
|
||||
{
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||
self.deref().cmp(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arrayish> PartialEq<&A> for ArrayishVec<A>
|
||||
where
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eq(&self, other: &&A) -> bool {
|
||||
self.deref() == other.slice()
|
||||
@@ -366,25 +419,31 @@ impl<A: Arrayish> PartialEq<&[A::Item]> for ArrayishVec<A>
|
||||
where
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eq(&self, other: &&[A::Item]) -> bool {
|
||||
self.deref() == *other
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
I think, in retrospect, this is useless?
|
||||
|
||||
The `&mut [A::Item]` should coerce to `&[A::Item]` and use the above impl.
|
||||
I'll leave it here for now though since we already had it written out..
|
||||
|
||||
impl<A: Arrayish> PartialEq<&mut [A::Item]> for ArrayishVec<A>
|
||||
where
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eq(&self, other: &&mut [A::Item]) -> bool {
|
||||
self.deref() == *other
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: PartialOrd, Ord, Hash
|
||||
*/
|
||||
|
||||
// //
|
||||
// Formatting impls
|
||||
|
||||
+6
-113
@@ -1,5 +1,9 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![cfg_attr(
|
||||
feature = "nightly_slice_partition_dedup",
|
||||
feature(slice_partition_dedup)
|
||||
)]
|
||||
|
||||
//! Just, really the littlest Vec you could need. So smol.
|
||||
|
||||
@@ -12,9 +16,10 @@ use core::{
|
||||
Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Pointer,
|
||||
UpperExp, UpperHex,
|
||||
},
|
||||
iter::{FromIterator, IntoIterator, Iterator},
|
||||
iter::{Extend, FromIterator, IntoIterator, Iterator},
|
||||
mem::{needs_drop, replace},
|
||||
ops::{Deref, DerefMut, Index, IndexMut},
|
||||
slice::SliceIndex,
|
||||
};
|
||||
|
||||
#[cfg(feature = "extern_crate_alloc")]
|
||||
@@ -25,115 +30,3 @@ pub use arrayish::*;
|
||||
|
||||
mod arrayish_vec;
|
||||
pub use arrayish_vec::*;
|
||||
|
||||
/*
|
||||
|
||||
// Note(Lokathor): We just want to hide the enum details away. Rust doesn't let
|
||||
// you be an enum with private variants, so instead we make this be a private
|
||||
// inner field of the public `TinyVec<T>` type.
|
||||
#[derive(Debug, Clone)]
|
||||
enum Payload<T: Default> {
|
||||
Inline { len: usize, data: [T; 8] },
|
||||
Heap(Vec<T>),
|
||||
}
|
||||
|
||||
/// A `TinyVec<T>` is like a `Vec<T>`, but it will store up to 8 elements
|
||||
/// "inline" on the stack before transitioning into being a normal `Vec<T>`.
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct TinyVec<T: Default>(Payload<T>);
|
||||
|
||||
// TODO: impl a better Debug
|
||||
|
||||
impl<T: Default> Default for TinyVec<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Deref for TinyVec<T> {
|
||||
type Target = [T];
|
||||
fn deref(&self) -> &[T] {
|
||||
match &self.0 {
|
||||
Payload::Inline { len, data } => &data[..*len],
|
||||
Payload::Heap(vec) => &vec,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> DerefMut for TinyVec<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
match &mut self.0 {
|
||||
Payload::Inline { len, data } => &mut data[..*len],
|
||||
Payload::Heap(ref mut vec) => &mut vec[..],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> TinyVec<T> {
|
||||
pub fn new() -> Self {
|
||||
Self(Payload::Inline {
|
||||
len: 0,
|
||||
data: [
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
T::default(),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push(&mut self, val: T) {
|
||||
match &mut self.0 {
|
||||
Payload::Inline { len: 8, data } => {
|
||||
let mut v = Vec::with_capacity(8 + 10);
|
||||
for data_mut in data.iter_mut() {
|
||||
v.push(replace(data_mut, T::default()));
|
||||
}
|
||||
v.push(val);
|
||||
replace(&mut self.0, Payload::Heap(v));
|
||||
}
|
||||
Payload::Inline { len, data } => {
|
||||
debug_assert!(*len < 8, "push: illegal len: {}", len);
|
||||
data[*len] = val;
|
||||
*len += 1;
|
||||
}
|
||||
Payload::Heap(ref mut vec) => vec.push(val),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
match &mut self.0 {
|
||||
Payload::Inline { len: 0, .. } => None,
|
||||
Payload::Inline { len, data } => {
|
||||
debug_assert!(*len > 0, "pop: illegal len: {}", len);
|
||||
let out = replace(&mut data[*len - 1], T::default());
|
||||
*len -= 1;
|
||||
Some(out)
|
||||
}
|
||||
Payload::Heap(ref mut vec) => vec.pop(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, new_len: usize) {
|
||||
match &mut self.0 {
|
||||
Payload::Inline { len, data } => {
|
||||
if needs_drop::<T>() {
|
||||
while *len > new_len {
|
||||
replace(&mut data[*len - 1], T::default());
|
||||
*len -= 1;
|
||||
}
|
||||
} else {
|
||||
*len = (*len).min(new_len);
|
||||
}
|
||||
}
|
||||
Payload::Heap(ref mut vec) => vec.truncate(new_len),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user