use crate::ffi;
use std::mem;
enum PyObjectSlot {
Empty,
Filled(*mut ffi::PyObject),
}
unsafe impl Send for PyObjectSlot {}
pub struct PyObjectFreeList {
entries: Box<[PyObjectSlot]>,
split: usize,
capacity: usize,
}
impl PyObjectFreeList {
pub fn with_capacity(capacity: usize) -> PyObjectFreeList {
let entries = (0..capacity)
.map(|_| PyObjectSlot::Empty)
.collect::<Box<[_]>>();
PyObjectFreeList {
entries,
split: 0,
capacity,
}
}
pub fn pop(&mut self) -> Option<*mut ffi::PyObject> {
let idx = self.split;
if idx == 0 {
None
} else {
match mem::replace(&mut self.entries[idx - 1], PyObjectSlot::Empty) {
PyObjectSlot::Filled(v) => {
self.split = idx - 1;
Some(v)
}
_ => panic!("PyObjectFreeList is corrupt"),
}
}
}
pub fn insert(&mut self, val: *mut ffi::PyObject) -> Option<*mut ffi::PyObject> {
let next = self.split + 1;
if next < self.capacity {
self.entries[self.split] = PyObjectSlot::Filled(val);
self.split = next;
None
} else {
Some(val)
}
}
}