pub struct ChunkAnyVec { /* private fields */ }Expand description
A type-erased vector containing values of the same type.
This is very similar to AnyVec except memory management. As the name
says, this vector is based on chunks. When you put values and the vector
doesn’t have sufficient capacity for them, the vector appends chunks and
then put the values in the chunks. Therefore, the vector will be more
efficient than AnyVec when frequent insertion/removal are expected.
Note, however, that the iteration performance would be worse than AnyVec
due to the split chunks in memory.
Implementations§
Source§impl ChunkAnyVec
impl ChunkAnyVec
Sourcepub fn new(tinfo: TypeInfo, chunk_cap: usize) -> Self
pub fn new(tinfo: TypeInfo, chunk_cap: usize) -> Self
Creates a new empty vector.
The vector will create and append chunks that can contain items as many as the given chunk capacity. But the type is ZST, chunk capacity is ignored.
§Panics
Panics if the given chunk capacity is not a power of two.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let chunk_cap = 2;
let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
assert_eq!(v.capacity(), 0);
unsafe {
for _ in 0..chunk_cap {
v.push(0_i32);
assert_eq!(v.capacity(), chunk_cap);
}
v.push(0_i32);
assert_eq!(v.capacity(), chunk_cap * 2);
}Sourcepub fn item_size(&self) -> usize
pub fn item_size(&self) -> usize
Returns size in bytes of the item.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let v = ChunkAnyVec::new(tinfo!(i32), 2);
assert_eq!(v.item_size(), std::mem::size_of::<i32>());Sourcepub fn is_zst(&self) -> bool
pub fn is_zst(&self) -> bool
Returns whether the item is zero-sized type or not.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let v = ChunkAnyVec::new(tinfo!(i32), 2);
assert!(!v.is_zst());
let v = ChunkAnyVec::new(tinfo!(()), 2);
assert!(v.is_zst());Sourcepub fn align(&self) -> usize
pub fn align(&self) -> usize
Returns alignment in bytes of the item.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let v = ChunkAnyVec::new(tinfo!(i32), 2);
assert_eq!(v.align(), std::mem::align_of::<i32>());Sourcepub fn fn_clone(&self) -> FnCloneRaw
pub fn fn_clone(&self) -> FnCloneRaw
Returns raw clone function pointer.
Sourcepub fn is_type_of<T: 'static>(&self) -> bool
pub fn is_type_of<T: 'static>(&self) -> bool
Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns number of item.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe { v.push(0_i32) };
assert_eq!(v.len(), 1);Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the vector is empty.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let v = ChunkAnyVec::new(tinfo!(i32), 2);
assert!(v.is_empty());Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns capacity in bytes of the vector.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
v.reserve(10);
assert!(v.capacity() >= 10);Sourcepub const fn default_chunk_capacity(&self) -> usize
pub const fn default_chunk_capacity(&self) -> usize
Returns default chunk capacity, which is a power of two.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let chunk_cap = 2;
let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
assert_eq!(v.default_chunk_capacity(), chunk_cap);Sourcepub fn num_chunks(&self) -> usize
pub fn num_chunks(&self) -> usize
Returns number of chunks.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
assert_eq!(v.num_chunks(), 0);
unsafe {
v.push(0_i32);
v.push(1_i32);
assert_eq!(v.num_chunks(), 1);
v.push(2_i32);
assert_eq!(v.num_chunks(), 2);
}Sourcepub fn get_chunk(&self, chunk_index: usize) -> Option<&AnyVec>
pub fn get_chunk(&self, chunk_index: usize) -> Option<&AnyVec>
Returns shared reference to a chunk at the given chunk index.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let chunk_cap = 2;
let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
unsafe {
v.push(0_i32);
v.push(1_i32);
v.push(2_i32);
}
let first_chunk = v.get_chunk(0).unwrap();
let first_slice = unsafe { first_chunk.as_slice::<i32>() };
assert_eq!(first_slice, &[0, 1]);Sourcepub fn iter_mut_of<T: 'static>(&mut self) -> FlatIterMut<'_, T> ⓘ
pub fn iter_mut_of<T: 'static>(&mut self) -> FlatIterMut<'_, T> ⓘ
Sourcepub fn par_iter_of<T: 'static>(&self) -> ParFlatIter<'_, T>
pub fn par_iter_of<T: 'static>(&self) -> ParFlatIter<'_, T>
Returns parallel iterator visiting all items.
Parallel iterator implements rayon’s parallel iterator traits, so
that it can be split into multiple CPU cores then consumed at the same
time.
§Panics
Panics if the given type is not the same as the vector contains.
§Examples
use my_ecs::prelude::*;
use my_ecs::ds::ChunkAnyVec;
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(1_i32);
v.push(2_i32);
v.push(3_i32);
}
let sum: i32 = v.par_iter_of::<i32>().sum();
assert_eq!(sum, 6);Sourcepub fn par_iter_mut_of<T: 'static>(&mut self) -> ParFlatIterMut<'_, T>
pub fn par_iter_mut_of<T: 'static>(&mut self) -> ParFlatIterMut<'_, T>
Returns mutable parallel iterator visiting all items.
Parallel iterator implements rayon’s parallel iterator traits, so
that it can be split into multiple CPU cores then consumed at the same
time.
§Panics
Panics if the given type is not the same as the vector contains.
§Examples
use my_ecs::prelude::*;
use my_ecs::ds::ChunkAnyVec;
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(1_i32);
v.push(2_i32);
v.push(3_i32);
}
let sum: i32 = v.par_iter_mut_of::<i32>().map(|x| *x + 1).sum();
assert_eq!(sum, 9);Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves additional capacity more than or equal to the given value.
If capacity of the vector is already sufficient, nothing takes place.
Otherwise, allocates chunks and append them to the vector so that the
capacity will be greater than or equal to self.len() + additional.
Unlike AnyVec::reserve, this method appends chunks as little as
possible.
§Panics
Panics if total memory in bytes after calling this method will exceed
isize::MAX.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
v.reserve(10);
assert!(v.capacity() >= 10);Sourcepub fn reserve_exact(&mut self, additional: usize)
pub fn reserve_exact(&mut self, additional: usize)
This method is the same as ChunkAnyVec::reserve.
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Shrinks capacity of the vector as much as possible.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let chunk_cap = 4;
let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
assert_eq!(v.capacity(), 0);
unsafe { v.push(1_i32) };
assert_eq!(v.capacity(), chunk_cap);
v.reserve(chunk_cap);
assert_eq!(v.capacity(), chunk_cap * 2);
v.shrink_to_fit();
assert_eq!(v.capacity(), chunk_cap);
v.pop_drop();
v.shrink_to_fit();
assert_eq!(v.capacity(), 0);Sourcepub unsafe fn set_len(&mut self, new_len: usize)
pub unsafe fn set_len(&mut self, new_len: usize)
Sets length of the vector to the given value without any additional operations.
§Safety
new_lenmust be less than or equal toself.capacity().- If
new_lenis greater than the previous length, caller must initialize the extended range with proper values. - If
new_lenis less than the previous length, caller must drop abandoned values from the vector properly.
Sourcepub unsafe fn push_raw(&mut self, ptr: NonNull<u8>)
pub unsafe fn push_raw(&mut self, ptr: NonNull<u8>)
Copies data as much as self.item_size() from src address to the end
of the vector.
If the vector doesn’t have sufficient capacity for the appended value,
then the vector increases its capacity first by calling
ChunkAnyVec::reserve which allocates memory more than just one value,
then does the copy.
§Safety
srcmust point to a valid type that the vector contains.srcmust not be dropped after calling this method because it is moved into the vector.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
use std::ptr::NonNull;
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
let value = 0x01020304_i32;
unsafe {
let ptr = (&value as *const i32 as *const u8).cast_mut();
v.push_raw(NonNull::new(ptr).unwrap());
assert_eq!(v.pop(), Some(value));
}Sourcepub unsafe fn push_with<F>(&mut self, write: F)
pub unsafe fn push_with<F>(&mut self, write: F)
Writes a value to the end of the vector by calling the given function.
If the vector doesn’t have sufficient capacity for the appended value,
then the vector increases its capacity first by calling
ChunkAnyVec::reserve which allocates a chunk, then does the write
operation.
§Safety
writemust write a valid type that the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
use std::ptr::{self, NonNull};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
let value = 0x01020304_i32;
unsafe {
v.push_with(|dst| {
ptr::write(dst as *mut i32, value);
});
assert_eq!(v.pop(), Some(value));
}Sourcepub unsafe fn pop_raw(&mut self, buf: *mut u8) -> Option<()>
pub unsafe fn pop_raw(&mut self, buf: *mut u8) -> Option<()>
Removes the last item from the vector and writes it to the given
buffer, then returns Some.
If removing is successful, caller becomes to own the item in the
buffer, so that caller must call drop() on it correctly.
Otherwise, returns None without change to the buffer.
§Safety
Undefined behavior if conditions below are not met.
bufmust have enough size to be copied an item.- When
Someis returned,bufmust be correctly handled as an item. For example, if an item should be dropped, caller must call drop() on it. - When
Noneis returned,bufmust be correctly handled as it was.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let chunk_cap = 4;
let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
unsafe { v.push(42_i32) };
assert_eq!(v.len(), 1);
let mut buf = 0_i32;
let res = unsafe { v.pop_raw(&mut buf as *mut i32 as *mut u8) };
assert!(res.is_some());
assert!(v.is_empty());
assert_eq!(buf, 42);Sourcepub fn pop_drop(&mut self) -> Option<()>
pub fn pop_drop(&mut self) -> Option<()>
Removes the last item from the vector then drops it immediately.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
assert_eq!(v.pop_drop(), Some(()));
}Sourcepub fn pop_forget(&mut self) -> Option<()>
pub fn pop_forget(&mut self) -> Option<()>
Removes the last item from the vector without calling drop function on it.
§Safety
Rust safety doesn’t include calling drop function. See
forget for more information. However, caller must
guarantee that not calling drop function is fine for the item.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
assert_eq!(v.pop_forget(), Some(()));
}Sourcepub unsafe fn swap_remove_raw(&mut self, index: usize, buf: *mut u8)
pub unsafe fn swap_remove_raw(&mut self, index: usize, buf: *mut u8)
Removes an item at the given index from the vector and writes it to the given buffer.
Therefore, the item is actually moved from the vector to the given buffer. So caller must take care of calling drop on it.
§Panics
Panics if the given index is out of bounds.
§Safety
Undefined behavior if conditions below are not met.
bufmust have enough size to be copied an item.- When
Someis returned,bufmust be correctly handled as an item. For example, if an item should be dropped, caller must call drop() on it. - When
Noneis returned,bufmust be correctly handled as it was.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
v.push(1_i32);
v.push(2_i32);
}
assert_eq!(v.len(), 3);
let mut buf = 3_i32;
unsafe { v.swap_remove_raw(0, &mut buf as *mut i32 as *mut u8) };
assert_eq!(buf, 0);
unsafe {
assert_eq!(v.pop::<i32>(), Some(1));
assert_eq!(v.pop::<i32>(), Some(2));
}Sourcepub unsafe fn swap_remove<T: 'static>(&mut self, index: usize) -> T
pub unsafe fn swap_remove<T: 'static>(&mut self, index: usize) -> T
Removes an item at the given index from the vector and returns it.
Then the last item of the vector is moved to the vacant slot.
§Panics
Panics if the given index is out of bounds.
§Safety
Tmust be the same type as the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
v.push(1_i32);
v.push(2_i32);
assert_eq!(v.swap_remove::<i32>(0), 0);
assert_eq!(v.swap_remove::<i32>(0), 2);
assert_eq!(v.swap_remove::<i32>(0), 1);
}Sourcepub fn swap_remove_drop(&mut self, index: usize)
pub fn swap_remove_drop(&mut self, index: usize)
Removes an item at the given index from the vector and drops it immediately.
Then the last item of the vector is moved to the vacant slot.
§Panics
Panics if the given index is out of bounds.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
v.swap_remove_drop(0);
assert!(v.is_empty());
}Sourcepub fn swap_remove_forget(&mut self, index: usize)
pub fn swap_remove_forget(&mut self, index: usize)
Removes an item at the given index from the vector without calling drop function on it.
Then the last item of the vector is moved to the vacant slot.
§Panics
Panics if given index is out of bounds.
§Safety
Rust safety doesn’t include calling drop function. See
forget for more information. However, caller must
guarantee that not calling drop function is fine for the item.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
v.swap_remove_forget(0);
assert!(v.is_empty());
}Sourcepub fn swap(&mut self, index0: usize, index1: usize)
pub fn swap(&mut self, index0: usize, index1: usize)
Replaces an item with another item in the vector.
§Panics
Panics if any given indices is out of bounds.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
v.push(1_i32);
v.swap(0, 1);
assert_eq!(v.pop(), Some(0));
assert_eq!(v.pop(), Some(1));
}Sourcepub fn get_raw(&self, index: usize) -> Option<NonNull<u8>>
pub fn get_raw(&self, index: usize) -> Option<NonNull<u8>>
Returns a pointer to an item at the given index.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
let value = 0x01020304_i32;
unsafe { v.push(value) };
let ptr = v.get_raw(0).unwrap().cast::<i32>().as_ptr().cast_const();
unsafe {
assert_eq!(std::ptr::read(ptr), value);
}Sourcepub unsafe fn get_raw_unchecked(&self, index: usize) -> NonNull<u8>
pub unsafe fn get_raw_unchecked(&self, index: usize) -> NonNull<u8>
Returns a pointer to an item at the given index.
§Safety
- Index must be in bounds.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
let value = 0x01020304_i32;
unsafe {
v.push(value);
let ptr = v.get_raw_unchecked(0)
.cast::<i32>()
.as_ptr()
.cast_const();
assert_eq!(std::ptr::read(ptr), value);
}Sourcepub unsafe fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T>
pub unsafe fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T>
Returns mutable reference to an item at the given index.
§Safety
Tmust be the same type as the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.push(0_i32);
*v.get_mut(0).unwrap() = 1_i32;
assert_eq!(v.get(0), Some(&1_i32));
}Sourcepub fn resize<T>(&mut self, new_len: usize, value: T)where
T: Clone + 'static,
pub fn resize<T>(&mut self, new_len: usize, value: T)where
T: Clone + 'static,
Resizes the vector to the given length.
If the new length is greater than previous length of the vector, then the vector is extended with the given value. Otherwise, the vector is shrunk.
§Panics
Panics if T is not the same type as the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.resize(2, 0_i32);
assert_eq!(v.pop(), Some(0_i32));
assert_eq!(v.pop(), Some(0_i32));
assert!(v.is_empty());
}Sourcepub unsafe fn resize_raw(&mut self, new_len: usize, val_ptr: NonNull<u8>)
pub unsafe fn resize_raw(&mut self, new_len: usize, val_ptr: NonNull<u8>)
Resizes the vector to the given length.
If the new length is greater than previous length of the vector, then the vector is extended with clones of a value pointed by the given pointer. Otherwise, the vector is shrunk.
§Panics
Panics if vector item is not Clone.
§Safety
val_ptrmust point to a valid type that the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
use std::ptr::NonNull;
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
let value = 0x01020304_i32;
unsafe {
let ptr = (&value as *const i32 as *const u8).cast_mut();
v.resize_raw(2, NonNull::new(ptr).unwrap());
assert_eq!(v.pop(), Some(value));
assert_eq!(v.pop(), Some(value));
assert!(v.is_empty());
}Sourcepub fn resize_with<T, F>(&mut self, new_len: usize, f: F)where
T: 'static,
F: FnMut() -> T,
pub fn resize_with<T, F>(&mut self, new_len: usize, f: F)where
T: 'static,
F: FnMut() -> T,
Resizes the vector to the given length.
If the new length is greater than previous length of the vector, then the vector is extended with values the given function generates. In this case, generated values are appended in order. Otherwise, the vector is shrunk.
§Panics
Panics if T is not the same type as the vector contains.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe {
v.resize_with(2, || 0_i32);
assert_eq!(v.pop(), Some(0_i32));
assert_eq!(v.pop(), Some(0_i32));
assert!(v.is_empty());
}Sourcepub fn truncate(&mut self, len: usize)
pub fn truncate(&mut self, len: usize)
Shrinks the vector to the given length, and drops abandoned items.
If the given length is greater than or equal to the current length of the vector, nothing takes place.
§Examples
use my_ecs::{tinfo, ds::ChunkAnyVec};
let mut v = ChunkAnyVec::new(tinfo!(i32), 2);
unsafe { v.resize(10, 0_i32) };
v.truncate(5);
assert_eq!(v.len(), 5);Trait Implementations§
Source§impl AsFlatRawIter for ChunkAnyVec
impl AsFlatRawIter for ChunkAnyVec
Source§unsafe fn iter(&self) -> FlatRawIter ⓘ
unsafe fn iter(&self) -> FlatRawIter ⓘ
§Safety
Returned iterator is not bounded by lifetime.
But it actually relies on &self, so it must be used as if
it’s borrowed.
Source§unsafe fn par_iter(&self) -> ParFlatRawIter
unsafe fn par_iter(&self) -> ParFlatRawIter
ParFlatRawIter. Read moreSource§unsafe fn iter_mut_of<T>(&mut self) -> FlatIterMut<'_, T> ⓘ
unsafe fn iter_mut_of<T>(&mut self) -> FlatIterMut<'_, T> ⓘ
Source§unsafe fn par_iter_of<T>(&self) -> ParFlatIter<'_, T>
unsafe fn par_iter_of<T>(&self) -> ParFlatIter<'_, T>
Source§unsafe fn par_iter_mut_of<T>(&mut self) -> ParFlatIterMut<'_, T>
unsafe fn par_iter_mut_of<T>(&mut self) -> ParFlatIterMut<'_, T>
Source§impl Clone for ChunkAnyVec
impl Clone for ChunkAnyVec
Source§fn clone(&self) -> ChunkAnyVec
fn clone(&self) -> ChunkAnyVec
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ChunkAnyVec
impl Debug for ChunkAnyVec
impl Resource for ChunkAnyVec
Auto Trait Implementations§
impl Freeze for ChunkAnyVec
impl RefUnwindSafe for ChunkAnyVec
impl Send for ChunkAnyVec
impl Sync for ChunkAnyVec
impl Unpin for ChunkAnyVec
impl UnwindSafe for ChunkAnyVec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more