X Tutup
using System; using System.Collections.Generic; using System.Runtime.Serialization; namespace Python.Runtime { /// /// Represents a standard Python iterator object. See the documentation at /// PY2: https://docs.python.org/2/c-api/iterator.html /// PY3: https://docs.python.org/3/c-api/iterator.html /// for details. /// public class PyIter : PyObject, IEnumerator { private PyObject? _current; /// /// PyIter Constructor /// /// /// Creates a new PyIter from an existing iterator reference. Note /// that the instance assumes ownership of the object reference. /// The object reference is not checked for type-correctness. /// internal PyIter(in StolenReference reference) : base(reference) { } /// /// Creates new from an untyped reference to Python object. /// The object must support iterator protocol. /// public PyIter(PyObject pyObject) : base(FromPyObject(pyObject)) { } static BorrowedReference FromPyObject(PyObject pyObject) { if (pyObject is null) throw new ArgumentNullException(nameof(pyObject)); if (!Runtime.PyIter_Check(pyObject.Reference)) throw new ArgumentException("Object does not support iterator protocol"); return pyObject.Reference; } internal PyIter(BorrowedReference reference) : base(reference) { } /// /// Create a new from a given iterable. /// /// Like doing "iter()" in Python. /// public static PyIter GetIter(PyObject iterable) { if (iterable == null) { throw new ArgumentNullException(); } var val = Runtime.PyObject_GetIter(iterable.Reference); PythonException.ThrowIfIsNull(val); return new PyIter(val.Steal()); } protected override void Dispose(bool disposing) { _current = null; base.Dispose(disposing); } public bool MoveNext() { NewReference next = Runtime.PyIter_Next(Reference); if (next.IsNull()) { if (Exceptions.ErrorOccurred()) { throw PythonException.ThrowLastAsClrException(); } // stop holding the previous object, if there was one _current = null; return false; } _current = next.MoveToPyObject(); return true; } public void Reset() { throw new NotSupportedException(); } public PyObject Current => _current ?? throw new InvalidOperationException(); object System.Collections.IEnumerator.Current => Current; protected PyIter(SerializationInfo info, StreamingContext context) : base(info, context) { _current = (PyObject?)info.GetValue("c", typeof(PyObject)); } protected override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("c", _current); } } }
X Tutup