trait-obj-list 0.1.2

List of unsized trait objects, stored in a flat array
Documentation
use crate::DynList;
use crate::ptr;
use crate::types::ListType;

/// Iterator that transfers ownership of items by yielding pointers to them.
///
/// The pointers are valid until the `IntoPtrsIter` structure is dropped, at
/// which point they are all deallocated.
///
/// Yielded pointers will not have their contents dropped, so it is safe to
/// move the data out of them. Any remaining unyielded pointers will have their
/// contents dropped once the iterator is dropped.
pub struct IntoPtrsIter<T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
	pub(crate) list: DynList<T, Typ>,
	pub(crate) offset: usize,
	pub(crate) index: usize,
}
impl<T, Typ> Iterator for IntoPtrsIter<T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
	type Item = *mut T;

	fn next(&mut self) -> Option<Self::Item> {
		if self.offset >= self.list.end {
			return None;
		}
		let (p, size) = unsafe {
			self.list
				.typ
				.read_entry(self.list.data.as_ptr(), self.offset, self.index)
		};
		self.offset += size;
		self.index += 1;
		Some(p)
	}

	fn size_hint(&self) -> (usize, Option<usize>) {
		let n = self.list.typ.num_items() - self.index;
		(n, Some(n))
	}
}
impl<T, Typ> ExactSizeIterator for IntoPtrsIter<T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
}
impl<T, Typ> core::ops::Drop for IntoPtrsIter<T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
	fn drop(&mut self) {
		unsafe {
			while self.offset < self.list.end {
				let (p, size) =
					self.list
						.typ
						.read_entry(self.list.data.as_ptr(), self.offset, self.index);
				core::ptr::drop_in_place(p);
				self.offset += size;
				self.index += 1;
			}
			self.list.realloc_to(0);
			self.list.end = 0;
			self.list.capacity = 0;
		}
	}
}