Add IntoIterator impl for PyTuple and PyList.

This commit is contained in:
Daniel Grunwald 2015-05-24 18:20:35 +02:00
parent d70479d257
commit db47455904
2 changed files with 96 additions and 0 deletions

View File

@ -75,6 +75,49 @@ impl <'p> PyList<'p> {
}
}
impl <'p> IntoIterator for PyList<'p> {
type Item = PyObject<'p>;
type IntoIter = PyListIterator<'p>;
#[inline]
fn into_iter(self) -> PyListIterator<'p> {
PyListIterator { list: self, index: 0 }
}
}
impl <'a, 'p> IntoIterator for &'a PyList<'p> {
type Item = PyObject<'p>;
type IntoIter = PyListIterator<'p>;
#[inline]
fn into_iter(self) -> PyListIterator<'p> {
PyListIterator { list: self.clone(), index: 0 }
}
}
pub struct PyListIterator<'p> {
list: PyList<'p>,
index: usize
}
impl <'p> Iterator for PyListIterator<'p> {
type Item = PyObject<'p>;
#[inline]
fn next(&mut self) -> Option<PyObject<'p>> {
if self.index < self.list.len() {
let item = self.list.get_item(self.index);
self.index += 1;
Some(item)
} else {
None
}
}
// Note: we cannot implement size_hint because the length of the list
// might change during the iteration.
}
impl <'p, T> ToPyObject<'p> for [T] where T: ToPyObject<'p> {
type ObjectType = PyList<'p>;

View File

@ -81,6 +81,59 @@ impl <'p> PyTuple<'p> {
*/
}
impl <'p> IntoIterator for PyTuple<'p> {
type Item = PyObject<'p>;
type IntoIter = PyTupleIterator<'p>;
#[inline]
fn into_iter(self) -> PyTupleIterator<'p> {
PyTupleIterator { index: 0, len: self.len(), tuple: self }
}
}
impl <'a, 'p> IntoIterator for &'a PyTuple<'p> {
type Item = PyObject<'p>;
type IntoIter = PyTupleIterator<'p>;
#[inline]
fn into_iter(self) -> PyTupleIterator<'p> {
PyTupleIterator { index: 0, len: self.len(), tuple: self.clone() }
}
}
pub struct PyTupleIterator<'p> {
tuple: PyTuple<'p>,
index: usize,
len: usize
}
impl <'p> Iterator for PyTupleIterator<'p> {
type Item = PyObject<'p>;
#[inline]
fn next(&mut self) -> Option<PyObject<'p>> {
if self.index < self.len {
let item = self.tuple.get_item(self.index);
self.index += 1;
Some(item)
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl <'p> ExactSizeIterator for PyTupleIterator<'p> {
#[inline]
fn len(&self) -> usize {
return self.len;
}
}
fn wrong_tuple_length<'p>(t: &PyTuple<'p>, expected_length: usize) -> PyErr<'p> {
let py = t.python();
let msg = format!("Expected tuple of length {}, but got tuple of length {}.", expected_length, t.len());