Skip to content

Commit

Permalink
added some additional new functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rustonaut committed Mar 23, 2024
1 parent 4958eb7 commit 0808253
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 7 deletions.
67 changes: 66 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,14 @@ pub mod smallvec_v1;
use core::{
fmt,
iter::{DoubleEndedIterator, ExactSizeIterator, Extend, IntoIterator, Peekable},
mem::MaybeUninit,
ops::RangeBounds,
result::Result as StdResult,
};

use alloc::{
boxed::Box,
collections::{BinaryHeap, VecDeque},
collections::{BinaryHeap, TryReserveError, VecDeque},
rc::Rc,
string::String,
vec::{self, Vec},
Expand Down Expand Up @@ -479,6 +480,28 @@ impl<T> Vec1<T> {
}
}

impl_wrapper! {
base_bounds_macro = ,
impl<T> Vec1<T> {
fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>;
fn shrink_to(&mut self, min_capacity: usize) -> ();
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>];
}
}

impl<T> Vec1<T>
where
T: Clone,
{
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
{
self.0.extend_from_within(src);
}
}

impl Vec1<u8> {
/// Works like `&[u8].to_ascii_uppercase()` but returns a `Vec1<T>` instead of a `Vec<T>`
pub fn to_ascii_uppercase(&self) -> Vec1<u8> {
Expand Down Expand Up @@ -1334,6 +1357,48 @@ mod test {
assert_eq!(a, vec1![1u8, 2, 8, 3]);
}

#[test]
fn try_reserve() {
let mut a = vec1![1u8, 2, 4, 3];
a.try_reserve(100).unwrap();
assert!(a.capacity() > 100);
a.try_reserve(usize::MAX).unwrap_err();
}

#[test]
fn try_reserve_exact() {
let mut a = vec1![1u8, 2, 4, 3];
a.try_reserve_exact(124).unwrap();
assert_eq!(a.capacity(), 128);
a.try_reserve(usize::MAX).unwrap_err();
}

#[test]
fn shrink_to() {
let mut a = Vec1::with_capacity(1, 16);
a.extend([2, 3, 4]);
a.shrink_to(16);
assert_eq!(a.capacity(), 16);
a.shrink_to(4);
assert_eq!(a.capacity(), 4);
a.shrink_to(1);
assert_eq!(a.capacity(), 4);
}

#[test]
fn spare_capacity_mut() {
let mut a = Vec1::with_capacity(1, 16);
a.extend([2, 3, 4]);
assert_eq!(a.spare_capacity_mut().len(), 12);
}

#[test]
fn extend_from_within() {
let mut a = vec1!["a", "b", "c", "d"];
a.extend_from_within(1..3);
assert_eq!(a, ["a", "b", "c", "d", "b", "c"]);
}

mod AsMut {
use crate::*;

Expand Down
65 changes: 60 additions & 5 deletions src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ macro_rules! impl_wrapper {
(
base_bounds_macro = $($tb:ident : $trait:ident)?,
impl <$A:ident> $ty_name:ident<$A_:ident> {
$(fn $fn_name:ident(&$($m:ident)* $(, $param:ident: $tp:ty)*) -> $rt:ty);*
$(fn $fn_name:ident(&$($m:ident)* $(, $param:ident: $tp:ty)*) -> $rt:ty ;)*
}
) => (
impl<$A> $ty_name<$A>
Expand Down Expand Up @@ -300,6 +300,15 @@ macro_rules! shared_impl {
/// The moment the last element would be removed this will instead fail, not removing
/// the element. **All but the last element will have been removed anyway.**
///
/// # Panic Behavior
///
/// The panic behavior is for now unspecified and might change without a
/// major version release.
///
/// The current implementation does only delete non-retained elements at
/// the end of the `retain` function call. This might change in the future
/// matching `std`s behavior.
///
/// # Error
///
/// If the last element would be removed instead of removing it a `Size0Error` is
Expand All @@ -323,16 +332,62 @@ macro_rules! shared_impl {
where
F: FnMut(&$item_ty) -> bool
{
// code is based on the code in the standard library,
// given a local instal of rust v1.50.0 source documentation in rustup:
self.retain_mut(|e| f(e))
}

/// Removes all elements except the ones which the predicate says need to be retained.
///
/// The moment the last element would be removed this will instead fail, not removing
/// the element. **All other non retained elements will still be removed.** This means
/// you have to be more careful compared to `Vec::retain_mut` about how you modify
/// non retained elements in the closure.
///
/// # Panic Behavior
///
/// The panic behavior is for now unspecified and might change without a
/// major version release.
///
/// The current implementation does only delete non-retained elements at
/// the end of the `retain` function call. This might change in the future
/// matching `std`s behavior.
///
/// # Error
///
/// If the last element would be removed instead of removing it a `Size0Error` is
/// returned.
///
/// # Example
///
/// Is for `Vec1` but similar code works with `SmallVec1`, too.
///
/// ```
/// # use vec1::vec1;
///
/// let mut vec = vec1![1, 7, 8, 9, 10];
/// vec.retain_mut(|v| {
/// *v += 2;
/// *v % 2 == 1
/// }).unwrap();
/// assert_eq!(vec, vec1![3, 9, 11]);
/// let Size0Error = vec.retain_mut(|_| false).unwrap_err();
/// assert_eq!(vec.len(), 1);
/// assert_eq!(vec.last(), &11);
/// ```
pub fn retain_mut<F>(&mut self, mut f: F) -> Result<(), Size0Error>
where
F: FnMut(&mut $item_ty) -> bool
{
// Code is based on the code in the standard library, but not the newest version
// as the newest version uses unsafe optimizations.
// Given a local instal of rust v1.50.0 source documentation in rustup:
// <path-to-rustup-rust-v1.50.0-toolchain-with-source-doc>/share/doc/rust/html/src/alloc/vec.rs.html#1314-1334
let len = self.len();
let mut del = 0;
{
let v = &mut **self;

for i in 0..len {
if !f(&v[i]) {
if !f(&mut v[i]) {
del += 1;
} else if del > 0 {
v.swap(i - del, i);
Expand Down Expand Up @@ -551,7 +606,7 @@ macro_rules! shared_impl {
fn insert(&mut self, idx: usize, val: $item_ty) -> ();
fn len(&self) -> usize;
fn capacity(&self) -> usize;
fn as_slice(&self) -> &[$item_ty]
fn as_slice(&self) -> &[$item_ty];
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/smallvec_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ impl_wrapper! {
fn grow(&mut self, len: usize) -> ();
fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr>;
fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>;
fn try_grow(&mut self, len: usize) -> Result<(), CollectionAllocErr>
fn try_grow(&mut self, len: usize) -> Result<(), CollectionAllocErr>;
}
}

Expand Down

0 comments on commit 0808253

Please sign in to comment.