@@ -13,15 +13,17 @@ typedef struct {
13
13
PyObject_HEAD
14
14
long * array_long ;
15
15
ssize_t size ;
16
- } SequenceOfLong ;
16
+ } SequenceLongObject ;
17
+
18
+ // Forward references
19
+ static PyTypeObject SequenceLongObjectType ;
17
20
18
- // Forward reference
19
21
static int is_sequence_of_long_type (PyObject * op );
20
22
21
23
static PyObject *
22
- SequenceOfLong_new (PyTypeObject * type , PyObject * Py_UNUSED (args ), PyObject * Py_UNUSED (kwds )) {
23
- SequenceOfLong * self ;
24
- self = (SequenceOfLong * ) type -> tp_alloc (type , 0 );
24
+ SequenceLongObject_new (PyTypeObject * type , PyObject * Py_UNUSED (args ), PyObject * Py_UNUSED (kwds )) {
25
+ SequenceLongObject * self ;
26
+ self = (SequenceLongObject * ) type -> tp_alloc (type , 0 );
25
27
if (self != NULL ) {
26
28
assert (!PyErr_Occurred ());
27
29
self -> size = 0 ;
@@ -31,7 +33,7 @@ SequenceOfLong_new(PyTypeObject *type, PyObject *Py_UNUSED(args), PyObject *Py_U
31
33
}
32
34
33
35
static int
34
- SequenceOfLong_init ( SequenceOfLong * self , PyObject * args , PyObject * kwds ) {
36
+ SequenceLongObject_init ( SequenceLongObject * self , PyObject * args , PyObject * kwds ) {
35
37
static char * kwlist [] = {"sequence" , NULL };
36
38
PyObject * sequence = NULL ;
37
39
@@ -46,7 +48,7 @@ SequenceOfLong_init(SequenceOfLong *self, PyObject *args, PyObject *kwds) {
46
48
if (!self -> array_long ) {
47
49
return -3 ;
48
50
}
49
- for (Py_ssize_t i = 0 ; i < PySequence_Length ( sequence ) ; ++ i ) {
51
+ for (Py_ssize_t i = 0 ; i < self -> size ; ++ i ) {
50
52
// New reference.
51
53
PyObject * py_value = PySequence_GetItem (sequence , i );
52
54
if (PyLong_Check (py_value )) {
@@ -70,20 +72,15 @@ SequenceOfLong_init(SequenceOfLong *self, PyObject *args, PyObject *kwds) {
70
72
}
71
73
72
74
static void
73
- SequenceOfLong_dealloc ( SequenceOfLong * self ) {
75
+ SequenceLongObject_dealloc ( SequenceLongObject * self ) {
74
76
free (self -> array_long );
75
77
Py_TYPE (self )-> tp_free ((PyObject * ) self );
76
78
}
77
79
78
- //static PyObject *
79
- //SequenceOfLong_size(SequenceOfLong *self, PyObject *Py_UNUSED(ignored)) {
80
- // return Py_BuildValue("n", self->size);
81
- //}
82
-
83
- static PyMethodDef SequenceOfLong_methods [] = {
80
+ static PyMethodDef SequenceLongObject_methods [] = {
84
81
// {
85
82
// "size",
86
- // (PyCFunction) SequenceOfLong_size ,
83
+ // (PyCFunction) SequenceLongObject_size ,
87
84
// METH_NOARGS,
88
85
// "Return the size of the sequence."
89
86
// },
@@ -92,66 +89,105 @@ static PyMethodDef SequenceOfLong_methods[] = {
92
89
93
90
/* Sequence methods. */
94
91
static Py_ssize_t
95
- SequenceOfLong_len (PyObject * self ) {
96
- return ((SequenceOfLong * )self )-> size ;
92
+ SequenceLongObject_sq_length (PyObject * self ) {
93
+ return ((SequenceLongObject * ) self )-> size ;
97
94
}
98
95
96
+ /**
97
+ * Returns a new SequenceLongObject composed of self + other.
98
+ * @param self
99
+ * @param other
100
+ * @return
101
+ */
99
102
static PyObject *
100
- SequenceOfLong_getitem (PyObject * self , Py_ssize_t index ) {
103
+ SequenceLongObject_sq_concat (PyObject * self , PyObject * other ) {
104
+ if (!is_sequence_of_long_type (other )) {
105
+ PyErr_Format (
106
+ PyExc_TypeError ,
107
+ "%s(): argument 1 must have type \"SequenceLongObject\" not %s" ,
108
+ Py_TYPE (other )-> tp_name
109
+ );
110
+ return NULL ;
111
+ }
112
+ PyObject * ret = SequenceLongObject_new (& SequenceLongObjectType , NULL , NULL );
113
+ /* For convenience. */
114
+ SequenceLongObject * sol = (SequenceLongObject * ) ret ;
115
+ sol -> size = ((SequenceLongObject * ) self )-> size + ((SequenceLongObject * ) other )-> size ;
116
+ sol -> array_long = malloc (sol -> size * sizeof (long ));
117
+ if (!sol -> array_long ) {
118
+ PyErr_Format (PyExc_MemoryError , "%s(): Can not create new object." , __FUNCTION__ );
119
+ }
120
+
121
+ ssize_t i = 0 ;
122
+ ssize_t ub = ((SequenceLongObject * ) self )-> size ;
123
+ while (i < ub ) {
124
+ sol -> array_long [i ] = ((SequenceLongObject * ) self )-> array_long [i ];
125
+ i ++ ;
126
+ }
127
+ ub += ((SequenceLongObject * ) other )-> size ;
128
+ while (i < ub ) {
129
+ sol -> array_long [i ] = ((SequenceLongObject * ) other )-> array_long [i ];
130
+ i ++ ;
131
+ }
132
+ return ret ;
133
+ }
134
+
135
+
136
+ static PyObject *
137
+ SequenceLongObject_sq_item (PyObject * self , Py_ssize_t index ) {
101
138
Py_ssize_t my_index = index ;
102
139
if (my_index < 0 ) {
103
- my_index += SequenceOfLong_len (self );
140
+ my_index += SequenceLongObject_sq_length (self );
104
141
}
105
- if (my_index > SequenceOfLong_len (self )) {
142
+ if (my_index > SequenceLongObject_sq_length (self )) {
106
143
PyErr_Format (
107
144
PyExc_IndexError ,
108
145
"Index %ld is out of range for length %ld" ,
109
146
index ,
110
- SequenceOfLong_len (self )
147
+ SequenceLongObject_sq_length (self )
111
148
);
112
149
return NULL ;
113
150
}
114
- return PyLong_FromLong (((SequenceOfLong * )self )-> array_long [my_index ]);
151
+ return PyLong_FromLong (((SequenceLongObject * ) self )-> array_long [my_index ]);
115
152
}
116
153
117
- PySequenceMethods SequenceOfLong_sequence_methods = {
118
- .sq_length = & SequenceOfLong_len ,
119
- .sq_concat = NULL ,
154
+ PySequenceMethods SequenceLongObject_sequence_methods = {
155
+ .sq_length = & SequenceLongObject_sq_length ,
156
+ .sq_concat = & SequenceLongObject_sq_concat ,
120
157
.sq_repeat = NULL ,
121
- .sq_item = & SequenceOfLong_getitem ,
158
+ .sq_item = & SequenceLongObject_sq_item ,
122
159
.sq_ass_item = NULL ,
123
160
.sq_contains = NULL ,
124
161
.sq_inplace_concat = NULL ,
125
162
.sq_inplace_repeat = NULL ,
126
163
};
127
164
128
165
static PyObject *
129
- SequenceOfLong___str__ ( SequenceOfLong * self , PyObject * Py_UNUSED (ignored )) {
166
+ SequenceLongObject___str__ ( SequenceLongObject * self , PyObject * Py_UNUSED (ignored )) {
130
167
assert (!PyErr_Occurred ());
131
- return PyUnicode_FromFormat ("<SequenceOfLong sequence size: %ld>" , self -> size );
168
+ return PyUnicode_FromFormat ("<SequenceLongObject sequence size: %ld>" , self -> size );
132
169
}
133
170
134
- static PyTypeObject SequenceOfLongType = {
171
+ static PyTypeObject SequenceLongObjectType = {
135
172
PyVarObject_HEAD_INIT (NULL , 0 )
136
- .tp_name = "SequenceOfLong " ,
137
- .tp_basicsize = sizeof (SequenceOfLong ),
173
+ .tp_name = "SequenceLongObject " ,
174
+ .tp_basicsize = sizeof (SequenceLongObject ),
138
175
.tp_itemsize = 0 ,
139
- .tp_dealloc = (destructor ) SequenceOfLong_dealloc ,
140
- .tp_as_sequence = & SequenceOfLong_sequence_methods ,
141
- .tp_str = (reprfunc ) SequenceOfLong___str__ ,
176
+ .tp_dealloc = (destructor ) SequenceLongObject_dealloc ,
177
+ .tp_as_sequence = & SequenceLongObject_sequence_methods ,
178
+ .tp_str = (reprfunc ) SequenceLongObject___str__ ,
142
179
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
143
180
.tp_doc = "Sequence of long integers." ,
144
- .tp_methods = SequenceOfLong_methods ,
145
- .tp_init = (initproc ) SequenceOfLong_init ,
146
- .tp_new = SequenceOfLong_new ,
181
+ .tp_methods = SequenceLongObject_methods ,
182
+ .tp_init = (initproc ) SequenceLongObject_init ,
183
+ .tp_new = SequenceLongObject_new ,
147
184
};
148
185
149
186
static int
150
187
is_sequence_of_long_type (PyObject * op ) {
151
- return Py_TYPE (op ) == & SequenceOfLongType ;
188
+ return Py_TYPE (op ) == & SequenceLongObjectType ;
152
189
}
153
190
154
-
155
191
static PyMethodDef cIterator_methods [] = {
156
192
// {"iterate_and_print", (PyCFunction) iterate_and_print, METH_VARARGS,
157
193
// "Iteratee through the argument printing the values."},
@@ -162,7 +198,7 @@ static PyModuleDef sequence_object_cmodule = {
162
198
PyModuleDef_HEAD_INIT ,
163
199
.m_name = "cSeqObject" ,
164
200
.m_doc = (
165
- "Example module that creates an extension type with sequence methods"
201
+ "Example module that creates an extension type with sequence methods"
166
202
),
167
203
.m_size = -1 ,
168
204
.m_methods = cIterator_methods ,
@@ -176,17 +212,17 @@ PyInit_cSeqObject(void) {
176
212
return NULL ;
177
213
}
178
214
179
- if (PyType_Ready (& SequenceOfLongType ) < 0 ) {
215
+ if (PyType_Ready (& SequenceLongObjectType ) < 0 ) {
180
216
Py_DECREF (m );
181
217
return NULL ;
182
218
}
183
- Py_INCREF (& SequenceOfLongType );
219
+ Py_INCREF (& SequenceLongObjectType );
184
220
if (PyModule_AddObject (
185
221
m ,
186
- "SequenceOfLong " ,
187
- (PyObject * ) & SequenceOfLongType ) < 0
222
+ "SequenceLongObject " ,
223
+ (PyObject * ) & SequenceLongObjectType ) < 0
188
224
) {
189
- Py_DECREF (& SequenceOfLongType );
225
+ Py_DECREF (& SequenceLongObjectType );
190
226
Py_DECREF (m );
191
227
return NULL ;
192
228
}
0 commit comments