1 // SIP support for std::vector
2 // by Giovanni Bajo <rasky <at> develer.com>
5 // ****************************************************
6 // SIP generic implementation for std::vector<>
7 // ****************************************************
8 // ALas, this template-based generic implementation is valid only
9 // if the element type is a SIP-wrapped type. For basic types (int, double, etc.)
10 // we are forced to cut & paste to provide a specialization.
13 %MappedType std::vector<TYPE*>
20 PyObject *l = PyList_New(sipCpp -> size());
22 // Create the Python list of the correct length.
26 // Go through each element in the C++ instance and convert it to a
28 for (int i = 0; i < (int)sipCpp->size(); ++i) {
29 TYPE *cpp = sipCpp->at(i);
30 PyObject *pobj = sipConvertFromInstance(cpp, sipClass_TYPE, sipTransferObj);
32 // Get the Python wrapper for the Type instance, creating a new
33 // one if necessary, and handle any ownership transfer.
35 // There was an error so garbage collect the Python list.
40 // Add the wrapper to the list.
41 PyList_SET_ITEM(l, i, pobj);
44 // Return the Python list.
49 // Check if type is compatible
51 // Must be any iterable
52 PyObject *i = PyObject_GetIter(sipPy);
53 bool iterable = (i != NULL);
58 // Iterate over the object
59 PyObject *iterator = PyObject_GetIter(sipPy);
62 std::vector<TYPE*> *V = new std::vector<TYPE*>();
64 while ((item = PyIter_Next(iterator)))
66 if (!sipCanConvertToInstance(item, sipClass_TYPE, SIP_NOT_NONE)) {
67 PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to TYPE");
73 TYPE* p = reinterpret_cast<TYPE*>(
74 sipConvertToInstance(item, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
79 sipReleaseInstance(p, sipClass_TYPE, state);
91 return sipGetState(sipTransferObj);
95 // ****************************************************
96 // Specialization for std::vector<char*>
97 // ****************************************************
99 %MappedType std::vector<char*>
108 // Create the Python list of the correct length.
109 if ((l = PyList_New(sipCpp -> size())) == NULL)
112 // Go through each element in the C++ instance and convert it to a
114 for (int i = 0; i < (int)sipCpp -> size(); ++i)
116 // Add the wrapper to the list.
117 PyList_SET_ITEM(l, i, sipBuildResult(NULL, "A", sipCpp->at(i)));
120 // Return the Python list.
125 // Check if type is compatible
126 if (sipIsErr == NULL)
128 // Must be any iterable
129 PyObject *i = PyObject_GetIter(sipPy);
130 bool iterable = (i != NULL);
135 // Iterate over the object
136 PyObject *iterator = PyObject_GetIter(sipPy);
139 // Maximum number of elements
140 int len = PyObject_Size(sipPy);
141 std::vector<char*> *V = new std::vector<char*>();
146 while ((item = PyIter_Next(iterator)))
148 if (!PyUnicode_Check(item))
150 PyErr_Format(PyExc_TypeError, "object in iterable is not a string");
154 //FIXME: memory leak here
155 const char* str = strdup(sipString_AsLatin1String(&item));
157 V->push_back(const_cast<char*>(str));
172 return sipGetState(sipTransferObj);
177 // ****************************************************
178 // Specialization for std::vector<double>
179 // ****************************************************
181 %MappedType std::vector<double>
190 // Create the Python list of the correct length.
191 if ((l = PyList_New(sipCpp -> size())) == NULL)
194 // Go through each element in the C++ instance and convert it to a
196 for (int i = 0; i < (int)sipCpp -> size(); ++i)
198 // Add the wrapper to the list.
199 PyList_SET_ITEM(l, i, PyFloat_FromDouble(sipCpp -> at(i)));
202 // Return the Python list.
207 // Check if type is compatible
208 if (sipIsErr == NULL)
210 // Must be any iterable
211 PyObject *i = PyObject_GetIter(sipPy);
212 bool iterable = (i != NULL);
217 // Iterate over the object
218 PyObject *iterator = PyObject_GetIter(sipPy);
221 // Maximum number of elements
222 int len = PyObject_Size(sipPy);
223 std::vector<double> *V = new std::vector<double>();
228 while ((item = PyIter_Next(iterator)))
230 if (!PyNumber_Check(item))
232 PyErr_Format(PyExc_TypeError, "object in iterable is not a number");
237 PyObject *f = PyNumber_Float(item);
238 V->push_back(PyFloat_AsDouble(f));
254 return sipGetState(sipTransferObj);
258 // ****************************************************
259 // Specialization for std::vector<int>
260 // ****************************************************
262 %MappedType std::vector<int>
271 // Create the Python list of the correct length.
272 if ((l = PyList_New((SIP_SSIZE_T)sipCpp -> size())) == NULL)
275 // Go through each element in the C++ instance and convert it to a
277 for (int i = 0; i < (int)sipCpp -> size(); ++i)
279 // Add the wrapper to the list.
280 PyList_SET_ITEM(l, i, PyInt_FromLong(sipCpp -> at(i)));
283 // Return the Python list.
288 // Check if type is compatible
289 if (sipIsErr == NULL)
291 // Must be any iterable
292 PyObject *i = PyObject_GetIter(sipPy);
293 bool iterable = (i != NULL);
298 // Iterate over the object
299 PyObject *iterator = PyObject_GetIter(sipPy);
302 // Maximum number of elements
303 int len = PyObject_Size(sipPy);
304 std::vector<int> *V = new std::vector<int>();
309 while ((item = PyIter_Next(iterator)))
311 if (!PyInt_Check(item))
313 PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to float");
318 int val = PyInt_AsLong(item);
334 return sipGetState(sipTransferObj);
339 // ****************************************************
340 // Specialization for std::vector<unsigned int>
341 // ****************************************************
343 %MappedType std::vector<unsigned int>
352 // Create the Python list of the correct length.
353 if ((l = PyList_New(sipCpp -> size())) == NULL)
356 // Go through each element in the C++ instance and convert it to a
358 for (int i = 0; i < (int)sipCpp -> size(); ++i)
360 // Add the wrapper to the list.
361 PyList_SET_ITEM(l, i, PyInt_FromLong(sipCpp -> at(i)));
364 // Return the Python list.
369 // Check if type is compatible
370 if (sipIsErr == NULL)
372 // Must be any iterable
373 PyObject *i = PyObject_GetIter(sipPy);
374 bool iterable = (i != NULL);
379 // Iterate over the object
380 PyObject *iterator = PyObject_GetIter(sipPy);
383 // Maximum number of elements
384 Py_ssize_t size = PyObject_Size(sipPy);
390 unsigned int len = size;
391 std::vector<unsigned int> *V = new std::vector<unsigned int>();
396 while ((item = PyIter_Next(iterator)))
398 if (!PyInt_Check(item))
400 PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to float");
405 unsigned int val = PyInt_AsLong(item);
421 return sipGetState(sipTransferObj);