// // SWIG typemaps for std::vector types // Luigi Ballabio // Apr 8, 2002 // // Python implementation %include std_common.i %include exception.i // __getitem__ is required to raise an IndexError for for-loops to work // other methods which can raise are made to throw an IndexError as well %exception std::vector::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::__setitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Python as much as possible, namely, to allow the user to pass and // be returned Python tuples or lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Python sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Python sequence of T:s // is returned which is most easily used in other Python functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1.reserve(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) { $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result.reserve(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp.reserve(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp.reserve(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T* ptr = new T((($1_type &)$1)[i]); PyTuple_SetItem($result,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T *), 1)); } } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) { T* ptr = new T((($1_type &)$1_name)[i]); PyTuple_SetItem($input,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; void clear(); %rename(append) push_back; void push_back(const T& x); %extend { bool __nonzero__() { return !(self->empty()); } T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp; tmp.reserve(j-i); tmp.insert(tmp.begin(),self->begin()+i,self->begin()+j); return tmp; } void __setitem__(int i, const T& x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) { self->insert(self->begin()+i,v.begin(),v.end()); } else { self->insert(self->end(),v.begin(),v.end()); } } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; // Partial specialization for vectors of pointers. [ beazley ] template class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1 = std::vector(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) { $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "*> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result = std::vector(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "*> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "*> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "*> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T *ptr = (($1_type &)$1)[i]; PyTuple_SetItem($result,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T*), 0)); } } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) { T *ptr = (($1_type &)$1_name)[i]; PyTuple_SetItem($input,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T*), 0)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T *x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T*),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T *x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T*),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, T * &value); vector(const vector &); %rename(__len__) size; unsigned int size() const; void clear(); %rename(append) push_back; void push_back(T * x); %extend { bool __nonzero__() { return !(self->empty()); } T *pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T *x = self->back(); self->pop_back(); return x; } T * __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp(j-i); std::copy(self->begin()+i,self->begin()+j,tmp.begin()); return tmp; } void __setitem__(int i, T *x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) self->insert(self->begin()+i,v.begin(),v.end()); else self->insert(self->end(),v.begin(),v.end()); } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; // specializations for built-ins %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) template<> class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1 = std::vector(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,1) != -1){ $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result = std::vector(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1){ $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) PyTuple_SetItem($result,i, CONVERT_TO((($1_type &)$1)[i])); } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) PyTuple_SetItem($input,i, CONVERT_TO((($1_type &)$1_name)[i])); } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* o = PySequence_GetItem($input,0); if (CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* o = PySequence_GetItem($input,0); if (CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; %rename(__nonzero__) empty; bool empty() const; void clear(); %rename(append) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp(j-i); std::copy(self->begin()+i,self->begin()+j,tmp.begin()); return tmp; } void __setitem__(int i, T x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) self->insert(self->begin()+i,v.begin(),v.end()); else self->insert(self->end(),v.begin(),v.end()); } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; %enddef specialize_std_vector(bool,PyInt_Check,PyInt_AsLong,SwigInt_FromBool); specialize_std_vector(char,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(int,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(short,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(long,PyLong_Check,PyLong_AsLong,PyLong_FromLong); specialize_std_vector(unsigned char,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned int,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned short,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned long,PyLong_Check,\ PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_vector(double,SwigNumber_Check,\ SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_vector(float,SwigNumber_Check,\ SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_vector(std::string,PyString_Check,\ SwigString_AsString,SwigString_FromString); }