// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::marker::PhantomData;
use std::ptr;

pub struct SwapRemoveIterator<'a, T> {
	vec: *mut Vec<T>,
	i: usize,
	_data: PhantomData<&'a mut T>,
}

impl<T> SwapRemoveIterator<'_, T> {
	pub fn new(vec: &mut Vec<T>) -> SwapRemoveIterator<'_, T> {
		SwapRemoveIterator {
			vec: ptr::from_mut(vec),
			i: 0,
			_data: PhantomData,
		}
	}

	pub fn next(&mut self) -> Option<&mut T> {
		// SAFETY: Pointer to vector is valid due to PhantomData
		let vec = unsafe { &mut (*self.vec) };
		(self.i < vec.len()).then(|| {
			// SAFETY: Index just bounds checked
			let ret = unsafe { vec.get_unchecked_mut(self.i) };
			self.i += 1;
			ret
		})
	}

	pub fn remove(&mut self) -> T {
		self.i -= 1;

		// SAFETY: Pointer to vector is valid due to PhantomData
		unsafe { &mut (*self.vec) }.swap_remove(self.i)
	}
}
