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};
#[cfg(Py_LIMITED_API)]
use crate::types::PyIterator;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python,
ToBorrowedObject, ToPyObject,
@ -110,21 +112,48 @@ impl PySet {
/// 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.
#[cfg(not(Py_LIMITED_API))]
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 {
set: self.as_ref(),
pos: 0,
it: PyIterator::from_object(set.py(), set).unwrap(),
}
}
}
#[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))]
pub struct PySetIterator<'py> {
set: &'py super::PyAny,
pos: isize,
}
#[cfg(not(Py_LIMITED_API))]
impl PySetIterator<'_> {
fn new(set: &PyAny) -> PySetIterator {
PySetIterator { set, pos: 0 }
}
}
#[cfg(not(Py_LIMITED_API))]
impl<'py> Iterator for PySetIterator<'py> {
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 {
type Item = &'a PyAny;
type IntoIter = PySetIterator<'a>;
@ -281,22 +309,17 @@ impl PyFrozenSet {
/// 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.
#[cfg(not(Py_LIMITED_API))]
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 {
type Item = &'a PyAny;
type IntoIter = PySetIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
PySetIterator {
set: self.as_ref(),
pos: 0,
}
self.iter()
}
}