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;
use crate::types::ListTypeRev;

/// Mutable iterator for a [`DynList`].
pub struct IterMut<'a, T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized + 'a,
	Typ: ListType<T>,
{
	pub(crate) list: &'a mut DynList<T, Typ>,
	pub(crate) offset: usize,
	pub(crate) index: usize,
	pub(crate) rev_offset: usize,
	pub(crate) rev_index: usize,
}
impl<'a, T, Typ> Iterator for IterMut<'a, T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
	type Item = &'a mut T;

	fn next(&mut self) -> Option<Self::Item> {
		if self.offset >= self.rev_offset {
			debug_assert_eq!(self.offset, self.rev_offset);
			debug_assert_eq!(self.index, self.rev_index);
			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(unsafe { &mut *p })
	}

	fn size_hint(&self) -> (usize, Option<usize>) {
		let n = self.rev_index - self.index;
		(n, Some(n))
	}
}
impl<'a, T, Typ> DoubleEndedIterator for IterMut<'a, T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListTypeRev<T>,
{
	fn next_back(&mut self) -> Option<Self::Item> {
		if self.offset >= self.rev_offset {
			debug_assert_eq!(self.offset, self.rev_offset);
			debug_assert_eq!(self.index, self.rev_index);
			return None;
		}
		let size = unsafe {
			self.list
				.typ
				.prev_entry_size(self.list.data.as_ptr(), self.rev_offset, self.rev_index)
		};
		debug_assert!(
			self.rev_offset >= size,
			"SOUNDNESS BUG: prev_entry_size returned too big of a size. rev_offset = {} but prev_entry_size returned {}",
			self.rev_offset,
			size
		);
		self.rev_offset -= size;
		self.rev_index -= 1;

		let (p, s) = unsafe {
			self.list
				.typ
				.read_entry(self.list.data.as_ptr(), self.rev_offset, self.rev_index)
		};
		debug_assert_eq!(s, size);

		Some(unsafe { &mut *p })
	}
}
impl<'a, T, Typ> ExactSizeIterator for IterMut<'a, T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
}
impl<'a, T, Typ> IterMut<'a, T, Typ>
where
	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
	Typ: ListType<T>,
{
	/// Creates an immutable iterator starting from this iterator's position.
	///
	/// This can be used to "look ahead" in the list.
	pub fn as_immutable<'b>(&'b self) -> crate::iters::Iter<'b, T, Typ> {
		crate::iters::Iter {
			list: &*self.list,
			offset: self.offset,
			index: self.index,
			rev_offset: self.rev_offset,
			rev_index: self.rev_index,
		}
	}
}