Implement set iterators in terms of limited API

This commit is contained in:
Alex Gaynor 2020-09-08 15:19:32 -04:00
parent a009c23bb1
commit d6c9435aef

View file

@ -2,6 +2,8 @@
// //
use crate::err::{self, PyErr, PyResult}; use crate::err::{self, PyErr, PyResult};
#[cfg(Py_LIMITED_API)]
use crate::types::PyIterator;
use crate::{ use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python, ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python,
ToBorrowedObject, ToPyObject, ToBorrowedObject, ToPyObject,
@ -110,21 +112,48 @@ impl PySet {
/// Returns an iterator of values in this set. /// Returns an iterator of values in this set.
/// ///
/// Note that it can be unsafe to use when the set might be changed by other code. /// Note that it can be unsafe to use when the set might be changed by other code.
#[cfg(not(Py_LIMITED_API))]
pub fn iter(&self) -> PySetIterator { pub fn iter(&self) -> PySetIterator {
PySetIterator::new(self)
}
}
#[cfg(Py_LIMITED_API)]
pub struct PySetIterator<'py> {
it: PyIterator<'py>,
}
#[cfg(Py_LIMITED_API)]
impl PySetIterator<'_> {
fn new(set: &PyAny) -> PySetIterator {
PySetIterator { PySetIterator {
set: self.as_ref(), it: PyIterator::from_object(set.py(), set).unwrap(),
pos: 0,
} }
} }
} }
#[cfg(Py_LIMITED_API)]
impl<'py> Iterator for PySetIterator<'py> {
type Item = &'py super::PyAny;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|p| p.unwrap())
}
}
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
pub struct PySetIterator<'py> { pub struct PySetIterator<'py> {
set: &'py super::PyAny, set: &'py super::PyAny,
pos: isize, pos: isize,
} }
#[cfg(not(Py_LIMITED_API))]
impl PySetIterator<'_> {
fn new(set: &PyAny) -> PySetIterator {
PySetIterator { set, pos: 0 }
}
}
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
impl<'py> Iterator for PySetIterator<'py> { impl<'py> Iterator for PySetIterator<'py> {
type Item = &'py super::PyAny; type Item = &'py super::PyAny;
@ -145,7 +174,6 @@ impl<'py> Iterator for PySetIterator<'py> {
} }
} }
#[cfg(not(Py_LIMITED_API))]
impl<'a> std::iter::IntoIterator for &'a PySet { impl<'a> std::iter::IntoIterator for &'a PySet {
type Item = &'a PyAny; type Item = &'a PyAny;
type IntoIter = PySetIterator<'a>; type IntoIter = PySetIterator<'a>;
@ -281,22 +309,17 @@ impl PyFrozenSet {
/// Returns an iterator of values in this frozen set. /// Returns an iterator of values in this frozen set.
/// ///
/// Note that it can be unsafe to use when the set might be changed by other code. /// Note that it can be unsafe to use when the set might be changed by other code.
#[cfg(not(Py_LIMITED_API))]
pub fn iter(&self) -> PySetIterator { pub fn iter(&self) -> PySetIterator {
self.into_iter() PySetIterator::new(self.as_ref())
} }
} }
#[cfg(not(Py_LIMITED_API))]
impl<'a> std::iter::IntoIterator for &'a PyFrozenSet { impl<'a> std::iter::IntoIterator for &'a PyFrozenSet {
type Item = &'a PyAny; type Item = &'a PyAny;
type IntoIter = PySetIterator<'a>; type IntoIter = PySetIterator<'a>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
PySetIterator { self.iter()
set: self.as_ref(),
pos: 0,
}
} }
} }