rename Vec -> DynVec

This commit is contained in:
missing 2022-08-19 12:13:36 -05:00
parent 51aab16e01
commit 474b591b94
5 changed files with 150 additions and 154 deletions

View file

@ -4,7 +4,7 @@ use test::{black_box, Bencher};
extern crate test;
use super::Vec;
use super::DynVec;
use std::{fmt::Debug, mem, vec::Vec as StdVec};
#[bench]
@ -20,7 +20,7 @@ fn std_push(b: &mut Bencher) {
#[bench]
#[cfg_attr(miri, ignore)]
fn dyn_push(b: &mut Bencher) {
let mut vec = Vec::new();
let mut vec = DynVec::new();
b.iter(|| vec.push(black_box(5)));
@ -40,7 +40,7 @@ fn std_push_box(b: &mut Bencher) {
#[bench]
#[cfg_attr(miri, ignore)]
fn dyn_push_unsize(b: &mut Bencher) {
let mut vec = Vec::new();
let mut vec = DynVec::new();
b.iter(|| vec.push_unsize_stable(black_box(5), |v| v as &dyn Debug));
@ -50,7 +50,7 @@ fn dyn_push_unsize(b: &mut Bencher) {
#[bench]
#[cfg_attr(miri, ignore)]
fn dyn_push_box(b: &mut Bencher) {
let mut vec = Vec::new();
let mut vec = DynVec::new();
b.iter(|| vec.push_box(black_box(Box::new(5) as Box<dyn Debug>)));
@ -60,7 +60,7 @@ fn dyn_push_box(b: &mut Bencher) {
#[bench]
#[cfg_attr(miri, ignore)]
fn dyn_push_then_unsize(b: &mut Bencher) {
let mut vec = Vec::new();
let mut vec = DynVec::new();
b.iter(|| vec.push(black_box(5)));

View file

@ -1,6 +1,6 @@
//! Implements `Debug`, `Default`, `Extend`, and `Deref`. Also implements `PartialEq` for various list-like types.
use crate::{Extra, Vec};
use crate::{DynVec, Extra};
use std::{
fmt::Debug,
@ -14,21 +14,21 @@ use std::{
#[cfg(feature = "unstable")]
use std::ops::CoerceUnsized;
impl<T: ?Sized> Default for Vec<T> {
impl<T: ?Sized> Default for DynVec<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: ?Sized + Debug> Debug for Vec<T> {
impl<T: ?Sized + Debug> Debug for DynVec<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
// Vec<T> == Vec<U>
impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<Vec<U>> for Vec<T> {
fn eq(&self, other: &Vec<U>) -> bool {
// DynVec<T> == DynVec<U>
impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<DynVec<U>> for DynVec<T> {
fn eq(&self, other: &DynVec<U>) -> bool {
if self.len != other.len {
return false;
}
@ -41,10 +41,10 @@ impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<Vec<U>> for Vec<T> {
}
}
impl<T: ?Sized + Eq> Eq for Vec<T> {}
impl<T: ?Sized + Eq> Eq for DynVec<T> {}
// Vec<T> == [U]
impl<T: PartialEq<U>, U> PartialEq<[U]> for Vec<T> {
// DynVec<T> == [U]
impl<T: PartialEq<U>, U> PartialEq<[U]> for DynVec<T> {
fn eq(&self, other: &[U]) -> bool {
if self.len != other.len() {
return false;
@ -58,85 +58,85 @@ impl<T: PartialEq<U>, U> PartialEq<[U]> for Vec<T> {
}
}
// [U] == Vec<T>
impl<T: PartialEq<U>, U> PartialEq<Vec<T>> for [U] {
fn eq(&self, other: &Vec<T>) -> bool {
// [U] == DynVec<T>
impl<T: PartialEq<U>, U> PartialEq<DynVec<T>> for [U] {
fn eq(&self, other: &DynVec<T>) -> bool {
other == self
}
}
// Vec<T> == &[U]
impl<T: PartialEq<U>, U> PartialEq<&[U]> for Vec<T> {
// DynVec<T> == &[U]
impl<T: PartialEq<U>, U> PartialEq<&[U]> for DynVec<T> {
fn eq(&self, other: &&[U]) -> bool {
*self == **other
}
}
// &[U] == Vec<T>
impl<T: PartialEq<U>, U> PartialEq<Vec<T>> for &[U] {
fn eq(&self, other: &Vec<T>) -> bool {
// &[U] == DynVec<T>
impl<T: PartialEq<U>, U> PartialEq<DynVec<T>> for &[U] {
fn eq(&self, other: &DynVec<T>) -> bool {
*other == **self
}
}
// Vec<T> == &mut [U]
impl<T: PartialEq<U>, U> PartialEq<&mut [U]> for Vec<T> {
// DynVec<T> == &mut [U]
impl<T: PartialEq<U>, U> PartialEq<&mut [U]> for DynVec<T> {
fn eq(&self, other: &&mut [U]) -> bool {
*self == **other
}
}
// &mut [U] == Vec<T>
impl<T: PartialEq<U>, U> PartialEq<Vec<T>> for &mut [U] {
fn eq(&self, other: &Vec<T>) -> bool {
// &mut [U] == DynVec<T>
impl<T: PartialEq<U>, U> PartialEq<DynVec<T>> for &mut [U] {
fn eq(&self, other: &DynVec<T>) -> bool {
*other == **self
}
}
// Vec<T> == [U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for Vec<T> {
// DynVec<T> == [U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for DynVec<T> {
fn eq(&self, other: &[U; N]) -> bool {
*self == other[..]
}
}
// [U; N] == Vec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<Vec<T>> for [U; N] {
fn eq(&self, other: &Vec<T>) -> bool {
// [U; N] == DynVec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<DynVec<T>> for [U; N] {
fn eq(&self, other: &DynVec<T>) -> bool {
*other == self[..]
}
}
// Vec<T> == &[U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&[U; N]> for Vec<T> {
// DynVec<T> == &[U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&[U; N]> for DynVec<T> {
fn eq(&self, other: &&[U; N]) -> bool {
*self == other[..]
}
}
// &[U; N] == Vec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<Vec<T>> for &[U; N] {
fn eq(&self, other: &Vec<T>) -> bool {
// &[U; N] == DynVec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<DynVec<T>> for &[U; N] {
fn eq(&self, other: &DynVec<T>) -> bool {
*other == self[..]
}
}
// Vec<T> == &mut [U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&mut [U; N]> for Vec<T> {
// DynVec<T> == &mut [U; N]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&mut [U; N]> for DynVec<T> {
fn eq(&self, other: &&mut [U; N]) -> bool {
*self == other[..]
}
}
// &mut [U; N] == Vec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<Vec<T>> for &mut [U; N] {
fn eq(&self, other: &Vec<T>) -> bool {
// &mut [U; N] == DynVec<T>
impl<T: PartialEq<U>, U, const N: usize> PartialEq<DynVec<T>> for &mut [U; N] {
fn eq(&self, other: &DynVec<T>) -> bool {
*other == self[..]
}
}
#[cfg(not(feature = "unstable"))]
impl<T: ?Sized> Extend<Box<T>> for Vec<T> {
impl<T: ?Sized> Extend<Box<T>> for DynVec<T> {
fn extend<I: IntoIterator<Item = Box<T>>>(&mut self, iter: I) {
for item in iter {
// TODO: optmize
@ -146,7 +146,7 @@ impl<T: ?Sized> Extend<Box<T>> for Vec<T> {
}
#[cfg(feature = "unstable")]
impl<T: ?Sized, U: ?Sized> Extend<Box<U>> for Vec<T>
impl<T: ?Sized, U: ?Sized> Extend<Box<U>> for DynVec<T>
where
Box<U>: CoerceUnsized<Box<T>>,
{
@ -158,7 +158,7 @@ where
}
}
impl<T> Deref for Vec<T> {
impl<T> Deref for DynVec<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
@ -170,7 +170,7 @@ impl<T> Deref for Vec<T> {
}
}
impl<T> DerefMut for Vec<T> {
impl<T> DerefMut for DynVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
if self.is_empty() {
unsafe { slice::from_raw_parts_mut(NonNull::dangling().as_ptr(), 0) }
@ -180,10 +180,10 @@ impl<T> DerefMut for Vec<T> {
}
}
unsafe impl<T: Send> Send for Vec<T> {}
unsafe impl<T: Sync> Sync for Vec<T> {}
unsafe impl<T: Send> Send for DynVec<T> {}
unsafe impl<T: Sync> Sync for DynVec<T> {}
impl<T> From<StdVec<T>> for Vec<T> {
impl<T> From<StdVec<T>> for DynVec<T> {
fn from(std_vec: StdVec<T>) -> Self {
let mut vec = Self::new();
let new_cap = (size_of::<T>() + size_of::<Extra<T>>()) * std_vec.len();
@ -199,8 +199,8 @@ impl<T> From<StdVec<T>> for Vec<T> {
}
}
impl<T> From<Vec<T>> for StdVec<T> {
fn from(mut vec: Vec<T>) -> Self {
impl<T> From<DynVec<T>> for StdVec<T> {
fn from(mut vec: DynVec<T>) -> Self {
let mut std_vec = Self::with_capacity(vec.len);
for item in vec.iter() {

View file

@ -2,7 +2,7 @@
use std::{marker::PhantomData, mem, ptr::NonNull};
use crate::{ptr_ext::PtrExt, Vec};
use crate::{ptr_ext::PtrExt, DynVec};
struct BaseIter<T: ?Sized> {
ptr: *const *mut T,
@ -13,7 +13,7 @@ unsafe impl<T: Send> Send for BaseIter<T> {}
unsafe impl<T: Sync> Sync for BaseIter<T> {}
impl<T: ?Sized> BaseIter<T> {
fn new(vec: &Vec<T>) -> Self {
fn new(vec: &DynVec<T>) -> Self {
Self {
ptr: vec.get_ptr_to_extra(vec.len).cast(),
ptr_back: vec.get_ptr_to_extra(0).cast(),
@ -47,7 +47,7 @@ impl<T: ?Sized> DoubleEndedIterator for BaseIter<T> {
}
// By-ref iteration
impl<'a, T: ?Sized> IntoIterator for &'a Vec<T> {
impl<'a, T: ?Sized> IntoIterator for &'a DynVec<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
@ -57,7 +57,7 @@ impl<'a, T: ?Sized> IntoIterator for &'a Vec<T> {
}
}
/// A by-ref iterator over the elements of a [`Vec`].
/// A by-ref iterator over the elements of a [`DynVec`].
pub struct Iter<'a, T: ?Sized> {
base: BaseIter<T>,
_phantom: PhantomData<&'a T>,
@ -67,8 +67,8 @@ unsafe impl<'a, T: Send> Send for Iter<'a, T> {}
unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
impl<'a, T: ?Sized> Iter<'a, T> {
/// Creates a new by-ref iterator over a [`Vec`]. usually seen as [`Vec::iter`].
pub fn new(vec: &'a Vec<T>) -> Self {
/// Creates a new by-ref iterator over a [`DynVec`]. usually seen as [`DynVec::iter`].
pub fn new(vec: &'a DynVec<T>) -> Self {
Self {
base: BaseIter::new(vec),
_phantom: PhantomData,
@ -91,7 +91,7 @@ impl<'a, T: ?Sized> DoubleEndedIterator for Iter<'a, T> {
}
// By-mut iteration
impl<'a, T: ?Sized> IntoIterator for &'a mut Vec<T> {
impl<'a, T: ?Sized> IntoIterator for &'a mut DynVec<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
@ -101,7 +101,7 @@ impl<'a, T: ?Sized> IntoIterator for &'a mut Vec<T> {
}
}
/// A by-mut iterator over the elements of a [`Vec`].
/// A by-mut iterator over the elements of a [`DynVec`].
#[allow(clippy::module_name_repetitions)]
pub struct IterMut<'a, T: ?Sized> {
base: BaseIter<T>,
@ -112,8 +112,8 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
impl<'a, T: ?Sized> IterMut<'a, T> {
/// Creates a new by-mut iterator over a [`Vec`]. usually seen as [`Vec::iter_mut`].
pub fn new(vec: &'a mut Vec<T>) -> Self {
/// Creates a new by-mut iterator over a [`DynVec`]. usually seen as [`DynVec::iter_mut`].
pub fn new(vec: &'a mut DynVec<T>) -> Self {
Self {
base: BaseIter::new(vec),
_phantom: PhantomData,
@ -136,7 +136,7 @@ impl<'a, T: ?Sized> DoubleEndedIterator for IterMut<'a, T> {
}
// By-value iteration
impl<T: ?Sized> IntoIterator for Vec<T> {
impl<T: ?Sized> IntoIterator for DynVec<T> {
type Item = Box<T>;
type IntoIter = IntoIter<T>;
@ -146,7 +146,7 @@ impl<T: ?Sized> IntoIterator for Vec<T> {
}
}
/// A by-value iterator over the elements of a [`Vec`].
/// A by-value iterator over the elements of a [`DynVec`].
#[allow(clippy::module_name_repetitions)]
pub struct IntoIter<T: ?Sized> {
ptr: NonNull<u8>,
@ -158,8 +158,8 @@ unsafe impl<T: Send> Send for IntoIter<T> {}
unsafe impl<T: Sync> Sync for IntoIter<T> {}
impl<T: ?Sized> IntoIter<T> {
/// Creates a new by-value iterator over a [`Vec`]. usually seen as [`Vec::into_iter`].
pub fn new(vec: Vec<T>) -> Self {
/// Creates a new by-value iterator over a [`DynVec`]. usually seen as [`DynVec::into_iter`].
pub fn new(vec: DynVec<T>) -> Self {
let this = Self {
ptr: vec.ptr,
capacity: vec.capacity,
@ -186,7 +186,7 @@ impl<T: ?Sized> DoubleEndedIterator for IntoIter<T> {
impl<T: ?Sized> Drop for IntoIter<T> {
fn drop(&mut self) {
drop(Vec::<T> {
drop(DynVec::<T> {
ptr: self.ptr,
len: 0,
capacity: self.capacity,
@ -197,9 +197,9 @@ impl<T: ?Sized> Drop for IntoIter<T> {
}
// // this implementation will collect *while unsizing*, and would conflict with the other
// impl<T: ?Sized, U> FromIterator<U> for Vec<T> where for<'a> &'a U: CoerceUnsized<&'a T> {
// impl<T: ?Sized, U> FromIterator<U> for DynVec<T> where for<'a> &'a U: CoerceUnsized<&'a T> {
// fn from_iter<I: IntoIterator<Item = U>>(iter: I) -> Self {
// let mut vec = Vec::new();
// let mut vec = DynVec::new();
// for item in iter.into_iter() {
// vec.push_unsize(item);
@ -209,7 +209,7 @@ impl<T: ?Sized> Drop for IntoIter<T> {
// }
// }
impl<T> FromIterator<T> for Vec<T> {
impl<T> FromIterator<T> for DynVec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut vec = Self::new();

View file

@ -1,43 +1,43 @@
//! # A [`Vec<T: ?Sized>`]
//!
//! [`dyn_vec::Vec`], a dynamic length collection of unsized elements, akin to [`std::vec::Vec`].
//! [`DynVec`], a dynamic length collection of unsized elements, akin to [`std::vec::Vec`].
//!
//! # Examples
//!
//! You can create a vector with [`Vec::new`]:
//! You can create a vector with [`DynVec::new`]:
//!
//! ```
//! # use std::fmt::Debug;
//! # use dyn_vec::prelude::*;
//! let vec: Vec<dyn Debug> = Vec::new();
//! let vec: DynVec<dyn Debug> = DynVec::new();
//! # assert_eq!(format!("{:?}", vec), "[]");
//! ```
//!
//! or with the [`vec!`] macro:
//! or with the [`dyn_vec!`] macro:
//!
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! # use dyn_vec::prelude::*;
//! # use std::fmt::Debug;
//! let vec: Vec<i32> = vec![1, 2, 3];
//! // check the docs for `vec!` for more info on this syntax
//! let vec_boxed: Vec<dyn Debug> = vec![box:
//! let vec: DynVec<i32> = dyn_vec![1, 2, 3];
//! // check the docs for `dyn_vec!` for more info on this syntax
//! let vec_boxed: DynVec<dyn Debug> = dyn_vec![box:
//! Box::new(1) as _,
//! Box::new("foo") as _,
//! Box::new(true) as _
//! ];
//! let vec_unsized: Vec<dyn Debug> = vec![unsized: 1, "foo", true];
//! let vec_from_elem: Vec<i32> = vec![3; 5];
//! let vec_unsized: DynVec<dyn Debug> = dyn_vec![unsized: 1, "foo", true];
//! let vec_from_elem: DynVec<i32> = dyn_vec![3; 5];
//! # assert_eq!(vec, [1, 2, 3]);
//! # assert_eq!(format!("{:?}", vec_boxed), r#"[1, "foo", true]"#);
//! # assert_eq!(format!("{:?}", vec_unsized), r#"[1, "foo", true]"#);
//! # assert_eq!(vec_from_elem, [3; 5]);
//! ```
//!
//! A vector can be pushed to with [`Vec::push`]:
//! A vector can be pushed to with [`DynVec::push`]:
//!
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! let mut vec: Vec<i32> = vec![];
//! # use dyn_vec::prelude::*;
//! let mut vec: DynVec<i32> = dyn_vec![];
//! vec.push(1);
//! vec.push(2);
//! vec.push(3);
@ -47,9 +47,9 @@
//! ...and with [`push_box`] and [`push_unsize`] ([`push_unsize_stable`] without the `"unstable"` feature):
//!
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! # use dyn_vec::prelude::*;
//! # use std::fmt::Debug;
//! let mut vec: Vec<dyn Debug> = vec![];
//! let mut vec: DynVec<dyn Debug> = dyn_vec![];
//! vec.push_box(Box::new(1));
//! vec.push_box(Box::new("foo"));
//! vec.push_box(Box::new(true));
@ -64,11 +64,11 @@
//! Finally, a vector can be [`unsize`]d to another vector ([`unsize_stable`] on stable):
//!
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! # use dyn_vec::prelude::*;
//! # use std::fmt::Debug;
//! let vec: Vec<i32> = vec![1, 2, 3];
//! let vec: DynVec<i32> = dyn_vec![1, 2, 3];
//! // vec.push_unsize_stable("foo", |v| v as _); // not yet...
//! let mut vec: Vec<dyn Debug> = vec.unsize_stable(|v| v as _);
//! let mut vec: DynVec<dyn Debug> = vec.unsize_stable(|v| v as _);
//! vec.push_unsize_stable("foo", |v| v as _); // now we can!
//! # assert_eq!(format!("{:?}", vec), r#"[1, 2, 3, "foo"]"#);
//! ```
@ -81,9 +81,9 @@
//! - [`#![feature(coerce_unsized)]`](https://github.com/rust-lang/rust/issues/27732)
//!
//! and enables the following functionality (note: these links are probably broken):
//! - [`Vec::push_unsize`]
//! - [`Vec::unsize`]
//! - [`Vec::extend_unsize`]
//! - [`DynVec::push_unsize`]
//! - [`DynVec::unsize`]
//! - [`DynVec::extend_unsize`]
//!
//! In addition, the `"unstable"` feature also enables dependance on the following nightly features:
//! - [`#![feature(set_ptr_value)]`](https://github.com/rust-lang/rust/issues/75091)
@ -94,7 +94,7 @@
//! # Data Layout
//!
//! ```text
//! Vec<T>
//! DynVec<T>
//! ┌────┬────┬────┬────┐
//! │ptr │len │cap │end │
//! └─┬──┴────┴─┬──┴─┬──┘
@ -114,16 +114,15 @@
//! └─ aligned to align_of::<*const T>() also aligned to *const T ─┘
//! ```
//!
//! [`Vec<T: ?Sized>`]: Vec
//! [`dyn_vec::Vec`]: Vec
//! [`Vec::push_unsize`]: Vec::push_unsize
//! [`Vec::unsize`]: Vec::unsize
//! [`Vec::extend_unsize`]: Vec::extend_unsize
//! [`push_box`]: Vec::push_box
//! [`push_unsize`]: Vec::push_unsize
//! [`push_unsize_stable`]: Vec::push_unsize_stable
//! [`unsize`]: Vec::unsize
//! [`unsize_stable`]: Vec::unsize_stable
//! [`DynVec<T: ?Sized>`]: DynVec
//! [`DynVec::push_unsize`]: DynVec::push_unsize
//! [`DynVec::unsize`]: DynVec::unsize
//! [`DynVec::extend_unsize`]: DynVec::extend_unsize
//! [`push_box`]: DynVec::push_box
//! [`push_unsize`]: DynVec::push_unsize
//! [`push_unsize_stable`]: DynVec::push_unsize_stable
//! [`unsize`]: DynVec::unsize
//! [`unsize_stable`]: DynVec::unsize_stable
#![cfg_attr(feature = "unstable", feature(coerce_unsized))]
#![cfg_attr(feature = "unstable", feature(set_ptr_value))]
@ -142,10 +141,8 @@ mod test;
// TODO: maybe remove this? Its not that many imports
/// Prelude, suitable for glob imports.
///
/// Using `prelude::*` will cause a conflict for the `vec!` macro. `prelude::{*, vec}` is recommended.
pub mod prelude {
pub use super::{vec, Vec};
pub use super::{dyn_vec, DynVec};
}
use core::panic;
@ -170,7 +167,7 @@ use ptr_ext::{ConstPtrExt, MutPtrExt, PtrExt};
/// A heap allocated, dynamic length collection of `?Sized` elements.
///
/// See [`std::vec::Vec`] (the standard library `Vec` type) for more information.
pub struct Vec<T: ?Sized> {
pub struct DynVec<T: ?Sized> {
ptr: NonNull<u8>,
len: usize,
capacity: usize,
@ -186,7 +183,7 @@ pub use iter::*;
/// The extra data stored at the end of the allocation.
type Extra<T> = *const T;
impl<T: ?Sized> Vec<T> {
impl<T: ?Sized> DynVec<T> {
/// Creates a new, empty vector.
pub const fn new() -> Self {
let ptr = NonNull::dangling();
@ -335,7 +332,7 @@ impl<T: ?Sized> Vec<T> {
/// Given an element, returns a pointer to where it would be written if it was pushed, assuming no reallocation is needed.
///
/// The pointer will be aligned, but writing to it may overwrite data belonging to the Vec.
/// The pointer will be aligned, but writing to it may overwrite data belonging to the vector.
/// To check for this, call `will_fit`.
/// In addition, the extra data for the element must be set using `set_extra_from_ptr`.
fn get_next_elem_ptr(&self, v: &T) -> *mut u8 {
@ -532,9 +529,9 @@ impl<T: ?Sized> Vec<T> {
IterMut::new(self)
}
/// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
/// Converts a `DynVec<T: Sized>` into a `DynVec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
#[cfg(feature = "unstable")]
pub fn unsize<U: ?Sized>(self) -> Vec<U>
pub fn unsize<U: ?Sized>(self) -> DynVec<U>
where
for<'a> &'a T: CoerceUnsized<&'a U>,
{
@ -542,10 +539,10 @@ impl<T: ?Sized> Vec<T> {
self.unsize_stable(|v| v as _)
}
/// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
/// Converts a `DynVec<T: Sized>` into a `DynVec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
///
/// The coercion is done through a closure, since `CoerceUnsized` is unstable. Usually you can pass `|v| v as _`.
pub fn unsize_stable<U: ?Sized>(mut self, coercer: Coercer<T, U>) -> Vec<U> {
pub fn unsize_stable<U: ?Sized>(mut self, coercer: Coercer<T, U>) -> DynVec<U> {
if size_of::<Extra<U>>() > size_of::<Extra<T>>() {
let elem_size = self.end_ptr.as_ptr().addr() - self.ptr.as_ptr().addr();
let extra_size = self.len * size_of::<Extra<U>>();
@ -557,7 +554,7 @@ impl<T: ?Sized> Vec<T> {
}
}
let new_vec = Vec::<U> {
let new_vec = DynVec::<U> {
ptr: self.ptr,
len: self.len,
capacity: self.capacity,
@ -663,10 +660,10 @@ impl<T: ?Sized> Vec<T> {
}
}
impl<T> Vec<[T]> {
impl<T> DynVec<[T]> {
/// Returns a slice over all the elements in the vector.
///
/// Only avaliable for `Vec<[T]>`.
/// Only avaliable for `DynVec<[T]>`.
pub fn as_slice_flatten(&self) -> &[T] {
if self.len == 0 {
return unsafe { slice::from_raw_parts(NonNull::dangling().as_ptr(), 0) };
@ -685,7 +682,7 @@ impl<T> Vec<[T]> {
/// Returns a mutable slice over all the elements in the vector.
///
/// Only avaliable for `Vec<[T]>`.
/// Only avaliable for `DynVec<[T]>`.
pub fn as_mut_slice_flatten(&mut self) -> &mut [T] {
if self.len == 0 {
return unsafe { slice::from_raw_parts_mut(NonNull::dangling().as_ptr(), 0) };
@ -703,7 +700,7 @@ impl<T> Vec<[T]> {
}
}
impl Vec<dyn Any> {
impl DynVec<dyn Any> {
/// Gets a reference to the element at then specified index, downcasting it to the specified type.
///
/// Same as `self.get(index).map(|v| v.downcast()).flatten()`.
@ -733,7 +730,7 @@ impl Vec<dyn Any> {
}
}
impl<T: ?Sized> Drop for Vec<T> {
impl<T: ?Sized> Drop for DynVec<T> {
fn drop(&mut self) {
unsafe {
for el in self.iter_mut() {
@ -745,7 +742,7 @@ impl<T: ?Sized> Drop for Vec<T> {
}
}
impl<T: ?Sized> Index<usize> for Vec<T> {
impl<T: ?Sized> Index<usize> for DynVec<T> {
type Output = T;
#[track_caller]
@ -760,7 +757,7 @@ impl<T: ?Sized> Index<usize> for Vec<T> {
}
}
impl<T: ?Sized> IndexMut<usize> for Vec<T> {
impl<T: ?Sized> IndexMut<usize> for DynVec<T> {
#[track_caller]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let len = self.len;
@ -774,42 +771,42 @@ impl<T: ?Sized> IndexMut<usize> for Vec<T> {
}
}
/// Creates a [`Vec`].
/// Creates a [`DynVec`].
///
/// # Examples
///
/// ```
/// # use dyn_vec::prelude::{vec, Vec};
/// # use dyn_vec::prelude::*;
/// # use std::fmt::Debug;
/// let vec1: Vec<i32> = vec![1, 2, 3];
/// let vec2: Vec<dyn Debug> = vec![box:
/// let vec1: DynVec<i32> = dyn_vec![1, 2, 3];
/// let vec2: DynVec<dyn Debug> = dyn_vec![box:
/// Box::new(1) as _,
/// Box::new(String::from("foo")) as _,
/// Box::new(true) as _
/// ];
/// let vec3: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
/// let vec3: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
/// ```
#[macro_export]
macro_rules! vec {
macro_rules! dyn_vec {
() => {
$crate::Vec::new();
$crate::DynVec::new();
};
(box: $($elem:expr),+ $(,)?) => {{
let mut vec = $crate::Vec::new();
let mut vec = $crate::DynVec::new();
$(vec.push_box($elem);)+
vec
}};
(unsized: $($elem:expr),+ $(,)?) => {{
let mut vec = $crate::Vec::new();
let mut vec = $crate::DynVec::new();
// TODO: when stuff stabalizes change this
$(vec.push_unsize_stable($elem, |v| v as _);)+
vec
}};
($elem:expr; $n:expr) => {
$crate::Vec::from_elem($elem, $n)
$crate::DynVec::from_elem($elem, $n)
};
($($elem:expr),+ $(,)?) => {{
let mut vec = $crate::Vec::new();
let mut vec = $crate::DynVec::new();
$(vec.push($elem);)+
vec
}};

View file

@ -2,8 +2,7 @@
use rand::{thread_rng, Rng};
// `dvec` makes r-a happy, otherwise it thinks we are using the std `vec!` macro
use super::prelude::{vec as dvec, *};
use super::prelude::*;
use std::{
any::Any,
fmt::Debug,
@ -20,7 +19,7 @@ impl<T: Debug + ?Sized> DebugExt for T {}
#[test]
fn basic_push() {
let mut vec: Vec<i32> = Vec::new();
let mut vec: DynVec<i32> = DynVec::new();
vec.push(3);
vec.push(5);
vec.push(7);
@ -29,7 +28,7 @@ fn basic_push() {
#[test]
fn box_push() {
let mut vec: Vec<dyn Debug> = Vec::new();
let mut vec: DynVec<dyn Debug> = DynVec::new();
vec.push_box(Box::new(1) as _); // makes r-a happy, idk
vec.push_box(Box::new(String::from("foo")));
vec.push_box(Box::new(true));
@ -38,7 +37,7 @@ fn box_push() {
#[test]
fn unsize_push() {
let mut vec: Vec<dyn Debug> = Vec::new();
let mut vec: DynVec<dyn Debug> = DynVec::new();
vec.push_unsize_stable(1, |v| v as _);
vec.push_unsize_stable(String::from("foo"), |v| v as _);
vec.push_unsize_stable(true, |v| v as _);
@ -47,18 +46,18 @@ fn unsize_push() {
#[test]
fn all_macro() {
let vec: Vec<i32> = dvec![3, 5, 7];
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
assert_eq!(vec, [3, 5, 7]);
let vec2: Vec<dyn Debug> = dvec![box:
let vec2: DynVec<dyn Debug> = dyn_vec![box:
Box::new(1) as _,
Box::new(String::from("foo")) as _,
Box::new(true) as _,
];
let vec3: Vec<dyn Debug> = dvec![unsized: 1, String::from("foo"), true];
let vec3: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec2.debug(), vec3.debug());
let vec4: Vec<i32> = dvec![3; 5];
let vec4: DynVec<i32> = dyn_vec![3; 5];
assert_eq!(vec4, [3; 5]);
}
@ -74,7 +73,7 @@ fn dropped() {
}
}
let vec: Vec<dyn Debug> = dvec![unsized: 1, FunkyDrop, true];
let vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, FunkyDrop, true];
assert!(!DROPPED.load(Ordering::SeqCst));
@ -85,7 +84,7 @@ fn dropped() {
#[test]
fn get() {
let vec: Vec<i32> = dvec![3, 5, 7];
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
assert_eq!(vec.get(0).copied(), Some(3));
assert_eq!(vec.get(1).copied(), Some(5));
assert_eq!(vec.get(2).copied(), Some(7));
@ -95,7 +94,7 @@ fn get() {
#[test]
#[should_panic = "index out of bounds: the len is 3 but the index is 3"]
fn index() {
let vec: Vec<i32> = dvec![3, 5, 7];
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
assert_eq!(vec[0], 3);
assert_eq!(vec[1], 5);
assert_eq!(vec[2], 7);
@ -104,7 +103,7 @@ fn index() {
#[test]
fn slice_flatten() {
let mut vec: Vec<[i32]> = dvec![unsized: [1, 2, 3], [4, 5], [6, 7, 8, 9]];
let mut vec: DynVec<[i32]> = dyn_vec![unsized: [1, 2, 3], [4, 5], [6, 7, 8, 9]];
assert_eq!(vec.as_slice_flatten(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
vec.as_mut_slice_flatten()[4] = 10;
assert_eq!(vec[1], [4, 10]);
@ -112,7 +111,7 @@ fn slice_flatten() {
#[test]
fn iteration() {
let mut vec: Vec<dyn Debug> = dvec![unsized: 1, String::from("foo"), true];
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
let mut iter = vec.iter();
assert_eq!(iter.next().unwrap().debug(), "1");
@ -126,7 +125,7 @@ fn iteration() {
assert_eq!(iter.next().unwrap().debug(), "true");
assert_eq!(iter.next().map(|_| ()), None);
let mut debugs = Vec::new(); // using custom vec instead of std vec >:)
let mut debugs = DynVec::new(); // using custom vec instead of std vec >:)
for item in vec {
debugs.push(item.debug());
}
@ -138,7 +137,7 @@ fn zst() {
#[derive(Debug, PartialEq, Eq)]
struct Zst;
let vec: Vec<Zst> = dvec![Zst, Zst, Zst];
let vec: DynVec<Zst> = dyn_vec![Zst, Zst, Zst];
assert_eq!(vec[1], Zst);
for el in vec.iter() {
@ -146,7 +145,7 @@ fn zst() {
}
assert_eq!(vec.debug(), "[Zst, Zst, Zst]");
let vec: Vec<dyn Debug> = dvec![unsized: Zst, (), Zst];
let vec: DynVec<dyn Debug> = dyn_vec![unsized: Zst, (), Zst];
assert_eq!(vec[1].debug(), "()");
for el in vec.iter() {
@ -157,7 +156,7 @@ fn zst() {
#[test]
fn downcast() {
let mut vec: Vec<dyn Any> = dvec![unsized: 1, String::from("foo"), true];
let mut vec: DynVec<dyn Any> = dyn_vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec.downcast_get::<f32>(0), None);
assert_eq!(vec.downcast_get::<i32>(0), Some(&1));
@ -172,7 +171,7 @@ fn downcast() {
#[test]
fn pop() {
let mut vec: Vec<dyn Debug> = dvec![unsized: 1, String::from("foo"), true];
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec.pop().debug(), "Some(true)");
assert_eq!(vec.pop().debug(), "Some(\"foo\")");
@ -183,7 +182,7 @@ fn pop() {
#[test]
fn with_capacity() {
// 4 and not 3 cause of `Layout::pad_to_align`
let mut vec = Vec::with_capacity(4);
let mut vec = DynVec::with_capacity(4);
let prev_ptr = vec.as_ptr();
@ -202,22 +201,22 @@ fn with_capacity() {
#[test]
fn unsize() {
let vec = dvec![1, 2, 3];
let mut vec: Vec<dyn Debug> = vec.unsize_stable(|v| v as _);
let vec = dyn_vec![1, 2, 3];
let mut vec: DynVec<dyn Debug> = vec.unsize_stable(|v| v as _);
vec.push_unsize_stable(String::from("foo"), |v| v as _);
assert_eq!(vec.debug(), "[1, 2, 3, \"foo\"]");
}
#[test]
fn remove() {
let mut vec: Vec<dyn Debug> = dvec![unsized: 1, String::from("foo"), true];
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec.remove(1).unwrap().debug(), "\"foo\"");
assert_eq!(vec.debug(), "[1, true]");
}
#[test]
fn stress_test() {
let mut vec: Vec<dyn Debug> = Vec::new();
let mut vec: DynVec<dyn Debug> = DynVec::new();
let mut rng = thread_rng();