forked from Rust-related/RustPython
Add iteration to collections.deque
This commit is contained in:
@@ -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),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user