Add iteration to collections.deque

This commit is contained in:
coolreader18
2019-08-12 21:47:30 -05:00
parent e5c92d6fa2
commit 277ebb240f

View File

@@ -1,5 +1,5 @@
use crate::function::OptionalArg;
use crate::obj::{objbool, objsequence, objtype::PyClassRef};
use crate::obj::{objbool, objiter, objsequence, objtype::PyClassRef};
use crate::pyobject::{IdProtocol, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::ReprGuard;
use crate::VirtualMachine;
@@ -13,6 +13,7 @@ struct PyDeque {
deque: RefCell<VecDeque<PyObjectRef>>,
maxlen: Cell<Option<usize>>,
}
type PyDequeRef = PyRef<PyDeque>;
impl PyValue for PyDeque {
fn class(vm: &VirtualMachine) -> PyClassRef {
@@ -337,10 +338,51 @@ impl PyDeque {
fn len(&self, _vm: &VirtualMachine) -> usize {
self.deque.borrow().len()
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyDequeIterator {
PyDequeIterator {
position: Cell::new(0),
deque: zelf,
}
}
}
#[pyclass(name = "_deque_iterator")]
#[derive(Debug)]
struct PyDequeIterator {
position: Cell<usize>,
deque: PyDequeRef,
}
impl PyValue for PyDequeIterator {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.class("_collections", "_deque_iterator")
}
}
#[pyimpl]
impl PyDequeIterator {
#[pymethod(name = "__next__")]
fn next(&self, vm: &VirtualMachine) -> PyResult {
if self.position.get() < self.deque.deque.borrow().len() {
let ret = self.deque.deque.borrow()[self.position.get()].clone();
self.position.set(self.position.get() + 1);
Ok(ret)
} else {
Err(objiter::new_stop_iteration(vm))
}
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
zelf
}
}
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
py_module!(vm, "_collections", {
"deque" => PyDeque::make_class(&vm.ctx),
"_deque_iterator" => PyDequeIterator::make_class(&vm.ctx),
})
}