2022-05-13 10:29:14 -05:00
//! # A [`Vec<T: ?Sized>`]
2022-08-14 14:21:40 -05:00
//!
2022-08-19 11:52:34 -05:00
//! [`dyn_vec::Vec`], a dynamic length collection of unsized elements, akin to [`std::vec::Vec`].
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! # Examples
2022-08-14 14:21:40 -05:00
//!
2022-05-13 13:14:18 -05:00
//! You can create a vector with [`Vec::new`]:
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! ```
//! # use std::fmt::Debug;
//! # use dyn_vec::prelude::*;
//! let vec: Vec<dyn Debug> = Vec::new();
//! # assert_eq!(format!("{:?}", vec), "[]");
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! or with the [`vec!`] macro:
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! # use std::fmt::Debug;
//! let vec: Vec<i32> = vec![1, 2, 3];
//! // check the docs for `vec!` for more info on this syntax
2022-05-13 13:14:18 -05:00
//! let vec_boxed: Vec<dyn Debug> = vec![box:
//! Box::new(1) as _,
//! Box::new("foo") as _,
//! Box::new(true) as _
//! ];
2022-05-13 10:29:14 -05:00
//! let vec_unsized: Vec<dyn Debug> = vec![unsized: 1, "foo", true];
2022-05-16 10:02:03 -05:00
//! let vec_from_elem: Vec<i32> = vec![3; 5];
//! # assert_eq!(vec, [1, 2, 3]);
2022-05-13 10:29:14 -05:00
//! # assert_eq!(format!("{:?}", vec_boxed), r#"[1, "foo", true]"#);
//! # assert_eq!(format!("{:?}", vec_unsized), r#"[1, "foo", true]"#);
2022-05-16 10:02:03 -05:00
//! # assert_eq!(vec_from_elem, [3; 5]);
2022-05-13 10:29:14 -05:00
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-05-13 13:14:18 -05:00
//! A vector can be pushed to with [`Vec::push`]:
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! let mut vec: Vec<i32> = vec![];
//! vec.push(1);
//! vec.push(2);
//! vec.push(3);
//! # assert_eq!(format!("{:?}", vec), "[1, 2, 3]");
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-06-08 23:00:11 -05:00
//! ...and with [`push_box`] and [`push_unsize`] ([`push_unsize_stable`] without the `"unstable"` feature):
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! ```
//! # use dyn_vec::prelude::{*, vec};
//! # use std::fmt::Debug;
//! let mut vec: Vec<dyn Debug> = vec![];
//! vec.push_box(Box::new(1));
//! vec.push_box(Box::new("foo"));
//! vec.push_box(Box::new(true));
2022-08-14 14:21:40 -05:00
//!
2022-06-08 23:00:11 -05:00
//! // these closures are only needed for the `_stable` versions
//! vec.push_unsize_stable(2, |v| v as _);
//! vec.push_unsize_stable("bar", |v| v as _);
//! vec.push_unsize_stable(false, |v| v as _);
2022-05-13 10:29:14 -05:00
//! # assert_eq!(format!("{:?}", vec), r#"[1, "foo", true, 2, "bar", false]"#);
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-06-08 23:00:11 -05:00
//! Finally, a vector can be [`unsize`]d to another vector ([`unsize_stable`] on stable):
2022-08-14 14:21:40 -05:00
//!
2022-05-16 10:42:55 -05:00
//! ```
2022-05-16 10:02:03 -05:00
//! # use dyn_vec::prelude::{*, vec};
//! # use std::fmt::Debug;
//! let vec: Vec<i32> = vec![1, 2, 3];
2022-06-08 23:00:11 -05:00
//! // vec.push_unsize_stable("foo", |v| v as _); // not yet...
//! let mut vec: Vec<dyn Debug> = vec.unsize_stable(|v| v as _);
//! vec.push_unsize_stable("foo", |v| v as _); // now we can!
2022-05-16 10:02:03 -05:00
//! # assert_eq!(format!("{:?}", vec), r#"[1, 2, 3, "foo"]"#);
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-06-08 23:00:11 -05:00
//! To use the `_stable` variations, one can generally add the argument `|v| v as _`.
2022-08-14 14:21:40 -05:00
//!
2022-08-14 18:42:10 -05:00
//! # Stability
//!
//! This crate is currently stable, but lacks some functionality. To enable this functionality, use the `"unstable"` crate feature, which depends on the following nightly features:
//! - [`#![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`]
//!
//! 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)
//! - [`#![feature(pointer_byte_offsets)]`](https://github.com/rust-lang/rust/issues/96283)
//!
//! in order to conform to [strict provenance](https://github.com/rust-lang/rust/issues/95228).
//!
2022-05-13 10:29:14 -05:00
//! # Data Layout
2022-08-14 14:21:40 -05:00
//!
2022-05-13 10:29:14 -05:00
//! ```text
//! Vec<T>
//! ┌────┬────┬────┬────┐
//! │ptr │len │cap │end │
//! └─┬──┴────┴─┬──┴─┬──┘
//! │ │ │
//! │ └────┼───────────────────────────────────────────────┐
//! ┌─┘ └───────────────────┐ │
//! │ │ │
//! ▼ ▼ ▼
//! ┌────┬────┬─────┬──────────┬───┬─────┬───────────────┬───┬───┬───┐
//! │pad │elem│pad │elem │pad│elem │ │ptr│ptr│ptr│
//! └────┴────┴─────┴──────────┴───┴─────┴───────────────┴─┬─┴─┬─┴─┬─┘
//! ▲ ▲ ▲ ▲ │ │ │ ▲
//! │ │ │ └───────────────────────┘ │ │ │
//! │ │ └──────────────────────────────────────────┘ │ │
//! │ └─────────────────────────────────────────────────────────┘ │
//! │ │
2022-08-14 15:13:56 -05:00
//! └─ aligned to align_of::<*const T>() also aligned to *const T ─┘
2022-05-13 10:29:14 -05:00
//! ```
2022-08-14 14:21:40 -05:00
//!
2022-05-13 13:14:18 -05:00
//! [`Vec<T: ?Sized>`]: Vec
2022-08-19 11:52:34 -05:00
//! [`dyn_vec::Vec`]: Vec
2022-06-08 23:00:11 -05:00
//! [`Vec::push_unsize`]: Vec::push_unsize
//! [`Vec::unsize`]: Vec::unsize
//! [`Vec::extend_unsize`]: Vec::extend_unsize
2022-05-13 10:29:14 -05:00
//! [`push_box`]: Vec::push_box
//! [`push_unsize`]: Vec::push_unsize
2022-06-08 23:00:11 -05:00
//! [`push_unsize_stable`]: Vec::push_unsize_stable
//! [`unsize`]: Vec::unsize
//! [`unsize_stable`]: Vec::unsize_stable
2022-05-13 10:29:14 -05:00
2022-06-08 23:00:11 -05:00
#![ cfg_attr(feature = " unstable " , feature(coerce_unsized)) ]
2022-08-14 17:41:10 -05:00
#![ cfg_attr(feature = " unstable " , feature(set_ptr_value)) ]
#![ cfg_attr(feature = " unstable " , feature(pointer_byte_offsets)) ]
2022-05-13 13:14:18 -05:00
#![ warn(missing_docs) ]
2022-05-16 09:42:00 -05:00
#![ warn(clippy::pedantic) ]
2022-08-14 14:21:40 -05:00
#![ warn(clippy::nursery) ]
2022-05-16 09:42:00 -05:00
#![ allow(clippy::must_use_candidate) ]
2022-08-14 14:21:40 -05:00
#![ allow(unstable_name_collisions) ]
2022-07-10 19:27:14 -05:00
#![ cfg_attr(test, feature(test)) ]
2022-08-14 14:21:40 -05:00
2022-07-10 19:27:14 -05:00
#[ cfg(test) ]
mod bench ;
2022-08-14 14:21:40 -05:00
#[ cfg(test) ]
mod test ;
2022-05-11 13:26:53 -05:00
2022-05-17 09:47:54 -05:00
// TODO: maybe remove this? Its not that many imports
2022-05-13 13:14:18 -05:00
/// Prelude, suitable for glob imports.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Using `prelude::*` will cause a conflict for the `vec!` macro. `prelude::{*, vec}` is recommended.
2022-05-13 10:29:14 -05:00
pub mod prelude {
2022-08-14 14:21:40 -05:00
pub use super ::{ vec , Vec } ;
2022-05-13 10:29:14 -05:00
}
2022-05-11 13:26:53 -05:00
use core ::panic ;
2022-05-12 08:48:32 -05:00
use std ::{
2022-08-19 11:52:34 -05:00
alloc ::{ alloc , dealloc , handle_alloc_error , Layout } ,
2022-08-14 14:21:40 -05:00
any ::Any ,
2022-05-12 08:48:32 -05:00
marker ::PhantomData ,
2022-08-19 11:52:34 -05:00
mem ::{ self , align_of , align_of_val , size_of , size_of_val , ManuallyDrop } ,
2022-06-08 23:00:11 -05:00
ops ::{ Index , IndexMut } ,
2022-08-14 14:21:40 -05:00
ptr ::{ drop_in_place , NonNull } ,
slice ,
2022-05-12 08:48:32 -05:00
} ;
2022-06-08 23:00:11 -05:00
#[ cfg(feature = " unstable " ) ]
use std ::ops ::CoerceUnsized ;
type Coercer < T , U > = for < ' a > fn ( & ' a T ) -> & ' a U ;
2022-05-17 09:47:54 -05:00
mod ptr_ext ;
2022-08-14 14:21:40 -05:00
use ptr_ext ::{ ConstPtrExt , MutPtrExt , PtrExt } ;
2022-05-11 13:26:53 -05:00
2022-05-13 10:29:14 -05:00
/// A heap allocated, dynamic length collection of `?Sized` elements.
2022-08-14 14:21:40 -05:00
///
2022-05-13 10:29:14 -05:00
/// See [`std::vec::Vec`] (the standard library `Vec` type) for more information.
2022-05-13 08:43:19 -05:00
pub struct Vec < T : ? Sized > {
2022-05-13 08:32:53 -05:00
ptr : NonNull < u8 > ,
len : usize ,
capacity : usize ,
end_ptr : NonNull < u8 > ,
2022-08-14 14:21:40 -05:00
_phantom : PhantomData < T > ,
2022-05-11 13:26:53 -05:00
}
2022-05-13 08:32:53 -05:00
// keeps this file cleaner
mod impls ;
mod iter ;
pub use iter ::* ;
2022-05-13 08:43:19 -05:00
/// The extra data stored at the end of the allocation.
type Extra < T > = * const T ;
2022-05-12 08:48:32 -05:00
2022-05-13 08:43:19 -05:00
impl < T : ? Sized > Vec < T > {
2022-05-13 13:14:18 -05:00
/// Creates a new, empty vector.
2022-08-14 14:21:40 -05:00
pub const fn new ( ) -> Self {
2022-05-11 13:26:53 -05:00
let ptr = NonNull ::dangling ( ) ;
Self {
ptr ,
len : 0 ,
capacity : 0 ,
end_ptr : ptr ,
2022-08-14 14:21:40 -05:00
_phantom : PhantomData ,
2022-05-11 13:26:53 -05:00
}
}
2022-05-16 09:42:00 -05:00
/// Creates a new vector that holds `len` copies of `v`.
2022-08-14 14:21:40 -05:00
///
2022-05-16 09:42:00 -05:00
/// Only avaliable when `T: Sized`.
2022-08-14 14:21:40 -05:00
pub fn from_elem ( v : T , len : usize ) -> Self
where
T : Sized + Clone ,
{
2022-05-16 09:42:00 -05:00
let mut vec = Self ::with_capacity ( len ) ;
for _ in 0 .. len {
vec . push ( v . clone ( ) ) ;
2022-05-13 08:59:05 -05:00
}
2022-05-16 09:42:00 -05:00
vec
}
/// Creates a new vector that can hold the given amount of `T`s.
2022-08-14 14:21:40 -05:00
///
2022-05-16 09:42:00 -05:00
/// Only avaliable when `T: Sized`.
2022-08-14 14:21:40 -05:00
pub fn with_capacity ( cap : usize ) -> Self
where
T : Sized ,
{
2022-05-16 09:42:00 -05:00
Self ::with_capacity_for ::< T > ( cap )
}
/// Creates a new vector with the given capacity, measured in bytes.\
pub fn with_capacity_bytes ( cap : usize ) -> Self {
let mut vec = Self ::new ( ) ;
2022-08-14 14:21:40 -05:00
unsafe {
vec . realloc ( cap ) ;
}
2022-05-16 09:42:00 -05:00
vec
2022-05-13 08:59:05 -05:00
}
2022-05-13 13:14:18 -05:00
/// Creates a new vector with enough capacity to hold the given amount of `U`s.
pub fn with_capacity_for < U > ( cap : usize ) -> Self {
Self ::with_capacity_bytes ( cap * ( size_of ::< U > ( ) + size_of ::< Extra < U > > ( ) ) )
}
2022-08-19 11:52:34 -05:00
/// Decomposes the vector into its raw components.
///
/// Returns the pointer to the underlying alloctaion, the number of elements,
/// the size of the allocation in bytes, and the total size of all of the
/// vector's elements.
pub fn into_raw_parts ( self ) -> ( * mut u8 , usize , usize , usize ) {
let mut this = ManuallyDrop ::new ( self ) ;
(
this . as_mut_ptr ( ) ,
this . len ( ) ,
this . capacity ( ) ,
this . data_size ( ) ,
)
}
/// Reconstructs a vector from its raw components.
///
/// # Safety
/// - `ptr` must be non-null and point to an allocation with the proper
/// data layout, as documented in the crate-level docs.
/// - `len` must be less than or equal to the number of initialized
/// elements in the allocation.
/// - `capacity` must be equal to the size of the allocation in bytes.
/// - `data_size` must be equal to the number of bytes taken up by the
/// first `len` elements of the vector, including leading (but not trailing)
/// padding.
/// - The allocation must have been allocated with alignment equal to
/// `align_of::<*const T>()`
///
/// All of these conditions are upheld by the values returned from
/// `into_raw_parts`.
pub const unsafe fn from_raw_parts (
ptr : * mut u8 ,
len : usize ,
capacity : usize ,
data_size : usize ,
) -> Self {
Self {
ptr : NonNull ::new_unchecked ( ptr ) ,
len ,
capacity ,
end_ptr : NonNull ::new_unchecked ( ptr . add ( data_size ) ) ,
_phantom : PhantomData ,
}
}
2022-05-13 13:14:18 -05:00
/// Appends an element to the end of the vector.
2022-08-14 14:21:40 -05:00
///
2022-05-13 08:32:53 -05:00
/// Only avaliable if `T: Sized`.
2022-08-14 14:21:40 -05:00
pub fn push ( & mut self , v : T )
where
T : Sized ,
{
2022-08-19 11:52:34 -05:00
unsafe { self . push_raw ( & * ManuallyDrop ::new ( v ) ) }
2022-05-11 13:26:53 -05:00
}
2022-05-13 13:14:18 -05:00
/// Appends an (possibly unsized) boxed element to the end of the vector.
2022-05-11 13:26:53 -05:00
pub fn push_box ( & mut self , v : Box < T > ) {
let ptr = Box ::into_raw ( v ) ;
unsafe {
2022-06-08 23:00:11 -05:00
let layout = Layout ::for_value ( & * ptr ) ; // ref it *before* its logically uninit
2022-05-11 13:26:53 -05:00
self . push_raw ( ptr ) ;
2022-06-08 23:00:11 -05:00
dealloc ( ptr . cast ( ) , layout ) ;
2022-05-11 13:26:53 -05:00
}
}
2022-05-13 13:14:18 -05:00
/// Appends a sized element of type `U` to the end of the vector, given that it can be `CoerceUnsized` to a `T`.
2022-06-08 23:00:11 -05:00
#[ cfg(feature = " unstable " ) ]
2022-08-14 14:21:40 -05:00
pub fn push_unsize < U > ( & mut self , v : U )
where
for < ' a > & ' a U : CoerceUnsized < & ' a T > ,
{
2022-06-08 23:00:11 -05:00
// TODO: maybe make this not call the stable version for perf?
self . push_unsize_stable ( v , | v | v as _ ) ;
}
/// Appends a sized element of type `U` to the end of the vector, given that it can be `CoerceUnsized` to a `T`.
2022-08-14 14:21:40 -05:00
///
2022-06-08 23:00:11 -05:00
/// The coercion is done through a closure, since `CoerceUnsized` is unstable. Usually you can pass `|v| v as _`.
pub fn push_unsize_stable < U > ( & mut self , v : U , coercer : Coercer < U , T > ) {
let v_unsized : & T = coercer ( & v ) ;
2022-05-11 13:26:53 -05:00
unsafe { self . push_raw ( v_unsized ) } ;
mem ::forget ( v ) ;
}
unsafe fn push_raw ( & mut self , v : * const T ) {
if ! self . will_fit ( & * v ) {
2022-06-08 23:00:11 -05:00
let new_alloc_size = self . capacity * 2 + size_of_val ( & * v ) * 2 + size_of ::< Extra < T > > ( ) ;
2022-05-11 13:26:53 -05:00
self . realloc ( new_alloc_size ) ;
}
self . push_raw_unchecked ( v ) ;
}
/// Given an element, returns a pointer to where it would be written if it was pushed, assuming no reallocation is needed.
2022-08-14 14:21:40 -05:00
///
2022-05-11 13:26:53 -05:00
/// The pointer will be aligned, but writing to it may overwrite data belonging to the Vec.
/// To check for this, call `will_fit`.
2022-05-13 08:59:05 -05:00
/// In addition, the extra data for the element must be set using `set_extra_from_ptr`.
2022-05-13 08:32:53 -05:00
fn get_next_elem_ptr ( & self , v : & T ) -> * mut u8 {
2022-05-17 09:47:54 -05:00
self . end_ptr . as_ptr ( ) . align_up ( align_of_val ( v ) )
2022-05-11 13:26:53 -05:00
}
2022-05-13 13:14:18 -05:00
/// Checks if a given element will fit in the vector without reallocations.
2022-05-11 13:26:53 -05:00
pub fn will_fit ( & self , v : & T ) -> bool {
2022-05-17 09:47:54 -05:00
let remaining_space = self . get_ptr_to_extra ( self . len ) . addr ( ) - self . end_ptr . as_ptr ( ) . addr ( ) ;
2022-05-13 08:43:19 -05:00
let needed_space = size_of_val ( v ) + size_of ::< Extra < T > > ( ) ;
2022-05-11 13:26:53 -05:00
remaining_space > = needed_space
}
unsafe fn push_raw_unchecked ( & mut self , v : * const T ) {
2022-05-17 09:47:54 -05:00
let dest = self . get_next_elem_ptr ( & * v ) . with_meta_from ( v ) ;
v . copy_val_to ( dest ) ;
self . set_extra_from_ptr ( self . len , dest ) ;
2022-05-11 13:26:53 -05:00
2022-05-17 09:47:54 -05:00
self . end_ptr = NonNull ::new_unchecked ( dest . get_end ( ) . cast ( ) ) ;
2022-05-11 13:26:53 -05:00
self . len + = 1 ;
}
2022-05-13 13:14:18 -05:00
/// Pops an element off the end of the vector, putting it in a [`Box`].
pub fn pop ( & mut self ) -> Option < Box < T > > {
unsafe {
self . len = self . len . checked_sub ( 1 ) ? ;
let el = self . get_ptr ( self . len ) ;
2022-05-17 09:47:54 -05:00
Some ( el . read_to_box ( ) )
2022-05-13 13:14:18 -05:00
}
}
2022-05-11 13:26:53 -05:00
unsafe fn realloc ( & mut self , size : usize ) {
2022-08-14 15:13:56 -05:00
let layout = Layout ::from_size_align_unchecked ( size , align_of ::< Extra < T > > ( ) ) . pad_to_align ( ) ;
2022-08-19 11:52:34 -05:00
let new_alloc = NonNull ::new ( alloc ( layout ) ) . unwrap_or_else ( | | handle_alloc_error ( layout ) ) ;
2022-05-11 13:26:53 -05:00
if self . capacity = = 0 {
// will panic if OOM
2022-08-19 11:52:34 -05:00
self . ptr = new_alloc ;
2022-05-11 13:26:53 -05:00
self . end_ptr = self . ptr ;
} else {
2022-05-17 09:47:54 -05:00
// cannot use mem::realloc here
2022-05-11 13:26:53 -05:00
// data
let mut ptr = new_alloc . as_ptr ( ) ;
for i in 0 .. self . len {
2022-05-17 09:47:54 -05:00
let v = self . get_ptr ( i ) ;
2022-06-08 23:00:11 -05:00
ptr = ptr . align_up ( align_of_val ( & * v ) ) ;
2022-05-17 09:47:54 -05:00
v . copy_val_to ( ptr ) ;
self . set_extra_from_ptr ( i , ptr . with_meta_from ( v ) ) ;
2022-06-08 23:00:11 -05:00
ptr = ptr . wrapping_add ( size_of_val ( & * v ) ) ;
2022-05-11 13:26:53 -05:00
}
self . end_ptr = NonNull ::new_unchecked ( ptr ) ;
2022-05-17 09:47:54 -05:00
// extra
let extra_src = self . get_ptr_to_extra ( self . len ) ;
let extra_dst = {
2022-05-11 13:26:53 -05:00
let current_alloc_end = self . ptr . as_ptr ( ) . wrapping_add ( self . capacity ) ;
let new_alloc_end = new_alloc . as_ptr ( ) . wrapping_add ( layout . size ( ) ) ;
2022-05-17 09:47:54 -05:00
let extra_len = current_alloc_end . addr ( ) - extra_src . addr ( ) ;
new_alloc_end . wrapping_sub ( extra_len )
2022-05-11 13:26:53 -05:00
} ;
2022-05-17 09:47:54 -05:00
extra_src . copy_to ( extra_dst . cast ( ) , self . len ) ;
2022-05-11 13:26:53 -05:00
2022-08-14 14:21:40 -05:00
dealloc (
self . ptr . as_ptr ( ) ,
Layout ::from_size_align_unchecked ( self . capacity , 8 ) ,
) ;
2022-05-11 13:26:53 -05:00
self . ptr = new_alloc ;
}
self . capacity = layout . size ( ) ;
}
/// for internal use
2022-08-14 14:21:40 -05:00
///
2022-05-17 09:47:54 -05:00
/// # Note: 1-indexed, to allow getting a pointer to the end of the alloc easily
2022-05-13 08:59:05 -05:00
fn get_ptr_to_extra ( & self , index : usize ) -> * mut Extra < T > {
2022-08-14 14:21:40 -05:00
self . ptr
. as_ptr ( )
. add_bytes ( self . capacity )
. cast ::< Extra < T > > ( )
. wrapping_sub ( index )
2022-05-11 13:26:53 -05:00
}
2022-05-13 08:59:05 -05:00
unsafe fn set_extra_from_ptr ( & self , index : usize , ptr : * const T ) {
self . get_ptr_to_extra ( index + 1 ) . write ( ptr ) ;
2022-05-12 08:48:32 -05:00
}
2022-05-11 13:26:53 -05:00
unsafe fn get_ptr ( & self , index : usize ) -> * const T {
2022-05-13 08:59:05 -05:00
* self . get_ptr_to_extra ( index + 1 )
2022-05-11 13:26:53 -05:00
}
2022-05-17 09:47:54 -05:00
unsafe fn get_ptr_before_pad ( & self , index : usize ) -> * const T {
2022-08-14 14:21:40 -05:00
self . get_ptr ( index ) . with_addr_from ( if index > 0 {
self . get_ptr ( index - 1 ) . get_end ( ) . cast ( )
} else {
self . ptr . as_ptr ( )
} )
2022-05-17 09:47:54 -05:00
}
2022-05-13 13:14:18 -05:00
/// Gets a reference to the element at the specified index.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Returns `None` if the index is out-of-bounds.
2022-05-11 13:26:53 -05:00
pub fn get ( & self , index : usize ) -> Option < & T > {
if index < self . len {
Some ( unsafe { self . get_unchecked ( index ) } )
} else {
None
}
}
2022-05-13 13:14:18 -05:00
/// Gets a reference to the element at the specified index.
2022-08-14 14:21:40 -05:00
///
2022-05-16 09:42:00 -05:00
/// # Safety
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Immediate UB if the index is out-of-bounds.
2022-05-11 13:26:53 -05:00
pub unsafe fn get_unchecked ( & self , index : usize ) -> & T {
& * self . get_ptr ( index )
}
2022-05-13 13:14:18 -05:00
/// Gets a mutable reference to the element at the specified index.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Returns `None` if the index is out-of-bounds.
2022-05-11 13:26:53 -05:00
pub fn get_mut ( & mut self , index : usize ) -> Option < & mut T > {
if index < self . len {
Some ( unsafe { self . get_unchecked_mut ( index ) } )
} else {
None
}
}
2022-05-13 13:14:18 -05:00
/// Gets a mutable reference to the element at the specified index.
2022-08-14 14:21:40 -05:00
///
2022-05-16 09:42:00 -05:00
/// # Safety
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Immediate UB if the index is out-of-bounds.
2022-05-11 13:26:53 -05:00
pub unsafe fn get_unchecked_mut ( & mut self , index : usize ) -> & mut T {
& mut * ( self . get_ptr ( index ) as * mut _ )
}
2022-05-13 13:14:18 -05:00
/// Returns the length of the vector, which is how many items it contains.
2022-08-14 14:21:40 -05:00
pub const fn len ( & self ) -> usize {
2022-05-11 13:26:53 -05:00
self . len
}
2022-05-16 09:42:00 -05:00
/// Returns `true` if the vector holds no elements.
2022-08-14 14:21:40 -05:00
pub const fn is_empty ( & self ) -> bool {
2022-05-16 09:42:00 -05:00
self . len = = 0
}
2022-05-12 08:48:32 -05:00
/// Returns the capacity, which is the size of the allocation in bytes.
2022-08-14 14:21:40 -05:00
///
2022-08-19 11:52:34 -05:00
/// Note the distinction from [`std::vec::Vec::capacity`], which returns how many *elements* it can hold.
2022-08-14 14:21:40 -05:00
pub const fn capacity ( & self ) -> usize {
2022-05-11 13:26:53 -05:00
self . capacity
}
2022-05-13 13:14:18 -05:00
/// Returns a pointer to the allocation of the vector.
2022-08-14 14:21:40 -05:00
pub const fn as_ptr ( & self ) -> * const u8 {
2022-05-11 13:26:53 -05:00
self . ptr . as_ptr ( )
}
2022-05-13 13:14:18 -05:00
/// Returns a mutable pointer to the allocation of the vector.
2022-05-11 13:26:53 -05:00
pub fn as_mut_ptr ( & mut self ) -> * mut u8 {
self . ptr . as_ptr ( )
}
2022-08-19 11:52:34 -05:00
/// Returns a pointer to the end of the last element of the vector.
pub const fn as_end_ptr ( & self ) -> * const u8 {
self . end_ptr . as_ptr ( )
}
/// Returns a mutable pointer to the end of the last element of the vector.
pub fn as_end_ptr_mut ( & mut self ) -> * const u8 {
self . end_ptr . as_ptr ( )
}
/// Returns the size (in bytes) of the elements (and padding) of the vector.
///
/// Same as `self.as_end_ptr() as usize - self.as_ptr() as usize`.
pub fn data_size ( & self ) -> usize {
self . as_end_ptr ( ) as usize - self . as_ptr ( ) as usize
}
2022-05-13 13:14:18 -05:00
/// Iterates over the vector by-ref.
2022-05-11 13:26:53 -05:00
pub fn iter ( & self ) -> Iter < T > {
Iter ::new ( self )
}
2022-05-13 13:14:18 -05:00
/// Iterates over the vector by-mut.
2022-05-11 13:26:53 -05:00
pub fn iter_mut ( & mut self ) -> IterMut < T > {
IterMut ::new ( self )
}
2022-05-12 08:48:32 -05:00
/// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
2022-06-08 23:00:11 -05:00
#[ cfg(feature = " unstable " ) ]
2022-08-14 14:21:40 -05:00
pub fn unsize < U : ? Sized > ( self ) -> Vec < U >
where
for < ' a > & ' a T : CoerceUnsized < & ' a U > ,
{
2022-06-08 23:00:11 -05:00
// TODO: maybe make this not call the stable version for perf?
self . unsize_stable ( | v | v as _ )
}
/// Converts a `Vec<T: Sized>` into a `Vec<U: ?Sized>`, given that `T` can be `CoerceUnsized` into `U`.
2022-08-14 14:21:40 -05:00
///
2022-06-08 23:00:11 -05:00
/// 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 > {
2022-05-16 10:42:55 -05:00
if size_of ::< Extra < U > > ( ) > size_of ::< Extra < T > > ( ) {
2022-05-17 09:47:54 -05:00
let elem_size = self . end_ptr . as_ptr ( ) . addr ( ) - self . ptr . as_ptr ( ) . addr ( ) ;
2022-05-16 10:42:55 -05:00
let extra_size = self . len * size_of ::< Extra < U > > ( ) ;
let needed_size = elem_size + extra_size ;
if needed_size > self . capacity {
2022-08-14 14:21:40 -05:00
unsafe {
self . realloc ( needed_size ) ;
}
2022-05-16 10:42:55 -05:00
}
}
2022-05-16 10:02:03 -05:00
2022-05-11 13:26:53 -05:00
let new_vec = Vec ::< U > {
ptr : self . ptr ,
len : self . len ,
capacity : self . capacity ,
end_ptr : self . end_ptr ,
_phantom : PhantomData ,
} ;
2022-05-13 08:43:19 -05:00
if size_of ::< Extra < U > > ( ) > size_of ::< Extra < T > > ( ) {
// new extra larger than old extra, must go from back to front
2022-05-11 13:26:53 -05:00
2022-05-12 08:48:32 -05:00
for i in ( 0 .. self . len ) . rev ( ) {
2022-05-17 09:47:54 -05:00
// using references here is necessary for unsizing coercion to work
2022-05-12 08:48:32 -05:00
let current = unsafe { & * self . get_ptr ( i ) } ;
2022-06-08 23:00:11 -05:00
unsafe { new_vec . set_extra_from_ptr ( i , coercer ( current ) ) }
2022-05-11 13:26:53 -05:00
}
} else {
2022-05-13 08:43:19 -05:00
// new extra smaller or same size as old extra, must go from front to back
2022-05-11 13:26:53 -05:00
2022-05-12 08:48:32 -05:00
for i in 0 .. self . len {
2022-05-17 09:47:54 -05:00
// using references here is necessary for unsizing coercion to work
2022-05-12 08:48:32 -05:00
let current = unsafe { & * self . get_ptr ( i ) } ;
2022-06-08 23:00:11 -05:00
unsafe { new_vec . set_extra_from_ptr ( i , coercer ( current ) ) }
2022-05-11 13:26:53 -05:00
}
}
mem ::forget ( self ) ;
new_vec
}
2022-05-13 10:29:14 -05:00
unsafe fn dealloc ( & self ) {
if self . capacity ! = 0 {
2022-08-14 14:21:40 -05:00
dealloc (
self . ptr . as_ptr ( ) ,
2022-08-14 15:13:56 -05:00
Layout ::from_size_align_unchecked ( self . capacity , align_of ::< Extra < T > > ( ) ) ,
2022-08-14 14:21:40 -05:00
) ;
2022-05-13 10:29:14 -05:00
}
}
2022-05-13 14:26:32 -05:00
/// Extends this vector with an iterator.
2022-08-14 14:21:40 -05:00
///
2022-05-13 14:26:32 -05:00
/// Similar to [`Extend::extend`], but seperate to prevent conflicting implementations.
2022-06-08 23:00:11 -05:00
#[ cfg(feature = " unstable " ) ]
2022-08-14 14:21:40 -05:00
pub fn extend_unsize < U , I : IntoIterator < Item = U > > ( & mut self , iter : I )
where
for < ' a > & ' a U : CoerceUnsized < & ' a T > ,
{
2022-06-08 23:00:11 -05:00
// TODO: maybe make this not call the stable version for perf?
self . extend_unsize_stable ( iter , | v | v as _ ) ;
}
/// Extends this vector with an iterator.
2022-08-14 14:21:40 -05:00
///
2022-06-08 23:00:11 -05:00
/// Similar to [`Extend::extend`], but seperate to prevent conflicting implementations.
2022-08-14 14:21:40 -05:00
///
2022-06-08 23:00:11 -05:00
/// The coercion is done through a closure, since `CoerceUnsized` is unstable. Usually you can pass `|v| v as _`.
2022-08-14 14:21:40 -05:00
pub fn extend_unsize_stable < U , I : IntoIterator < Item = U > > (
& mut self ,
iter : I ,
coercer : Coercer < U , T > ,
) {
2022-05-13 14:26:32 -05:00
for item in iter {
2022-06-08 23:00:11 -05:00
self . push_unsize_stable ( item , coercer ) ;
2022-05-13 14:26:32 -05:00
}
}
2022-05-17 09:47:54 -05:00
/// Removes the element at the specified index, shifting other elements over to fill the gap.
2022-08-14 14:21:40 -05:00
pub fn remove ( & mut self , index : usize ) -> Option < Box < T > > {
2022-05-17 09:47:54 -05:00
if index > = self . len {
2022-08-14 14:21:40 -05:00
return None ;
2022-05-17 09:47:54 -05:00
}
if index = = self . len - 1 {
2022-08-14 14:21:40 -05:00
return self . pop ( ) ;
2022-05-17 09:47:54 -05:00
}
unsafe {
let res = Some ( self . get_ptr ( index ) . read_to_box ( ) ) ;
// starting from the now-empty spot, up to but not including the end...
2022-08-14 14:21:40 -05:00
for index in index .. self . len - 1 {
2022-05-17 09:47:54 -05:00
// get a pointer to the end of the previous element
let mut new_ptr = self . get_ptr_before_pad ( index ) ;
// align it up to the align of the NEXT element
let next_ptr = self . get_ptr ( index + 1 ) ;
2022-06-08 23:00:11 -05:00
new_ptr = new_ptr . align_up ( align_of_val ( & * next_ptr ) ) ;
2022-08-14 14:21:40 -05:00
2022-05-17 09:47:54 -05:00
// if its the same, we can break as the rest will be useless
2022-08-14 14:21:40 -05:00
if new_ptr = = next_ptr {
break ;
}
2022-05-17 09:47:54 -05:00
// data
next_ptr . copy_val_to ( new_ptr as * mut T ) ;
// extra
self . set_extra_from_ptr ( index , new_ptr . with_meta_from ( next_ptr ) ) ;
}
self . len - = 1 ;
2022-08-14 14:21:40 -05:00
2022-05-17 09:47:54 -05:00
res
}
}
2022-05-11 13:26:53 -05:00
}
impl < T > Vec < [ T ] > {
2022-05-13 13:14:18 -05:00
/// Returns a slice over all the elements in the vector.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Only avaliable for `Vec<[T]>`.
2022-05-11 13:26:53 -05:00
pub fn as_slice_flatten ( & self ) -> & [ T ] {
2022-05-16 09:42:00 -05:00
if self . len = = 0 {
2022-08-14 14:21:40 -05:00
return unsafe { slice ::from_raw_parts ( NonNull ::dangling ( ) . as_ptr ( ) , 0 ) } ;
2022-05-16 09:42:00 -05:00
}
2022-05-11 13:26:53 -05:00
// SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked`
unsafe {
2022-05-17 09:47:54 -05:00
slice ::from_raw_parts ( self . get_ptr ( 0 ) . data_ptr ( ) . cast ( ) , {
let start = self . get_ptr ( 0 ) . addr ( ) ;
let end = self . end_ptr . as_ptr ( ) . addr ( ) ;
2022-05-16 09:42:00 -05:00
debug_assert_eq! ( ( end - start ) % size_of ::< T > ( ) , 0 ) ;
2022-05-11 13:26:53 -05:00
( end - start ) / size_of ::< T > ( ) // integer division!
} )
}
}
2022-05-13 13:14:18 -05:00
/// Returns a mutable slice over all the elements in the vector.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// Only avaliable for `Vec<[T]>`.
2022-05-11 13:26:53 -05:00
pub fn as_mut_slice_flatten ( & mut self ) -> & mut [ T ] {
2022-05-16 09:42:00 -05:00
if self . len = = 0 {
2022-08-14 14:21:40 -05:00
return unsafe { slice ::from_raw_parts_mut ( NonNull ::dangling ( ) . as_ptr ( ) , 0 ) } ;
2022-05-16 09:42:00 -05:00
}
2022-05-11 13:26:53 -05:00
// SAFETY: the slices should be contiguous by the logic of `push_raw_unchecked`
unsafe {
2022-05-17 09:47:54 -05:00
slice ::from_raw_parts_mut ( self . get_ptr ( 0 ) . data_ptr ( ) as _ , {
let start = self . get_ptr ( 0 ) . addr ( ) ;
let end = self . end_ptr . as_ptr ( ) . addr ( ) ;
2022-05-16 09:42:00 -05:00
debug_assert_eq! ( ( end - start ) % size_of ::< T > ( ) , 0 ) ;
2022-05-11 13:26:53 -05:00
( end - start ) / size_of ::< T > ( ) // integer division!
} )
}
}
}
2022-05-13 13:14:18 -05:00
impl Vec < dyn Any > {
/// Gets a reference to the element at then specified index, downcasting it to the specified type.
2022-08-14 14:21:40 -05:00
///
2022-08-19 11:52:34 -05:00
/// Same as `self.get(index).map(|v| v.downcast()).flatten()`.
2022-05-13 13:14:18 -05:00
pub fn downcast_get < T : Any > ( & self , index : usize ) -> Option < & T > {
self . get ( index ) ? . downcast_ref ( )
}
/// Gets a mutable reference to the element at then specified index, downcasting it to the specified type.
2022-08-14 14:21:40 -05:00
///
2022-08-19 11:52:34 -05:00
/// Same as `self.get_mut(index).map(|v| v.downcast_mut()).flatten()`.
2022-05-13 13:14:18 -05:00
pub fn downcast_get_mut < T : Any > ( & mut self , index : usize ) -> Option < & mut T > {
self . get_mut ( index ) ? . downcast_mut ( )
}
/// Pops an element off the end of the vector, downcasting it to the specified type.
2022-08-14 14:21:40 -05:00
///
2022-05-13 13:14:18 -05:00
/// If the element is not of type `T`, the element will not be popped.
2022-08-14 14:21:40 -05:00
///
2022-08-19 11:52:34 -05:00
/// Same as `self.pop().map(|v| v.downcast()).flatten()`, but without an intermediate allocation.
2022-05-13 13:14:18 -05:00
pub fn downcast_pop < T : Any > ( & mut self ) -> Option < T > {
unsafe {
2022-05-17 09:47:54 -05:00
let el = self . get_unchecked_mut ( self . len . checked_sub ( 1 ) ? ) ;
let v = Some ( ( el . downcast_mut ( ) ? as * mut T ) . read ( ) ) ;
2022-05-13 13:14:18 -05:00
self . len - = 1 ;
v
}
}
}
2022-05-11 13:26:53 -05:00
impl < T : ? Sized > Drop for Vec < T > {
fn drop ( & mut self ) {
unsafe {
2022-06-08 23:00:11 -05:00
for el in self . iter_mut ( ) {
drop_in_place ( el ) ;
2022-05-11 13:26:53 -05:00
}
2022-06-08 23:00:11 -05:00
2022-05-13 10:29:14 -05:00
self . dealloc ( ) ;
2022-05-11 13:26:53 -05:00
}
}
}
impl < T : ? Sized > Index < usize > for Vec < T > {
type Output = T ;
#[ track_caller ]
fn index ( & self , index : usize ) -> & Self ::Output {
match self . get ( index ) {
Some ( v ) = > v ,
2022-08-14 14:21:40 -05:00
None = > panic! (
" index out of bounds: the len is {} but the index is {} " ,
self . len , index
) ,
2022-05-11 13:26:53 -05:00
}
}
}
impl < T : ? Sized > IndexMut < usize > for Vec < T > {
#[ track_caller ]
fn index_mut ( & mut self , index : usize ) -> & mut Self ::Output {
let len = self . len ;
match self . get_mut ( index ) {
Some ( v ) = > v ,
2022-08-14 14:21:40 -05:00
None = > panic! (
" index out of bounds: the len is {} but the index is {} " ,
len , index
) ,
2022-05-11 13:26:53 -05:00
}
}
}
/// Creates a [`Vec`].
2022-08-14 14:21:40 -05:00
///
2022-05-11 13:26:53 -05:00
/// # Examples
2022-08-14 14:21:40 -05:00
///
2022-05-11 13:26:53 -05:00
/// ```
/// # use dyn_vec::prelude::{vec, Vec};
/// # use std::fmt::Debug;
2022-05-16 10:02:03 -05:00
/// let vec1: Vec<i32> = vec![1, 2, 3];
2022-05-11 13:26:53 -05:00
/// let vec2: Vec<dyn Debug> = 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];
/// ```
#[ macro_export ]
macro_rules ! vec {
( ) = > {
2022-08-14 14:21:40 -05:00
$crate ::Vec ::new ( ) ;
2022-05-11 13:26:53 -05:00
} ;
( box : $( $elem :expr ) , + $(, ) ? ) = > { {
let mut vec = $crate ::Vec ::new ( ) ;
$( vec . push_box ( $elem ) ; ) +
vec
} } ;
( unsized : $( $elem :expr ) , + $(, ) ? ) = > { {
let mut vec = $crate ::Vec ::new ( ) ;
2022-06-08 23:00:11 -05:00
// TODO: when stuff stabalizes change this
$( vec . push_unsize_stable ( $elem , | v | v as _ ) ; ) +
2022-05-11 13:26:53 -05:00
vec
} } ;
( $elem :expr ; $n :expr ) = > {
2022-05-16 09:42:00 -05:00
$crate ::Vec ::from_elem ( $elem , $n )
2022-05-11 13:26:53 -05:00
} ;
( $( $elem :expr ) , + $(, ) ? ) = > { {
let mut vec = $crate ::Vec ::new ( ) ;
$( vec . push ( $elem ) ; ) +
vec
} } ;
2022-08-14 14:21:40 -05:00
}