use super::{ffi, solvable::SolvableId};
use std::marker::PhantomData;
pub struct Queue<T> {
queue: ffi::Queue,
_data: PhantomData<T>,
}
impl<T> Default for Queue<T> {
fn default() -> Self {
let mut queue = ffi::Queue {
elements: std::ptr::null_mut(),
count: 0,
alloc: std::ptr::null_mut(),
left: 0,
};
unsafe { ffi::queue_init(&mut queue as *mut ffi::Queue) };
Self {
queue,
_data: PhantomData,
}
}
}
impl<T> Drop for Queue<T> {
fn drop(&mut self) {
unsafe {
ffi::queue_free(self.raw_ptr());
}
}
}
impl<T> Queue<T> {
pub(super) fn raw_ptr(&mut self) -> *mut ffi::Queue {
&mut self.queue as *mut ffi::Queue
}
}
impl<T: Into<ffi::Id>> Queue<T> {
#[allow(dead_code)]
pub fn push_id(&mut self, id: T) {
unsafe {
ffi::queue_insert(self.raw_ptr(), self.queue.count, id.into());
}
}
pub fn id_iter(&self) -> impl Iterator<Item = ffi::Id> + '_ {
unsafe { std::slice::from_raw_parts(self.queue.elements as _, self.queue.count as usize) }
.iter()
.copied()
}
}
pub struct QueueRef<'queue>(ffi::Queue, PhantomData<&'queue ffi::Queue>);
impl QueueRef<'_> {
pub(super) unsafe fn from_ffi_queue<T>(_source: &T, queue: ffi::Queue) -> QueueRef<'_> {
QueueRef(queue, PhantomData)
}
pub fn iter(&self) -> impl Iterator<Item = SolvableId> + '_ {
(0..self.0.count as usize).map(|index| {
let id = unsafe { *self.0.elements.add(index) };
SolvableId(id)
})
}
}
#[cfg(test)]
mod test {
use super::{super::pool::StringId, Queue};
#[test]
fn create_queue() {
let _queue = Queue::<StringId>::default();
}
}