Skip to content

Commit 0531148

Browse files
committed
Adding iterobject.[ch], which were accidentally not added. Sorry\!
1 parent 59d1d2b commit 0531148

2 files changed

Lines changed: 201 additions & 0 deletions

File tree

Include/iterobject.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* Iterators (the basic kind, over a sequence) */
2+
3+
extern DL_IMPORT(PyTypeObject) PyIter_Type;
4+
5+
#define PyIter_Check(op) ((op)->ob_type == &PyIter_Type)
6+
7+
extern DL_IMPORT(PyObject *) PyIter_New(PyObject *);
8+
9+
extern DL_IMPORT(PyTypeObject) PyCallIter_Type;
10+
11+
#define PyCallIter_Check(op) ((op)->ob_type == &PyCallIter_Type)
12+
13+
extern DL_IMPORT(PyObject *) PyCallIter_New(PyObject *, PyObject *);

Objects/iterobject.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/* Iterator objects */
2+
3+
#include "Python.h"
4+
5+
typedef struct {
6+
PyObject_HEAD
7+
long it_index;
8+
PyObject *it_seq;
9+
} iterobject;
10+
11+
PyObject *
12+
PyIter_New(PyObject *seq)
13+
{
14+
iterobject *it;
15+
it = PyObject_NEW(iterobject, &PyIter_Type);
16+
if (it == NULL)
17+
return NULL;
18+
it->it_index = 0;
19+
Py_INCREF(seq);
20+
it->it_seq = seq;
21+
return (PyObject *)it;
22+
}
23+
static void
24+
iter_dealloc(iterobject *it)
25+
{
26+
Py_DECREF(it->it_seq);
27+
PyObject_DEL(it);
28+
}
29+
30+
static PyObject *
31+
iter_next(iterobject *it, PyObject *args)
32+
{
33+
PyObject *seq = it->it_seq;
34+
35+
if (PyList_Check(seq)) {
36+
PyObject *item;
37+
if (it->it_index >= PyList_GET_SIZE(seq)) {
38+
PyErr_SetObject(PyExc_StopIteration, Py_None);
39+
return NULL;
40+
}
41+
item = PyList_GET_ITEM(seq, it->it_index);
42+
it->it_index++;
43+
Py_INCREF(item);
44+
return item;
45+
}
46+
else {
47+
PyObject *result = PySequence_GetItem(seq, it->it_index++);
48+
if (result == NULL &&
49+
PyErr_ExceptionMatches(PyExc_IndexError))
50+
PyErr_SetObject(PyExc_StopIteration, Py_None);
51+
return result;
52+
}
53+
}
54+
55+
static PyObject *
56+
iter_getiter(PyObject *it)
57+
{
58+
Py_INCREF(it);
59+
return it;
60+
}
61+
62+
static PyMethodDef iter_methods[] = {
63+
{"next", (PyCFunction)iter_next, METH_VARARGS,
64+
"it.next() -- get the next value, or raise StopIteration"},
65+
{NULL, NULL} /* sentinel */
66+
};
67+
68+
static PyObject *
69+
iter_getattr(iterobject *it, char *name)
70+
{
71+
return Py_FindMethod(iter_methods, (PyObject *)it, name);
72+
}
73+
74+
PyTypeObject PyIter_Type = {
75+
PyObject_HEAD_INIT(&PyType_Type)
76+
0, /* ob_size */
77+
"iterator", /* tp_name */
78+
sizeof(iterobject), /* tp_basicsize */
79+
0, /* tp_itemsize */
80+
/* methods */
81+
(destructor)iter_dealloc, /* tp_dealloc */
82+
0, /* tp_print */
83+
(getattrfunc)iter_getattr, /* tp_getattr */
84+
0, /* tp_setattr */
85+
0, /* tp_compare */
86+
0, /* tp_repr */
87+
0, /* tp_as_number */
88+
0, /* tp_as_sequence */
89+
0, /* tp_as_mapping */
90+
0, /* tp_hash */
91+
0, /* tp_call */
92+
0, /* tp_str */
93+
0, /* tp_getattro */
94+
0, /* tp_setattro */
95+
0, /* tp_as_buffer */
96+
Py_TPFLAGS_DEFAULT, /* tp_flags */
97+
0, /* tp_doc */
98+
0, /* tp_traverse */
99+
0, /* tp_clear */
100+
0, /* tp_richcompare */
101+
0, /* tp_weaklistoffset */
102+
(getiterfunc)iter_getiter, /* tp_iter */
103+
};
104+
105+
/* -------------------------------------- */
106+
107+
typedef struct {
108+
PyObject_HEAD
109+
PyObject *it_callable;
110+
PyObject *it_sentinel;
111+
} calliterobject;
112+
113+
PyObject *
114+
PyCallIter_New(PyObject *callable, PyObject *sentinel)
115+
{
116+
calliterobject *it;
117+
it = PyObject_NEW(calliterobject, &PyCallIter_Type);
118+
if (it == NULL)
119+
return NULL;
120+
Py_INCREF(callable);
121+
it->it_callable = callable;
122+
Py_INCREF(sentinel);
123+
it->it_sentinel = sentinel;
124+
return (PyObject *)it;
125+
}
126+
static void
127+
calliter_dealloc(calliterobject *it)
128+
{
129+
Py_DECREF(it->it_callable);
130+
Py_DECREF(it->it_sentinel);
131+
PyObject_DEL(it);
132+
}
133+
static PyObject *
134+
calliter_next(calliterobject *it, PyObject *args)
135+
{
136+
PyObject *result = PyObject_CallObject(it->it_callable, NULL);
137+
if (result != NULL) {
138+
if (PyObject_RichCompareBool(result, it->it_sentinel, Py_EQ)) {
139+
PyErr_SetObject(PyExc_StopIteration, Py_None);
140+
Py_DECREF(result);
141+
result = NULL;
142+
}
143+
}
144+
return result;
145+
}
146+
147+
static PyMethodDef calliter_methods[] = {
148+
{"next", (PyCFunction)calliter_next, METH_VARARGS,
149+
"it.next() -- get the next value, or raise StopIteration"},
150+
{NULL, NULL} /* sentinel */
151+
};
152+
153+
static PyObject *
154+
calliter_getattr(calliterobject *it, char *name)
155+
{
156+
return Py_FindMethod(calliter_methods, (PyObject *)it, name);
157+
}
158+
159+
PyTypeObject PyCallIter_Type = {
160+
PyObject_HEAD_INIT(&PyType_Type)
161+
0, /* ob_size */
162+
"callable-iterator", /* tp_name */
163+
sizeof(calliterobject), /* tp_basicsize */
164+
0, /* tp_itemsize */
165+
/* methods */
166+
(destructor)calliter_dealloc, /* tp_dealloc */
167+
0, /* tp_print */
168+
(getattrfunc)calliter_getattr, /* tp_getattr */
169+
0, /* tp_setattr */
170+
0, /* tp_compare */
171+
0, /* tp_repr */
172+
0, /* tp_as_number */
173+
0, /* tp_as_sequence */
174+
0, /* tp_as_mapping */
175+
0, /* tp_hash */
176+
0, /* tp_call */
177+
0, /* tp_str */
178+
0, /* tp_getattro */
179+
0, /* tp_setattro */
180+
0, /* tp_as_buffer */
181+
Py_TPFLAGS_DEFAULT, /* tp_flags */
182+
0, /* tp_doc */
183+
0, /* tp_traverse */
184+
0, /* tp_clear */
185+
0, /* tp_richcompare */
186+
0, /* tp_weaklistoffset */
187+
(getiterfunc)iter_getiter, /* tp_iter */
188+
};

0 commit comments

Comments
 (0)