diff --git a/Lib/python/argcargv.i b/Lib/python/argcargv.i index 4b3204005..0fb80cbad 100644 --- a/Lib/python/argcargv.i +++ b/Lib/python/argcargv.i @@ -16,7 +16,7 @@ SWIG_AsArgcArgv(PyObject* input, int list = PyList_Check(input); if (list || PyTuple_Check(input)) { *argc = list ? PyList_Size(input) : PyTuple_Size(input); - argv = swig_new_array(char*, *argc + 1); + argv = swig_new_array(*argc + 1, char*); *owner = 1; for (; i < *argc; ++i) { PyObject *obj = list ? PyList_GetItem(input,i) : PyTuple_GetItem(input,i); diff --git a/Lib/python/ccomplex.i b/Lib/python/ccomplex.i index c6e0336a3..78999e1c9 100644 --- a/Lib/python/ccomplex.i +++ b/Lib/python/ccomplex.i @@ -8,6 +8,7 @@ * ISO C99: 7.3 Complex arithmetic */ +%fragment("","header") %{ #include %} @@ -25,15 +26,12 @@ /* C complex constructor */ #define CCplxConst(r, i) ((r) + I*(i)) -%swig_cplxflt_conv(float_complex, CCplxFlt, - CCplxConst, creal, cimag); - -%swig_cplxdbl_conv(double_complex, CCplxDbl, - CCplxConst, creal, cimag); +%swig_cplxflt_convn(float_complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double_complex, CCplxConst, creal, cimag); /* declaring the typemaps */ -%typemap_stype(float_complex, CPLXFLT, CCplxFlt); -%typemap_stype(double_complex, CPLXDBL, CCplxDbl); +%typemap_primitive(SWIG_TYPECHECK_CPLXFLT, float_complex); +%typemap_primitive(SWIG_TYPECHECK_CPLXDBL, double_complex); %apply double_complex { complex }; diff --git a/Lib/python/complex_common.i b/Lib/python/complex_common.i index 76daa4a1d..7e97de4d8 100644 --- a/Lib/python/complex_common.i +++ b/Lib/python/complex_common.i @@ -11,63 +11,96 @@ */ /* the common from conversor */ -%define %swig_fromcplx_conv(Type, Name, Real, Imag) -%fragment("SWIG_From"#Name,"header") +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header") %{ -SWIGSTATIC(PyObject*) -SWIG_From##Name(Type c) +SWIGSTATICINLINE(PyObject*) + SWIG_From_meth(Type)(SWIG_cplusplus(const Type&, Type) c) { return PyComplex_FromDoubles(Real(c), Imag(c)); } %} %enddef - /* the double case */ -%define %swig_cplxdbl_conv(Type, Name, Constructor, Real, Imag) -%fragment("SWIG_As"#Name,"header", - fragment="SWIG_AsDouble") +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) %{ -SWIGSTATIC(Type) -SWIG_As##Name(PyObject *o) +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(Type) (PyObject *o, Type* val) { - Type c = PyComplex_Check(o) ? - Constructor(PyComplex_RealAsDouble(o), - PyComplex_ImagAsDouble(o)) : - Constructor(SWIG_AsDouble(o), 0); - if (PyErr_Occurred()){ - PyErr_Clear(); + if (PyComplex_Check(o)) { + if (val) *val = Constructor(PyComplex_RealAsDouble(o), + PyComplex_ImagAsDouble(o)); + return 1; + } else { + double d; + if (SWIG_AsVal_meth(double)(o, &d)) { + if (val) *val = Constructor(d, 0); + return 1; + } else { + PyErr_Clear(); + } + } + if (val) { PyErr_SetString(PyExc_TypeError, "a Type is expected"); } - return c; + return 0; } %} -%swig_fromcplx_conv(Type, Name, Real, Imag); +%swig_fromcplx_conv(Type, Real, Imag); %enddef /* the float case */ -%define %swig_cplxflt_conv(Type, Name, Constructor, Real, Imag) -%fragment("SWIG_As"#Name,"header", - fragment="SWIG_CheckFloat", - fragment="SWIG_AsDouble") +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment="SWIG_CheckDoubleInRange", + fragment=SWIG_AsVal_frag(float)) %{ -SWIGSTATIC(Type) -SWIG_As##Name(PyObject *o) +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(Type)(PyObject *o, Type *val) { - Type c = PyComplex_Check(o) ? - Constructor(SWIG_CheckFloat(PyComplex_RealAsDouble(o)), - SWIG_CheckFloat(PyComplex_RealAsDouble(o))) : - Constructor(SWIG_CheckFloat(SWIG_AsDouble(o)),0); - if (PyErr_Occurred()) { - PyErr_Clear(); + const char* errmsg = val ? #Type : 0; + if (PyComplex_Check(o)) { + double re = PyComplex_RealAsDouble(o); + double im = PyComplex_ImagAsDouble(o); + if (SWIG_CheckDoubleInRange(re, FLT_MIN, FLT_MAX, errmsg) + && SWIG_CheckDoubleInRange(im, FLT_MIN, FLT_MAX, errmsg)) { + if (val) *val = Constructor(swig_numeric_cast(re, float), + swig_numeric_cast(im, float)); + return 1; + } else { + return 0; + } + } else { + double re; + if (SWIG_AsVal_meth(double)(o, &re)) { + if (SWIG_CheckDoubleInRange(re, FLT_MIN, FLT_MAX, errmsg)) { + if (val) *val = Constructor(swig_numeric_cast(re,float), 0); + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + } + if (val) { PyErr_SetString(PyExc_TypeError, "a Type is expected"); } - return c; - } + return 0; +} %} - -%swig_fromcplx_conv(Type, Name, Real, Imag); +%swig_fromcplx_conv(Type, Real, Imag); %enddef +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) + #endif //__python_complex_common_i__ diff --git a/Lib/python/implicit.i b/Lib/python/implicit.i new file mode 100644 index 000000000..ab3531976 --- /dev/null +++ b/Lib/python/implicit.i @@ -0,0 +1,217 @@ +%include std_common.i + +/* + The %implict macro allows a SwigType to be accepted + as an input parameter and use its implicit constructors when needed. + + + %implicit(A, int, double, B); + + %inline + { + struct B { }; + struct A + { + int ii; + A(int i) { ii = 1; } + A(double d) { ii = 2; } + A(const B& b) { ii = 3; } + }; + + int get(A a) { return a.ii; } + } + + Here, you can call 'get' as + + get(1) ==> get(A(1)) + get(2.0) ==> get(A(2.0)) + get(B()) ==> get(A(B())) + + and swig will construct an 'A' temporal variable using the + corresponding implicit constructor. + + + The plain implicit macro takes care of simple type list. If it doesn't + work because you are passing template types with commas, then use + the %implicit_{1,2,3} versions, and the SWIG_arg macro. + +*/ + + +%define %implicit_type(...) +%traits_swigtype(__VA_ARGS__); +%enddef + +%define %implicit_frag(...) ,fragment=SWIG_Traits_frag(__VA_ARGS__) %enddef + +%define %implicit_code(...) + if (swigpy::check<__VA_ARGS__ >(obj)) { + if (val) *val = new value_type(swigpy::as<__VA_ARGS__ >(obj)); + return 2; + } +%enddef + +/* implicit */ + +%define %implicit(Type, ...) + +%formacro_1(%implicit_type,__VA_ARGS__); + +%fragment(SWIG_Traits_frag(Type),"header", + fragment="traits" + %formacro_1(%implicit_frag,__VA_ARGS__)) %{ +namespace swigpy { + template <> struct traits { + typedef pointer_category category; + static const char* type_name() { return "Type"; } + }; + + template <> struct traits_asptr< Type > { + typedef Type value_type; + static int asptr(PyObject *obj, value_type **val) { + Type *vptr; + static swig_type_info* desc = SWIG_TypeQuery("Type *"); + if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { + if (val) *val = vptr; + return 1; + } else { + if (PyErr_Occurred()) PyErr_Clear(); + %formacro_1(%implicit_code,__VA_ARGS__) + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a " "Type" " is expected"); + } + return 0; + } + }; +} +%} + +%typemap_traits_ptr(SWIG_CCode(POINTER),Type); +%enddef + +/* implicit_1 */ + + +%define %implicit_1(Type, Imp1) +%traits_swigtype(Imp1); + +%fragment(SWIG_Traits_frag(Type),"header", + fragment="traits", + fragment=SWIG_Traits_frag(Imp1)) %{ +namespace swigpy { + template <> struct traits< Type > { + typedef pointer_category category; + static const char* type_name() { return "Type"; } + }; + + template <> struct traits_asptr< Type > { + typedef Type value_type; + static int asptr(PyObject *obj, value_type **val) { + Type *vptr; + static swig_type_info* desc = SWIG_TypeQuery("Type *"); + if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { + if (val) *val = vptr; + return 1; + } else { + if (PyErr_Occurred()) PyErr_Clear(); + %implicit_code(Imp1); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a " "Type" " is expected"); + } + return 0; + } + }; +} +%} + +%typemap_traits_ptr(SWIG_CCode(POINTER),Type); + +%enddef + +/* implicit_2 */ + +%define %implicit_2(Type, Imp1, Imp2) +%traits_swigtype(Imp1); +%traits_swigtype(Imp2); + +%fragment(SWIG_Traits_frag(Type),"header", + fragment="traits", + fragment=SWIG_Traits_frag(Imp1), + fragment=SWIG_Traits_frag(Imp2)) %{ +namespace swigpy { + template <> struct traits< Type > { + typedef pointer_category category; + static const char* type_name() { return "Type"; } + }; + + template <> struct traits_asptr< Type > { + typedef Type value_type; + static int asptr(PyObject *obj, value_type **val) { + Type *vptr; + static swig_type_info* desc = SWIG_TypeQuery("Type *"); + if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { + if (val) *val = vptr; + return 1; + } else { + if (PyErr_Occurred()) PyErr_Clear(); + %implicit_code(Imp1); + %implicit_code(Imp2); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a " "Type" " is expected"); + } + return 0; + } + }; +} +%} + +%typemap_traits_ptr(SWIG_CCode(POINTER),Type); +%enddef + + +/* implicit_3 */ + +%define %implicit_3(Type, Imp1, Imp2, Imp3) +%traits_swigtype(Imp1); +%traits_swigtype(Imp2); +%traits_swigtype(Imp3); + +%fragment(SWIG_Traits_frag(Type),"header", + fragment="traits", + fragment=SWIG_Traits_frag(Imp1), + fragment=SWIG_Traits_frag(Imp2), + fragment=SWIG_Traits_frag(Imp3)) %{ +namespace swigpy { + template <> struct traits< Type > { + typedef pointer_category category; + static const char* type_name() { return "Type"; } + }; + + template <> struct traits_asptr< Type > { + typedef Type value_type; + static int asptr(PyObject *obj, value_type **val) { + Type *vptr; + static swig_type_info* desc = SWIG_TypeQuery("Type *"); + if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { + if (val) *val = vptr; + return 1; + } else { + if (PyErr_Occurred()) PyErr_Clear(); + %implicit_code(Imp1); + %implicit_code(Imp2); + %implicit_code(Imp3); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a " "Type" " is expected"); + } + return 0; + } + }; +} +%} + +%typemap_traits_ptr(SWIG_CCode(POINTER),Type); +%enddef diff --git a/Lib/python/pycontainer.i b/Lib/python/pycontainer.i new file mode 100644 index 000000000..c2e51e52a --- /dev/null +++ b/Lib/python/pycontainer.i @@ -0,0 +1,568 @@ +// +// Python sequence <-> C++ container wrapper +// +// This wrapper, and its iterator, allows a general use (and reuse) of +// the the mapping between C++ and Python, thanks to the C++ +// templates. +// +// Of course, it needs the C++ compiler to support templates, but +// since we will use this wrapper with the STL containers, that should +// be the case. +// + + +/**** The PySequence C++ Wrap ***/ + +%{ +#if PY_VERSION_HEX < 0x02000000 +#define PySequence_Size PySequence_Length +#endif +%} + +%fragment("PySequence_Cont","header", + fragment="traits", + fragment="PyObject_var") +%{ +#include +namespace swigpy +{ + template + struct PySequence_Ref + { + PySequence_Ref(PyObject* seq, int index) + : _seq(seq), _index(index) + { + } + + operator T () const + { + swigpy::PyObject_var item = PySequence_GetItem(_seq, _index); + return swigpy::as(item); + } + + PySequence_Ref& operator=(const T& v) + { + PySequence_SetItem(_seq, _index, swigpy::from(v)); + return *this; + } + + private: + PyObject* _seq; + int _index; + }; + + template + struct PySequence_ArrowProxy + { + PySequence_ArrowProxy(const T& x): m_value(x) {} + const T* operator->() const { return &m_value; } + operator const T*() const { return &m_value; } + T m_value; + }; + + template + struct PySequence_Iter + { + typedef PySequence_Iter self; + + typedef std::random_access_iterator_tag iterator_category; + typedef Reference reference; + typedef T value_type; + typedef T* pointer; + typedef int difference_type; + + PySequence_Iter() + { + } + + PySequence_Iter(PyObject* seq, int index) + : _seq(seq), _index(index) + { + } + + reference operator*() const + { + return reference(_seq, _index); + } + + PySequence_ArrowProxy + operator->() const { + return PySequence_ArrowProxy(operator*()); + } + + bool operator==(const self& ri) const + { + return (_index == ri._index) && (_seq == ri._seq); + } + + bool operator!=(const self& ri) const + { + return !(operator==(ri)); + } + + self& operator ++ () + { + ++_index; + return *this; + } + + self& operator -- () + { + --_index; + return *this; + } + + self& operator += (difference_type n) + { + _index += n; + return *this; + } + + self operator +(difference_type n) const + { + return self(_seq, _index + n); + } + + self& operator -= (difference_type n) + { + _index -= n; + return *this; + } + + self operator -(difference_type n) const + { + return self(_seq, _index - n); + } + + difference_type operator - (const self& ri) const + { + return _index - ri._index; + } + + reference + operator[](difference_type n) const + { + return reference(_seq, _index + n); + } + + private: + PyObject* _seq; + int _index; + }; + + template + struct PySequence_Cont + { + typedef PySequence_Ref reference; + typedef const PySequence_Ref const_reference; + typedef T value_type; + typedef T* pointer; + typedef int difference_type; + typedef int size_type; + typedef const pointer const_pointer; + typedef PySequence_Iter iterator; + typedef PySequence_Iter const_iterator; + + PySequence_Cont(PyObject* seq) : _seq(0) + { + if (!PySequence_Check(seq)) { + throw std::invalid_argument("a sequence is expected"); + } + _seq = seq; + Py_INCREF(_seq); + } + + ~PySequence_Cont() + { + if (_seq) Py_DECREF(_seq); + } + + size_type size() const + { + return PySequence_Size(_seq); + } + + bool empty() const + { + return size() == 0; + } + + iterator begin() + { + return iterator(_seq, 0); + } + + const_iterator begin() const + { + return const_iterator(_seq, 0); + } + + iterator end() + { + return iterator(_seq, size()); + } + + const_iterator end() const + { + return const_iterator(_seq, size()); + } + + reference operator[](difference_type n) + { + return reference(_seq, n); + } + + const_reference operator[](difference_type n) const + { + return const_reference(_seq, n); + } + + bool check(bool set_err = true) const + { + int s = size(); + for (int i = 0; i < s; ++i) { + swigpy::PyObject_var item = PySequence_GetItem(_seq, i); + if (!swigpy::check(item)) { + if (set_err) { + PyErr_Format(PyExc_TypeError, + "element %d is not of type '%s' as expected", + i, swigpy::type_name()); + } + return 0; + } + } + return 1; + } + + private: + PyObject* _seq; + }; +} + +%} + + +/**** The python container methods ****/ + + +%define %pycontainer_methods(Container) + // __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 __getitem__ { + try { + $action; + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } + } + + %exception __setitem__ { + try { + $action; + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } + } + + %exception __setslice__ { + try { + $action; + } catch (std::invalid_argument& e) { + SWIG_exception(SWIG_TypeError,const_cast(e.what())); + } + } + + %exception __delitem__ { + try { + $action; + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } + } + + %exception pop { + try { + $action; + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } + } + + %newobject __getslice__; + + %extend { + bool __nonzero__() const { + return !(self->empty()); + } + + size_type __len__() const + { + return self->size(); + } + } +%enddef + +%define %pysequence_methods_common(Sequence) + %pycontainer_methods(SWIG_arg(Sequence)) + + %extend { + value_type pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + Sequence::value_type x = self->back(); + self->pop_back(); + return x; + } + + Sequence* __getslice__(difference_type i, difference_type j) const { + Sequence::size_type size = self->size(); + if (i<0) i +=size; + if (j<0) j +=size; + if (i<0) i = 0; + if (j>size) j = size; + Sequence::const_iterator beg = self->begin(); + Sequence::const_iterator end = self->begin(); + std::advance(beg,i); + std::advance(end,j); + Sequence *tmp = new Sequence(beg,end); + return tmp; + } + + void __setslice__(difference_type i, + difference_type j, const Sequence& v) { + Sequence::size_type size = self->size(); + if (i<0) i += size; + if (i<0) i = 0; + j = i + v.size(); + Sequence::iterator beg = self->begin(); + std::advance(beg,i); + + Sequence::const_iterator vmid = v.begin(); + std::advance(vmid, ((j > size ? size : j) - i)); + + self->insert(std::copy(v.begin(), vmid, beg),vmid, v.end()); + } + + void __delitem__(difference_type i) { + Sequence::size_type size = self->size(); + if (i<0) i+= size; + if (i>=0 && ibegin(); + std::advance(pos,i); + self->erase(pos); + } + + else + throw std::out_of_range("index out of range"); + } + + void __delslice__(difference_type i, + difference_type j) { + Sequence::size_type size = self->size(); + if (i<0) i +=size; + if (j<0) j +=size; + if (i<0) i = 0; + if (j>size) j = size; + Sequence::iterator beg = self->begin(); + Sequence::iterator end = self->begin(); + std::advance(beg, i); + std::advance(end, j); + self->erase(beg, end); + } + + } +%enddef + +%define %pysequence_methods(Sequence) + %pysequence_methods_common(SWIG_arg(Sequence)) + %extend { + + const value_type& __getitem__(difference_type i) const { + Sequence::size_type size = self->size(); + if (i<0) i += size; + if (i>=0 && ibegin(); + std::advance(pos, i); + return *(pos); + } else { + throw std::out_of_range("index out of range"); + } + } + + void __setitem__(difference_type i, const value_type& x) { + Sequence::size_type size = self->size(); + if (i<0) i+= size; + if (i>=0 && ibegin(); + std::advance(pos, i); + *(pos) = x; + } else { + throw std::out_of_range("index out of range"); + } + } + + void append(const value_type& x) { + self->push_back(x); + } + } +%enddef + +%define %pysequence_methods_val(Sequence) + %pysequence_methods_common(SWIG_arg(Sequence)) + %extend { + value_type __getitem__(difference_type i) { + Sequence::size_type size = self->size(); + if (i<0) i += size; + if (i>=0 && ibegin(); + std::advance(pos, i); + return *(pos); + } else { + throw std::out_of_range("index out of range"); + } + } + + value_type __getitem__(difference_type i) const { + Sequence::size_type size = self->size(); + if (i<0) i += size; + if (i>=0 && ibegin(); + std::advance(pos, i); + return *(pos); + } else { + throw std::out_of_range("index out of range"); + } + } + + void __setitem__(difference_type i, value_type x) { + Sequence::size_type size = self->size(); + if (i<0) i+= size; + if (i>=0 && ibegin(); + std::advance(pos, i); + *(pos) = x; + } else { + throw std::out_of_range("index out of range"); + } + } + + void append(value_type x) { + self->push_back(x); + } + } +%enddef + + +%define %pydict_methods(Dict) + %pycontainer_methods(SWIG_arg(Dict)) + + %extend { + mapped_type __getitem__(const key_type& key) const { + Dict::const_iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + + void __setitem__(const key_type& key, const mapped_type& x) { + (*self)[key] = x; + } + + void __delitem__(const key_type& key) { + Dict::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + + bool has_key(const key_type& key) const { + Dict::const_iterator i = self->find(key); + return i != self->end(); + } + + PyObject* keys() { + Dict::size_type size = self->size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "map size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* keyList = PyList_New(pysize); + Dict::const_iterator i = self->begin(); + for (int j = 0; j < pysize; ++i, ++j) { + PyList_SetItem(keyList, j, swigpy::from(i->first)); + } + return keyList; + } + + PyObject* values() { + Dict::size_type size = self->size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "map size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* valList = PyTuple_New(pysize); + Dict::const_iterator i = self->begin(); + for (int j = 0; j < pysize; ++i, ++j) { + PyTuple_SetItem(valList, j, swigpy::from(i->second)); + } + return valList; + } + + PyObject* items() { + Dict::size_type size = self->size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "map size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + PyObject* itemList = PyTuple_New(pysize); + Dict::const_iterator i = self->begin(); + for (int j = 0; j < pysize; ++i, ++j) { + PyTuple_SetItem(itemList, j, swigpy::from(*i)); + } + return itemList; + } + + // Python 2.2 methods + bool __contains__(const key_type& key) const { + Dict::const_iterator i = self->find(key); + return i != self->end(); + } + + PyObject* __iter__() { + Dict::size_type size = self->size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "map size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* keyList = PyList_New(pysize); + Dict::const_iterator i = self->begin(); + for (int j = 0; j < pysize; ++i, ++j) { + PyList_SetItem(keyList, j, swigpy::from(i->first)); + } +%#if PY_VERSION_HEX >= 0x02020000 + PyObject* iter = PyObject_GetIter(keyList); + Py_DECREF(keyList); + return iter; +%#else + return keyList; +%#endif + } + } +%enddef diff --git a/Lib/python/pymacros.swg b/Lib/python/pymacros.swg new file mode 100644 index 000000000..ee0275442 --- /dev/null +++ b/Lib/python/pymacros.swg @@ -0,0 +1,93 @@ +%{ +/* Auxiliar swig macros that appear in the header */ + +#ifdef __cplusplus +#define SWIGSTATICINLINE(a) static inline a +#define SWIGSTATIC(a) static a +#define swig_new_array(size,Type) (new Type[(size)]) +#define swig_delete_array(cptr) delete[] cptr +#define swig_const_cast(a,Type) const_cast(a) +#define swig_static_cast(a,Type) static_cast(a) +#define swig_reinterpret_cast(a,Type) reinterpret_cast(a) +#define swig_new_copy(ptr,Type) (new Type(*ptr)) +#define swig_numeric_cast(a,Type) static_cast(a) + +#else /* C case */ + +#define SWIGSTATICINLINE(a) static a +#define SWIGSTATIC(a) static a +#define swig_new_array(size,Type) ((Type*) malloc((size)*sizeof(Type))) +#define swig_delete_array(cptr) free((char*)cptr) +#define swig_const_cast(a,Type) (Type)(a) +#define swig_static_cast(a,Type) (Type)(a) +#define swig_reinterpret_cast(a,Type) (Type)(a) +#define swig_numeric_cast(a,Type) (Type)(a) +#define swig_new_copy(ptr,Type) ((Type*)memcpy(malloc(sizeof(Type)),ptr,sizeof(Type))) + +#endif /* __cplusplus */ +%} + + +/* Auxiliar swig macros used to write typemaps */ +#define SWIG_arg(...) __VA_ARGS__ +#define SWIG_str(...) #__VA_ARGS__ + +#define SWIG_Mangle(...) #@__VA_ARGS__ + +#define SWIG_MethodType(Name, ...) SWIG_ ## Name ## _ ## #@__VA_ARGS__ +#define SWIG_StringType(Name, ...) "SWIG_" #Name "_" {__VA_ARGS__} + +#define SWIG_AsVal_meth(...) SWIG_MethodType(AsVal, __VA_ARGS__) +#define SWIG_AsPtr_meth(...) SWIG_MethodType(AsPtr, __VA_ARGS__) +#define SWIG_As_meth(...) SWIG_MethodType(As, __VA_ARGS__) +#define SWIG_From_meth(...) SWIG_MethodType(From, __VA_ARGS__) +#define SWIG_Check_meth(...) SWIG_MethodType(Check, __VA_ARGS__) +#define SWIG_CCode(...) SWIG_MethodType(TYPECHECK, __VA_ARGS__) +#define SWIG_Order(...) SWIG_MethodType(Order, __VA_ARGS__) + +#define SWIG_Traits_frag(...) SWIG_StringType(Traits, __VA_ARGS__) +#define SWIG_AsPtr_frag(...) SWIG_StringType(AsPtr, __VA_ARGS__) +#define SWIG_AsVal_frag(...) SWIG_StringType(AsVal, __VA_ARGS__) +#define SWIG_As_frag(...) SWIG_StringType(As, __VA_ARGS__) +#define SWIG_From_frag(...) SWIG_StringType(From, __VA_ARGS__) +#define SWIG_Check_frag(...) SWIG_StringType(Check, __VA_ARGS__) +#define SWIG_CCode_frag(...) SWIG_StringType(TYPECHECK, __VA_ARGS__) + + +%define SWIG_define(Def, Val) +%#define Def Val +%enddef + +%define SWIG_cplusplus(cppval, cval) +#if __cplusplus +cppval +#else +cval +#endif +%enddef + +/* for loop for macro with one argument */ + +%define %_formacro_1(macro, arg1,...) +macro(arg1) +#if #__VA_ARGS__ != "__fordone__" +%_formacro_1(macro, __VA_ARGS__) +#endif +%enddef + +%define %formacro_1(macro,...) +%_formacro_1(macro,__VA_ARGS__,__fordone__) +%enddef + +/* for loop for macro with two arguments */ + +%define %_formacro_2(macro, arg1, arg2, ...) +macro(arg1, arg2) +#if #__VA_ARGS__ != "__fordone__" +%_formacro_2(macro, __VA_ARGS__) +#endif +%enddef + +%define %formacro_2(macro,...) +%_formacro_2(macro, __VA_ARGS__, __fordone__) +%enddef diff --git a/Lib/python/pymisctypes.swg b/Lib/python/pymisctypes.swg index c57436211..751ad0425 100644 --- a/Lib/python/pymisctypes.swg +++ b/Lib/python/pymisctypes.swg @@ -5,13 +5,17 @@ %apply unsigned long { size_t }; %apply const unsigned long& { const size_t& }; +%apply unsigned long& { size_t& }; %apply long { ptrdiff_t }; %apply const long& { const ptrdiff_t& }; +%apply long& { ptrdiff_t& }; #ifdef __cplusplus %apply unsigned long { std::size_t }; %apply const unsigned long& { const std::size_t& }; +%apply unsigned long& { std::size_t& }; %apply long { std::ptrdiff_t }; %apply const long& { const std::ptrdiff_t& }; +%apply long& { std::ptrdiff_t& }; #endif diff --git a/Lib/python/pyprimtypes.swg b/Lib/python/pyprimtypes.swg index f7912210a..b0abfe001 100644 --- a/Lib/python/pyprimtypes.swg +++ b/Lib/python/pyprimtypes.swg @@ -8,357 +8,577 @@ methods. In the other cases, some extra work is needed. */ -/* - no wrapped found needed here... yet, - and we define the names SWIG for consistency - */ -%{ -#define SWIG_FromSignedChar PyInt_FromLong -#define SWIG_FromUnsignedChar PyInt_FromLong -#define SWIG_FromShort PyInt_FromLong -#define SWIG_FromUnsignedShort PyInt_FromLong -#define SWIG_FromInt PyInt_FromLong -#define SWIG_FromLong PyInt_FromLong -#define SWIG_FromFloat PyFloat_FromDouble -#define SWIG_FromDouble PyFloat_FromDouble -#define SWIG_FromFloat PyFloat_FromDouble -#define SWIG_FromDouble PyFloat_FromDouble -%} +%insert(header) { +SWIG_define(SWIG_From_meth(signed char), PyInt_FromLong); +SWIG_define(SWIG_From_meth(unsigned char), PyInt_FromLong); +SWIG_define(SWIG_From_meth(short), PyInt_FromLong); +SWIG_define(SWIG_From_meth(unsigned short), PyInt_FromLong); +SWIG_define(SWIG_From_meth(int), PyInt_FromLong); +SWIG_define(SWIG_From_meth(long), PyInt_FromLong); +SWIG_define(SWIG_From_meth(float), PyFloat_FromDouble); +SWIG_define(SWIG_From_meth(double), PyFloat_FromDouble); +SWIG_define(SWIG_From_meth(float), PyFloat_FromDouble); +SWIG_define(SWIG_From_meth(double), PyFloat_FromDouble); +} %fragment("","header") %{ #include %} -%fragment("SWIG_AsUnsignedLong","header") %{ -SWIGSTATICINLINE(unsigned long) -SWIG_AsUnsignedLong(PyObject * obj) +%fragment(SWIG_AsVal_frag(unsigned long),"header") { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(unsigned long)(PyObject * obj, unsigned long *val) { if (PyLong_Check(obj)) { - return PyLong_AsUnsignedLong(obj); - } else { - long i = PyInt_AsLong(obj); - if ( !PyErr_Occurred() && (i < 0)) { - PyErr_SetString(PyExc_TypeError, "negative value for unsigned type"); - } - return i; + if (val) *val = PyLong_AsUnsignedLong(obj); + return 1; + } + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v >= 0) { + if (val) *val = v; + return 1; + } } + if (val) { + PyErr_SetString(PyExc_TypeError, "a unsigned long is expected"); + } + return 0; +} } -%} %fragment("SWIG_CheckLongInRange","header", - fragment="") %{ -SWIGSTATICINLINE(long) -SWIG_CheckLongInRange(long value, const char* type, - long min_value, long max_value) + fragment="") { +SWIGSTATICINLINE(int) + SWIG_CheckLongInRange(long value, long min_value, long max_value, + const char *errmsg) { - if (!PyErr_Occurred()) { - if (value < min_value) { - PyObject *err = - PyString_FromFormat("value %ld is less than '%s' minimum %ld", - value, type, min_value); - - PyErr_SetObject(PyExc_OverflowError, err); - Py_DECREF(err); - } else if (value > max_value) { - PyObject *err = - PyString_FromFormat("value %ld is greater than '%s' maximum %ld", - value, type, max_value); - PyErr_SetObject(PyExc_OverflowError, err); - Py_DECREF(err); + if (value < min_value) { + if (errmsg) { + PyErr_Format(PyExc_OverflowError, + "value %ld is less than '%s' minimum %ld", + value, errmsg, min_value); } + return 0; + } else if (value > max_value) { + if (errmsg) { + PyErr_Format(PyExc_OverflowError, + "value %ld is greater than '%s' maximum %ld", + value, errmsg, max_value); + } + return 0; } - return value; + return 1; +} } -%} %fragment("SWIG_CheckUnsignedLongInRange","header", - fragment="") %{ -SWIGSTATICINLINE(unsigned long) -SWIG_CheckUnsignedLongInRange(unsigned long value, const char* type, - unsigned long max_value) + fragment="") { +SWIGSTATICINLINE(int) + SWIG_CheckUnsignedLongInRange(unsigned long value, + unsigned long max_value, + const char *errmsg) { - if (!PyErr_Occurred()) { - if (value > max_value) { - PyObject *err = - PyString_FromFormat("value %ld is greater than '%s' minimum %ld", - value, type, max_value); - PyErr_SetObject(PyExc_OverflowError, err); - Py_DECREF(err); + if (value > max_value) { + if (errmsg) { + PyErr_Format(PyExc_OverflowError, + "value %ld is greater than '%s' minimum %ld", + value, errmsg, max_value); } + return 0; } - return value; + return 1; + } } -%} -%fragment("SWIG_AsDouble","header") %{ -SWIGSTATICINLINE(double) -SWIG_AsDouble(PyObject *obj) +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(double)(PyObject *obj, double *val) { - double val = (PyFloat_Check(obj)) ? PyFloat_AsDouble(obj) : -#if HAVE_LONG_LONG - ((PyInt_Check(obj)) ? PyInt_AsLong(obj) : PyLong_AsLongLong(obj)); -#else - ((PyInt_Check(obj)) ? PyInt_AsLong(obj) : PyLong_AsLong(obj)); -#endif - if (PyErr_Occurred()) { - PyErr_Clear(); + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return 1; + } + if (PyLong_Check(obj)) { + if (val) *val = PyLong_AsDouble(obj); + return 1; + } + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return 1; + } + if (val) { PyErr_SetString(PyExc_TypeError, "a double is expected"); } - return val; + return 0; +} } -%} -%fragment("SWIG_AsLong","header") %{ -SWIGSTATICINLINE(long) -SWIG_AsLong(PyObject * obj) +%fragment(SWIG_AsVal_frag(long),"header") { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(long)(PyObject * obj, long* val) { - return PyInt_Check(obj) ? PyInt_AsLong(obj) : PyLong_AsLong(obj); + if (PyLong_Check(obj)) { + if (val) *val = PyLong_AsLong(obj); + return 1; + } + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return 1; + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a long is expected"); + } + return 0; + } } -%} -%fragment("SWIG_FromLongLong","header", - fragment="") %{ + +%fragment(SWIG_From_frag(long long),"header", + fragment="") { SWIGSTATICINLINE(PyObject* ) -SWIG_FromLongLong(long long value) + SWIG_From_meth(long long)(long long value) { return (value > LONG_MAX) ? PyLong_FromLongLong(value) - : PyInt_FromLong(swig_numeric_cast(long,value)); + : PyInt_FromLong(swig_numeric_cast(value,long)); +} } -%} -%fragment("SWIG_FromUnsignedLongLong","header", - fragment="") %{ + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment="") { SWIGSTATICINLINE(PyObject* ) -SWIG_FromUnsignedLongLong(unsigned long long value) + SWIG_From_meth(unsigned long long)(unsigned long long value) { return (value > LONG_MAX) ? PyLong_FromUnsignedLongLong(value) : - PyInt_FromLong(swig_numeric_cast(long, value)); + PyInt_FromLong(swig_numeric_cast(value,long)); +} } -%} -%fragment("SWIG_AsLongLong","header") %{ -SWIGSTATICINLINE(long long) -SWIG_AsLongLong(PyObject *obj) +%fragment(SWIG_AsVal_frag(long long),"header") { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(long long)(PyObject *obj, long long *val) { - return PyInt_Check(obj) ? - PyInt_AsLong(obj) : PyLong_AsLongLong(obj); + if (PyLong_Check(obj)) { + if (val) *val = PyLong_AsLongLong(obj); + return 1; + } + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return 1; + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a long long is expected"); + } + return 0; +} } -%} -%fragment("SWIG_AsUnsignedLongLong","header", - fragment="SWIG_AsUnsignedLong") %{ -SWIGSTATICINLINE(unsigned long long) -SWIG_AsUnsignedLongLong(PyObject *obj) +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment=SWIG_AsVal_frag(unsigned long)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(unsigned long long)(PyObject *obj, unsigned long long *val) { - return PyLong_Check(obj) ? - PyLong_AsUnsignedLongLong(obj) : SWIG_AsUnsignedLong(obj); + if (PyLong_Check(obj)) { + if (val) *val = PyLong_AsUnsignedLongLong(obj); + return 1; + } + unsigned long v; + if (SWIG_AsVal_meth(unsigned long)(obj,&v)) { + if (val) *val = v; + return 1; + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a long long is expected"); + } + return 0; +} } -%} -%fragment("SWIG_FromUnsignedLong","header") %{ +%fragment(SWIG_From_frag(unsigned long),"header") { SWIGSTATICINLINE(PyObject* ) -SWIG_FromUnsignedLong(unsigned long value) + SWIG_From_meth(unsigned long)(unsigned long value) { return (value > LONG_MAX) ? PyLong_FromUnsignedLong(value) - : PyInt_FromLong(swig_numeric_cast(long,value)); + : PyInt_FromLong(swig_numeric_cast(value,long)); +} } -%} -%fragment("SWIG_AsSignedChar","header", +%fragment(SWIG_AsVal_frag(signed char),"header", fragment="SWIG_CheckLongInRange", - fragment="SWIG_AsLong") %{ -SWIGSTATICINLINE(signed char) -SWIG_AsSignedChar(PyObject *obj) -{ - return swig_numeric_cast(signed char, - SWIG_CheckLongInRange(SWIG_AsLong(obj), - "signed char", SCHAR_MIN, SCHAR_MAX)); + fragment=SWIG_AsVal_frag(long)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(signed char)(PyObject *obj, signed char *val) +{ + const char* errmsg = val ? "signed char" : 0; + long v; + if (SWIG_AsVal_meth(long)(obj, &v)) { + if (SWIG_CheckLongInRange(v, SCHAR_MIN, SCHAR_MAX, errmsg)) { + if (val) *val = swig_numeric_cast(v, signed char); + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a signed char is expected"); + } + return 0; +} } -%} -%fragment("SWIG_AsShort","header", +%fragment(SWIG_AsVal_frag(short),"header", fragment="SWIG_CheckLongInRange", - fragment="SWIG_AsLong") %{ -SWIGSTATICINLINE(short) -SWIG_AsShort(PyObject *obj) + fragment=SWIG_AsVal_frag(long)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(short)(PyObject *obj, short *val) { - return swig_numeric_cast(short, - SWIG_CheckLongInRange(SWIG_AsLong(obj), - "short", SHRT_MIN, SHRT_MAX)); + const char* errmsg = val ? "short" : 0; + long v; + if (SWIG_AsVal_meth(long)(obj, &v)) { + if (SWIG_CheckLongInRange(v, SHRT_MIN, SHRT_MAX, errmsg)) { + if (val) *val = swig_numeric_cast(v, short); + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a short is expected"); + } + return 0; +} } -%} /* need range checks */ -%fragment("SWIG_AsInt","header", +%fragment(SWIG_AsVal_frag(int),"header", fragment="SWIG_CheckLongInRange", - fragment="SWIG_AsLong") %{ -#if INT_MAX != LONG_MAX + fragment=SWIG_AsVal_frag(long)) { +%#if INT_MAX != LONG_MAX SWIGSTATICINLINE(int) -SWIG_AsInt(PyObject *obj) +SWIG_AsVal_meth(int)(PyObject *obj, int *val) { - return swig_numeric_cast(int, - SWIG_CheckLongInRange(SWIG_AsLong(obj), - "int", INT_MIN, INT_MAX)); -} -#else -#define SWIG_AsInt SWIG_AsLong -#endif -%} -%fragment("SWIG_AsUnsignedInt","header", - fragment="SWIG_CheckUnsignedLongInRange", - fragment="SWIG_AsUnsignedLong") %{ -#if UINT_MAX != ULONG_MAX -SWIGSTATICINLINE(unsigned int) -SWIG_AsUnsignedInt(PyObject *obj) -{ - return swig_numeric_cast(unsigned int, - SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), - "unsigned int", UINT_MAX)); -} -#else -#define SWIG_AsUnsignedInt SWIG_AsUnsignedLong -#endif -%} - -%fragment("SWIG_FromUnsignedInt","header", - fragment="SWIG_FromUnsignedLong") %{ -#if UINT_MAX < LONG_MAX -#define SWIG_FromUnsignedInt SWIG_FromLong -#else -#define SWIG_FromUnsignedInt SWIG_FromUnsignedLong -#endif -%} - - -%fragment("SWIG_AsUnsignedChar","header", - fragment="SWIG_CheckUnsignedLongInRange", - fragment="SWIG_AsUnsignedLong") %{ -SWIGSTATICINLINE(unsigned char) -SWIG_AsUnsignedChar(PyObject *obj) -{ - return swig_numeric_cast(unsigned char, - SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), - "unsigned char", UCHAR_MAX)); -} -%} - -%fragment("SWIG_AsUnsignedShort","header", - fragment="SWIG_CheckUnsignedLongInRange", - fragment="SWIG_AsUnsignedLong") %{ -SWIGSTATICINLINE(unsigned short ) -SWIG_AsUnsignedShort(PyObject *obj) -{ - return swig_numeric_cast(unsigned short, - SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), - "unsigned short", USHRT_MAX)); -} -%} - - -%fragment("SWIG_FloatCast","header") %{ -#include - -SWIGSTATIC(float) -SWIG_FloatCast(double value) -{ - float f = 0; - if (!PyErr_Occurred()) { - if (value < FLT_MIN) { - PyObject *err = - PyString_FromFormat("value %g is less than float minimum %g", - value, FLT_MIN); - PyErr_SetObject(PyExc_OverflowError, err); - Py_DECREF(err); - } else if (value > FLT_MAX) { - PyObject *err = - PyString_FromFormat("value %g is greater than float maximum %g", - value, FLT_MAX); - PyErr_SetObject(PyExc_OverflowError, err); - Py_DECREF(err); + const char* errmsg = val ? "int" : 0; + long v; + if (SWIG_AsVal_meth(long)(obj, &v)) { + if (SWIG_CheckLongInRange(v, INT_MIN,INT_MAX, errmsg)) { + if (val) *val = swig_numeric_cast(v, int); + return 1; } else { - f = swig_numeric_cast(float, value); + return 0; } + } else { + PyErr_Clear(); } - return f; + if (val) { + PyErr_SetString(PyExc_TypeError, "a int is expected"); + } + return 0; } -%} - -%fragment("SWIG_AsFloat","header", - fragment="SWIG_FloatCast", - fragment="SWIG_AsDouble") %{ -SWIGSTATICINLINE(float) -SWIG_AsFloat(PyObject *obj) +%#else +SWIGSTATICINLINE(int) +SWIG_AsVal_meth(int)(PyObject *obj, int *val) { - return SWIG_FloatCast(SWIG_AsDouble(obj)); + return SWIG_AsVal_meth(long)(obj,(long*)val); +} +%#endif } -%} -%fragment("SWIG_FromChar","header") %{ +%fragment(SWIG_AsVal_frag(unsigned int),"header", + fragment="SWIG_CheckUnsignedLongInRange", + fragment=SWIG_AsVal_frag(unsigned long)) { +%#if UINT_MAX != ULONG_MAX +SWIGSTATICINLINE(int) +SWIG_AsVal_meth(unsigned int)(PyObject *obj, unsigned int *val) +{ + const char* errmsg = val ? "unsigned int" : 0; + unsigned long v; + if (SWIG_AsVal_meth(unsigned long)(obj, &v)) { + if (SWIG_CheckUnsignedLongInRange(v, INT_MAX, errmsg)) { + if (val) *val = swig_numeric_cast(v, unsigned int); + return 1; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a unsigned int is expected"); + } + return 0; +} +%#else +SWIGSTATICINLINE(unsigned int) + SWIG_AsVal_meth(unsigned int)(PyObject *obj, unsigned int *val) +{ + return SWIG_AsVal_meth(unsigned long)(obj,(unsigned long *)val); +} +%#endif +} + +%fragment(SWIG_From_frag(unsigned int),"header", + fragment=SWIG_From_frag(long), + fragment=SWIG_From_frag(unsigned long)) { +%#if UINT_MAX < LONG_MAX +SWIG_define(SWIG_From_meth(unsigned int), SWIG_From_meth(long)); +%#else +SWIG_define(SWIG_From_meth(unsigned int), SWIG_From_meth(unsigned long)); +%#endif +} + +%fragment(SWIG_AsVal_frag(unsigned char),"header", + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CheckUnsignedLongInRange") { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(unsigned char)(PyObject *obj, unsigned char *val) +{ + const char* errmsg = val ? "unsigned char" : 0; + unsigned long v; + if (SWIG_AsVal_meth(unsigned long)(obj, &v)) { + if (SWIG_CheckUnsignedLongInRange(v, UCHAR_MAX,errmsg)) { + if (val) *val = swig_numeric_cast(v, unsigned char); + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a unsigned char is expected"); + } + return 0; +} +} + +%fragment(SWIG_AsVal_frag(unsigned short),"header", + fragment="SWIG_CheckUnsignedLongInRange", + fragment=SWIG_AsVal_frag(unsigned long)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(unsigned short)(PyObject *obj, unsigned short *val) +{ + const char* errmsg = val ? "unsigned short" : 0; + unsigned long v; + if (SWIG_AsVal_meth(unsigned long)(obj, &v)) { + if (SWIG_CheckUnsignedLongInRange(v, USHRT_MAX, errmsg)) { + if (val) *val = swig_numeric_cast(v, unsigned short); + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a unsigned short is expected"); + } + return 0; +} +} + + +%fragment("SWIG_CheckDoubleInRange","header") { +%#include + +SWIGSTATIC(int) + SWIG_CheckDoubleInRange(double value, double min_value, + double max_value, const char* errmsg) +{ + if (value < min_value) { + if (errmsg) { + PyErr_Format(PyExc_OverflowError, + "value %g is less than %s minimum %g", + value, errmsg, min_value); + } + return 0; + } else if (value > max_value) { + if (errmsg) { + PyErr_Format(PyExc_OverflowError, + "value %g is greater than %s maximum %g", + value, errmsg, max_value); + } + return 0; + } + return 1; +} +} + +%fragment(SWIG_AsVal_frag(float),"header", + fragment="SWIG_CheckDoubleInRange", + fragment=SWIG_AsVal_frag(double)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(float)(PyObject *obj, float *val) +{ + const char* errmsg = val ? "float" : 0; + double v; + if (SWIG_AsVal_meth(double)(obj, &v)) { + if (SWIG_CheckDoubleInRange(v, FLT_MIN, FLT_MAX, errmsg)) { + if (val) *val = v; + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a float is expected"); + } + return 0; +} +} + +%fragment(SWIG_From_frag(char),"header") { SWIGSTATICINLINE(PyObject*) -SWIG_FromChar(char c) + SWIG_From_meth(char)(char c) { return PyString_FromStringAndSize(&c,1); } -%} +} -%fragment("SWIG_FromBool","header") %{ +%fragment(SWIG_AsVal_frag(char),"header", + fragment="SWIG_AsCharArray", + fragment="SWIG_CheckLongInRange", + fragment=SWIG_AsVal_frag(long)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(char)(PyObject *obj, char *val) +{ + const char* errmsg = val ? "char" : 0; + long v; + if (SWIG_AsVal_meth(long)(obj, &v)) { + if (SWIG_CheckLongInRange(v, CHAR_MIN,CHAR_MAX, errmsg)) { + if (val) *val = v; + return 1; + } else { + return 0; + } + } else { + PyErr_Clear(); + return SWIG_AsCharArray(obj, val, 1); + } + } +} + +%fragment(SWIG_From_frag(bool),"header") { SWIGSTATICINLINE(PyObject*) -SWIG_FromBool(bool value) + SWIG_From_meth(bool)(bool value) { PyObject *obj = value ? Py_True : Py_False; Py_INCREF(obj); return obj; } -%} +} -%fragment("SWIG_AsBool","header") %{ -SWIGSTATICINLINE(bool) -SWIG_AsBool(PyObject *obj) +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(int)) { +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(bool)(PyObject *obj, bool *val) { - return PyObject_IsTrue(obj) ? true : false; -} -%} - -%fragment("SWIG_AsChar","header", - fragment="SWIG_AsCharArray", - fragment="SWIG_CheckLongInRange", - fragment="SWIG_AsLong") %{ -SWIGSTATICINLINE(char) -SWIG_AsChar(PyObject *obj) -{ - char c = 0; - if (PyInt_Check(obj) || PyLong_Check(obj)) { - c = swig_numeric_cast(char, - SWIG_CheckLongInRange(SWIG_AsLong(obj), - "char", CHAR_MIN, CHAR_MAX)); - } else { - SWIG_AsCharArray(obj, &c, 1); - if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "a char is expected"); - } + /* if (val) *val = PyObject_IsTrue(obj); return 1; */ + if (obj == Py_True) { + if (val) *val = true; + return 1; } - return c; + if (obj == Py_False) { + if (val) *val = false; + return 1; + } + int res; + if (SWIG_AsVal_meth(int)(obj, &res)) { + if (val) *val = (bool)res; + return 1; + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a float is expected"); + } + return 0; +} } -%} -%typemap_stype(bool, BOOL, Bool); -%typemap_stype(signed char, INT8, SignedChar); -%typemap_stype(unsigned char, UINT8, UnsignedChar); -%typemap_stype(short, INT16, Short); -%typemap_stype(unsigned short, UINT16, UnsignedShort); -%typemap_stype(int, INT32, Int); -%typemap_stype(unsigned int, UINT32, UnsignedInt); -%typemap_stype(long, INT64, Long); -%typemap_stype(unsigned long, UINT64, UnsignedLong); -%typemap_stype(long long, INT128, LongLong); -%typemap_stype(unsigned long long, UINT128, UnsignedLongLong); -%typemap_stype(float, FLOAT, Float); -%typemap_stype(double, DOUBLE, Double); -%typemap_stype(char, CHAR, Char); + +/* ------------------------------------------------------------ + * typemap for primitive type with no pointer representation + * ------------------------------------------------------------ */ + +%define %typemap_primitive(Code, ...) +%typemap_asvalfromn(SWIG_arg(Code), __VA_ARGS__); +%enddef + +%typemap_primitive(SWIG_CCode(BOOL), bool); +%typemap_primitive(SWIG_CCode(INT8), signed char); +%typemap_primitive(SWIG_CCode(UINT8), unsigned char); +%typemap_primitive(SWIG_CCode(INT16), short); +%typemap_primitive(SWIG_CCode(UINT16), unsigned short); +%typemap_primitive(SWIG_CCode(INT32), int); +%typemap_primitive(SWIG_CCode(UINT32), unsigned int); +%typemap_primitive(SWIG_CCode(INT64), long); +%typemap_primitive(SWIG_CCode(UINT64), unsigned long); +%typemap_primitive(SWIG_CCode(INT128), long long); +%typemap_primitive(SWIG_CCode(UINT128), unsigned long long); +%typemap_primitive(SWIG_CCode(FLOAT), float); +%typemap_primitive(SWIG_CCode(DOUBLE), double); +%typemap_primitive(SWIG_CCode(CHAR), char); + + +/* ------------------------------------------------------------ + * Primitive Type Macros + * ------------------------------------------------------------ */ + +/* useful macros to derive typemap declarations from primitive types */ + +%define _apply_macro(macro, arg, ...) +#if #__VA_ARGS__ != "" + macro(__VA_ARGS__,arg); +#else + macro(arg); +#endif +%enddef + +/* Apply macro to the order types */ +%define %apply_otypes(Macro,...) +_apply_macro(Macro, signed char , __VA_ARGS__); +_apply_macro(Macro, unsigned char , __VA_ARGS__); +_apply_macro(Macro, short , __VA_ARGS__); +_apply_macro(Macro, unsigned short , __VA_ARGS__); +_apply_macro(Macro, int , __VA_ARGS__); +_apply_macro(Macro, unsigned int , __VA_ARGS__); +_apply_macro(Macro, long , __VA_ARGS__); +_apply_macro(Macro, unsigned long , __VA_ARGS__); +_apply_macro(Macro, long long , __VA_ARGS__); +_apply_macro(Macro, unsigned long long , __VA_ARGS__); +_apply_macro(Macro, float , __VA_ARGS__); +_apply_macro(Macro, double , __VA_ARGS__); +_apply_macro(Macro, char , __VA_ARGS__); +%enddef + +/* apply the Macro(Type) to all the C types */ +%define %apply_ctypes(Macro,...) +%apply_otypes(Macro, __VA_ARGS__) +_apply_macro(Macro, bool, __VA_ARGS__); +%enddef + +/* apply the Macro(Type) to all the C++ types */ +%define %apply_cpptypes(Macro,...) +%apply_otypes(Macro, __VA_ARGS__) +_apply_macro(Macro, bool, __VA_ARGS__); +_apply_macro(Macro, std::string, __VA_ARGS__); +_apply_macro(Macro, std::complex, __VA_ARGS__); +_apply_macro(Macro, std::complex, __VA_ARGS__); +%enddef + +/* apply the Macro2(Type1, Type2) to all the C++ types */ +%define %apply_cpptypes_2(Macro2) +%apply_cpptypes(%apply_cpptypes, Macro2) +%enddef + diff --git a/Lib/python/pyptrtypes.swg b/Lib/python/pyptrtypes.swg new file mode 100644 index 000000000..cd42ca3c9 --- /dev/null +++ b/Lib/python/pyptrtypes.swg @@ -0,0 +1,146 @@ +/* + Value typemaps (Type, const Type&) for "Ptr" types, such as swig + wrapped classes, that define the AsPtr/From methods +*/ + +/* in */ + +%define PYPTR_IN_TYPEMAP(pyobj_asptr,pyfrag,...) + %typemap(in,fragment=pyfrag) __VA_ARGS__ { + __VA_ARGS__ *ptr; + int res = pyobj_asptr($input, &ptr); + if (!res) SWIG_fail; + $1 = *ptr; + if (res > 1) delete ptr; + } + %typemap(in,fragment=pyfrag) const __VA_ARGS__ & (int res = 0) + "if (!(res = pyobj_asptr($input, &$1))) SWIG_fail;"; + + %typemap(freearg) const __VA_ARGS__ & + "if (res$argnum > 1) delete $1;"; +%enddef + +/* out */ + +%define PYPTR_OUT_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(out,fragment=pyfrag) __VA_ARGS__ + "$result = pyobj_from($1);"; + %typemap(out,fragment=pyfrag) const __VA_ARGS__& + "$result = pyobj_from(*($1));"; +%enddef + +/* varin */ + +%define PYPTR_VARIN_TYPEMAP(pyobj_asptr,pyfrag,...) + %typemap(varin,fragment=pyfrag) __VA_ARGS__ { + __VA_ARGS__ *ptr; + int res = pyobj_asptr($input, &ptr); + if (!res) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + if (!res) SWIG_fail; + $1 = *ptr; + if (res > 1) delete ptr; + } +%enddef + +/* varout */ + +%define PYPTR_VAROUT_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(varout,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& + "$result = pyobj_from($1);"; +%enddef + +/* Primitive types */ +%define PYPTR_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(constcode,fragment=pyfrag) __VA_ARGS__ + "PyDict_SetItemString(d,\"$symname\", pyobj_from($value));"; +%enddef + + +/* directorin */ + +%define PYPTR_DIRECTORIN_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(directorin,fragment=pyfrag) __VA_ARGS__ + "$input = pyobj_from($1_name);"; +%enddef + +/* directorout */ + +%define PYPTR_DIRECTOROUT_TYPEMAP(pyobj_asptr,pyfrag,...) + %typemap(directorargout,fragment=pyfrag) __VA_ARGS__ *DIRECTOROUT ($*1_ltype temp) { + __VA_ARGS__ *ptr; + int res = pyobj_asptr($input, &ptr); + if (!res) + throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + temp = *ptr; + $result = &temp; + if (res > 1) delete ptr; + } + %typemap(directorout,fragment=pyfrag) __VA_ARGS__ { + __VA_ARGS__ *ptr; + int res = pyobj_asptr($input, &ptr); + if (!res) + throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + $result = *ptr; + if (res > 1) delete ptr; + } + %typemap(directorout,fragment=pyfrag) const __VA_ARGS__& ($*1_ltype temp) { + __VA_ARGS__ *ptr; + int res = pyobj_asptr($input, &ptr); + if (!res) + throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + temp = *ptr; + $result = &temp; + if (res > 1) delete ptr; + } + %typemap(directorout,fragment=pyfrag) __VA_ARGS__ &DIRECTOROUT = __VA_ARGS__ +%enddef + +/* throws */ + +%define PYPTR_THROWS_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(throws,fragment=pyfrag) __VA_ARGS__ { + PyErr_SetObject(PyExc_RuntimeError, pyobj_from($1)); + SWIG_fail; + } +%enddef + +/* typecheck */ + +%define PYPTR_TYPECHECK_TYPEMAP(check,pyobj_asptr,pyfrag,...) +%typemap(typecheck,precedence=check,fragment=pyfrag) + __VA_ARGS__, const __VA_ARGS__& + "$1 = pyobj_asptr($input, (__VA_ARGS__**)(0));"; +%enddef + +/* + typemap definition for types with AsPtr/From methods + */ + +%define %typemap_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, ...) + PYPTR_IN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); + PYPTR_OUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYPTR_VARIN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); + PYPTR_VAROUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYPTR_CONSTCODE_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYPTR_DIRECTORIN_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYPTR_DIRECTOROUT_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); + PYPTR_THROWS_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag),__VA_ARGS__); + PYPTR_TYPECHECK_TYPEMAP(SWIG_arg(CheckCode), SWIG_arg(AsPtrMeth), + SWIG_arg(AsPtrFrag), __VA_ARGS__); +%enddef + +/* + typemap for simple swig types with only AsPtr/From conversor methods +*/ + +%define %typemap_asptrfromn(CheckCode, ...) +%typemap_asptrfrom(SWIG_arg(CheckCode), + SWIG_AsPtr_meth(__VA_ARGS__), + SWIG_From_meth(__VA_ARGS__), + SWIG_arg(SWIG_AsPtr_frag(__VA_ARGS__)), + SWIG_arg(SWIG_From_frag(__VA_ARGS__)), + __VA_ARGS__); +%enddef diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index b484a5254..8e6fcf814 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -163,6 +163,7 @@ statichere PyTypeObject varlinktype = { 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ @@ -183,6 +184,14 @@ statichere PyTypeObject varlinktype = { 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ +#endif +#ifdef COUNT_ALLOCS + /* these must be last */ + 0, /* tp_alloc */ + 0, /* tp_free */ + 0, /* tp_maxalloc */ + 0, /* tp_next */ +#endif }; /* Create a variable linking object for use later */ @@ -293,10 +302,9 @@ cobject: type_error: if (flags & SWIG_POINTER_EXCEPTION) { if (ty && c) { - PyObject *err = - PyString_FromFormat("Type error. Got %s, expected %s",c,ty->name); - PyErr_SetObject(PyExc_TypeError, err); - Py_DECREF(err); + PyErr_Format(PyExc_TypeError, + "Type error. Got %s, expected %s", + c, ty->name); } else { PyErr_SetString(PyExc_TypeError,"Expected a pointer"); } @@ -334,10 +342,9 @@ type_error: if (flags) { if (ty && c) { - PyObject *err = - PyString_FromFormat("Type error. Got %s, expected %s",c,ty->name); - PyErr_SetObject(PyExc_TypeError, err); - Py_DECREF(err); + PyErr_Format(PyExc_TypeError, + "Type error. Got %s, expected %s", + c, ty->name); } else { PyErr_SetString(PyExc_TypeError,"Expected a pointer"); } diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg index b5bbb69ed..499cc5d8a 100644 --- a/Lib/python/pystrings.swg +++ b/Lib/python/pystrings.swg @@ -6,42 +6,53 @@ %types(char *); %fragment("SWIG_AsCharPtrAndSize","header") %{ -/* returns '1' if the input is a raw char*, '0' if is a PyString */ +/* returns '1' if the input is a raw char*, '2' if is a PyString */ SWIGSTATIC(int) SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size) { static swig_type_info* pchar_info = 0; - int psize = 0; + int vsize = 0; + char* vptr = 0; if (!pchar_info) pchar_info = SWIG_TypeQuery("char *"); - if (SWIG_ConvertPtr(obj, swig_reinterpret_cast(void **,cptr), pchar_info, 0) == -1) { - PyErr_Clear(); - PyString_AsStringAndSize(obj, cptr, &psize); - if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError,"a string is expected"); - } - if (size) *size = psize; - return 0; - } else { - if (size) *size = (*cptr) ? (strlen(*cptr) + 1) : 0; + if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_info, 0) != -1) { + if (cptr) *cptr = vptr; + if (size) *size = vptr ? (strlen(vptr) + 1) : 0; return 1; + } else { + if (PyString_Check(obj)) { +#if PY_VERSION_HEX >= 0x02000000 + PyString_AsStringAndSize(obj, &vptr, &vsize); +#else + vptr = PyString_AsString(obj); + vsize = PyString_Size(obj); +#endif + if (cptr) *cptr = vptr; + if (size) *size = vsize; + return 2; + } } + if (cptr || size) { + PyErr_SetString(PyExc_TypeError, "a string is expected"); + } + return 0; } %} %fragment("SWIG_AsCharPtr","header", fragment="SWIG_AsCharPtrAndSize") %{ -SWIGSTATICINLINE(char* ) -SWIG_AsCharPtr(PyObject *obj) +SWIGSTATICINLINE(int) + SWIG_AsCharPtr(PyObject *obj, char **val) { char* cptr; - SWIG_AsCharPtrAndSize(obj, &cptr, 0); - if (PyErr_Occurred()) { - PyErr_Clear(); + if (SWIG_AsCharPtrAndSize(obj, &cptr, 0)) { + if (val) *val = cptr; + return 1; + } + if (val) { PyErr_SetString(PyExc_TypeError, "a char* is expected"); - } - return cptr; + } + return 0; } %} @@ -52,10 +63,10 @@ SWIG_FromCharPtr(const char* cptr) size_t size = cptr ? strlen(cptr) : 0; if (cptr) { if (size > INT_MAX) { - return SWIG_NewPointerObj(swig_const_cast(char*,cptr), + return SWIG_NewPointerObj(swig_const_cast(cptr,char*), SWIG_TypeQuery("char *"), 0); } else { - return PyString_FromStringAndSize(cptr, swig_numeric_cast(int,size)); + return PyString_FromStringAndSize(cptr, swig_numeric_cast(size,int)); } } else { Py_INCREF(Py_None); @@ -66,43 +77,44 @@ SWIG_FromCharPtr(const char* cptr) %fragment("SWIG_AsNewCharPtr","header", fragment="SWIG_AsCharPtrAndSize") %{ -SWIGSTATIC(char*) -SWIG_AsNewCharPtr(PyObject *obj) +SWIGSTATIC(int) + SWIG_AsNewCharPtr(PyObject *obj, char **val) { - char *res = 0; - char* cptr; size_t csize; - int is_raw_pchar = SWIG_AsCharPtrAndSize(obj, &cptr, &csize); - if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "a char* is expected"); - } else if (cptr) { - /* we add the '0' terminator if needed */ - size_t size = (!is_raw_pchar && csize && !(cptr[csize - 1])) ? - csize : csize + 1; - if (size) { - res = swig_new_array(char, size); - if (csize) memcpy(res, cptr, csize); - if (csize < size) res[csize] = 0; + char* cptr = 0; size_t csize = 0; + int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize); + if (res) { + if (val) { + /* we add the '0' terminator if needed for PyString */ + size_t size = ((res == 2) && csize && (cptr[csize - 1])) ? + csize + 1 : csize; + if (size) { + *val = swig_new_array(size, char); + if (csize) memcpy(*val, cptr, csize); + if (csize < size) (*val)[csize] = 0; + } else if (cptr) { + *val = swig_new_array(1, char); + (*val)[0] = 0; + } else { + *val = 0; + } + } + return 1; + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a char* is expected"); } - return res; + return 0; } %} %fragment("SWIG_AsCharArray","header", fragment="SWIG_AsCharPtrAndSize") %{ -SWIGSTATIC(void) -SWIG_AsCharArray(PyObject *obj, char* carray, size_t size) +SWIGSTATIC(int) +SWIG_AsCharArray(PyObject *obj, char *val, size_t size) { char* cptr; size_t csize; - SWIG_AsCharPtrAndSize(obj, &cptr, &csize); - if (PyErr_Occurred()) { - PyErr_Clear(); - PyObject *err = - PyString_FromFormat("a char array of size %d is expected", size); - PyErr_SetObject(PyExc_TypeError, err); - Py_DECREF(err); - } else { + if (SWIG_AsCharPtrAndSize(obj, &cptr, &csize)) { /* in C (but not in C++) you can do: char x[5] = "hello"; @@ -112,17 +124,20 @@ SWIG_AsCharArray(PyObject *obj, char* carray, size_t size) #ifndef __cplusplus if ((csize == size + 1) && !(cptr[csize-1])) --csize; #endif - if (csize > size) { - PyObject *err = - PyString_FromFormat("a char array of maximum size %d is expected", - size); - PyErr_SetObject(PyExc_TypeError, err); - Py_DECREF(err); - } else { - if (csize) memcpy(carray, cptr, csize); - if (csize < size) memset(carray + csize, 0, size - csize); + if (csize <= size) { + if (val) { + if (csize) memcpy(val, cptr, csize); + if (csize < size) memset(val + csize, 0, size - csize); + } + return 1; } } + if (val) { + PyErr_Format(PyExc_TypeError, + "a char array of maximum size %d is expected", + size); + } + return 0; } %} @@ -131,10 +146,10 @@ SWIGSTATICINLINE(PyObject *) SWIG_FromCharArray(const char* carray, size_t size) { if (size > INT_MAX) { - SWIG_NewPointerObj(swig_const_cast(char*,carray), SWIG_TypeQuery("char *"), 0); + SWIG_NewPointerObj(swig_const_cast(carray,char*), SWIG_TypeQuery("char *"), 0); return Py_None; } else { - return PyString_FromStringAndSize(carray, swig_numeric_cast(int,size)); + return PyString_FromStringAndSize(carray, swig_numeric_cast(size,int)); } } %} @@ -147,14 +162,13 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(in,fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const *const - "$1 = SWIG_AsCharPtr($input); - if (PyErr_Occurred()) SWIG_fail;"; + "if (!SWIG_AsCharPtr($input, (char**)&$1)) SWIG_fail;"; %typemap(in,fragment="SWIG_AsCharPtr") char const*&, char *const&, char const *const & { - $*ltype temp = SWIG_AsCharPtr($input); - if (PyErr_Occurred()) SWIG_fail; + $*ltype temp; + if (!SWIG_AsCharPtr($input, (char**)&temp)) SWIG_fail; $1 = &temp; } @@ -172,8 +186,9 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(varin,fragment="SWIG_AsNewCharPtr") char * { - char *cptr = SWIG_AsNewCharPtr($input); - if (PyErr_Occurred()) { + char *cptr = 0; + if (!SWIG_AsNewCharPtr($input, &cptr)) { + PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } @@ -185,8 +200,9 @@ SWIG_FromCharArray(const char* carray, size_t size) warning="451:Setting const char * variable may leak memory") const char * { - char *cptr = SWIG_AsNewCharPtr($input); - if (PyErr_Occurred()) { + char *cptr; + if (!SWIG_AsNewCharPtr($input, &cptr)) { + PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } @@ -210,7 +226,7 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(directorin,fragment="SWIG_FromCharPtr") char *, char const*, char *const, char const *const, char const *&, char *const &, char const *const & - "$input = SWIG_NewPointerObj(swig_const_cast(char*,$1_name), $descriptor(char *), 0);" + "$input = SWIG_NewPointerObj((char*)($1_name), $descriptor(char *), 0);" /* "$input = SWIG_FromCharPtr($1_name);"; */ @@ -218,16 +234,15 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(directorout,fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const* const - "$result = SWIG_AsCharPtr($input); - if (PyErr_Occurred()) { + "if (!SWIG_AsCharPtr($input, (char**) &$result)) { Swig::DirectorTypeMismatchException(\"Error converting Python object into char*\"); }"; %typemap(directorout,fragment="SWIG_AsCharPtr") char const *&, char *const &, char const *const & { - char* temp = SWIG_AsCharPtr($input); - if (PyErr_Occurred()) { + char* temp; + if (!SWIG_AsCharPtr($input, &temp)) { Swig::DirectorTypeMismatchException("Error converting Python object into char*"); } $result = ($1_ltype) &temp; @@ -239,13 +254,7 @@ SWIG_FromCharArray(const char* carray, size_t size) fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const *const, char const*&, char *const&, char const *const & - "SWIG_AsCharPtr($input); - if (PyErr_Occurred()) { - $1 = 0; - PyErr_Clear(); - } else { - $1 = 1; - }"; + "$1 = SWIG_AsCharPtr($input, (char **)(0));"; /* throws */ @@ -281,8 +290,7 @@ SWIG_FromCharArray(const char* carray, size_t size) char [ANY], const char [ANY] { char temp[$1_dim0]; - SWIG_AsCharArray($input, temp, $1_dim0); - if (PyErr_Occurred()) SWIG_fail; + if (!SWIG_AsCharArray($input, temp, $1_dim0)) SWIG_fail; $1 = temp; } @@ -297,8 +305,8 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(varin,fragment="SWIG_AsCharArray") char [ANY] { - SWIG_AsCharArray($input, $1, $1_dim0); - if (PyErr_Occurred()) { + if (!SWIG_AsCharArray($input, $1, $1_dim0)) { + PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } @@ -328,8 +336,7 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(directorout,fragment="SWIG_AsCharArray") char [ANY], const char [ANY] (char temp[$result_dim0]) { - SWIG_AsCharArray($input, temp, $result_dim0); - if (PyErr_Occurred()) { + if (!SWIG_AsCharArray($input, temp, $result_dim0)) { Swig::DirectorTypeMismatchException("Error converting Python object into char[$result_dim0]"); } $result = temp; @@ -340,15 +347,8 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(typecheck,precedence=SWIG_TYPECHECK_STRING, fragment="SWIG_AsCharArray") char [ANY], const char[ANY] -{ - char* carray = 0; size_t size = 0; - SWIG_AsCharArray($input, &carray, &size); - if (PyErr_Occurred()) { - $1 = 0; - PyErr_Clear(); - } else { - $1 = ((carray != 0) && (size <= $input_dim0)); - } +{ + return SWIG_AsCharArray($input, (char **)0, (size_t *)0); } /* throw */ @@ -367,18 +367,17 @@ SWIG_FromCharArray(const char* carray, size_t size) %typemap(in, fragment="SWIG_AsCharPtrAndSize") (char *STRING, int LENGTH) (char *buf, size_t size) { - int is_raw_pchar = SWIG_AsCharPtrAndSize($input, &buf, &size); - if (PyErr_Occurred()) SWIG_fail; + int res = SWIG_AsCharPtrAndSize($input, &buf, &size); + if (!res) SWIG_fail; $1 = ($1_ltype) buf; - $2 = ($2_ltype) (is_raw_pchar && size) ? size - 1 : size; + $2 = ($2_ltype) ((res == 1) && size) ? size - 1 : size; } /* Here size includes the '0' terminator */ %typemap(in,fragment="SWIG_AsCharPtrAndSize") (char *STRING, int SIZE) (char *buf, size_t size) { - SWIG_AsCharPtrAndSize($input, &buf, &size); - if (PyErr_Occurred()) SWIG_fail; + if (!SWIG_AsCharPtrAndSize($input, &buf, &size)) SWIG_fail; $1 = ($1_ltype) buf; $2 = ($2_ltype) size; } diff --git a/Lib/python/pyswigtype.swg b/Lib/python/pyswigtype.swg index 54070dddd..5f99cae18 100644 --- a/Lib/python/pyswigtype.swg +++ b/Lib/python/pyswigtype.swg @@ -4,7 +4,7 @@ /* Pointers, references, and arrays */ -%typemap(in) SWIGTYPE *, SWIGTYPE [] +%typemap(in) SWIGTYPE *, SWIGTYPE [] "if ((SWIG_ConvertPtr($input,(void **)(&$1),$1_descriptor, SWIG_POINTER_EXCEPTION | $disown)) == -1) SWIG_fail;"; diff --git a/Lib/python/python.swg b/Lib/python/python.swg index 54df253bb..bb9a3fa28 100644 --- a/Lib/python/python.swg +++ b/Lib/python/python.swg @@ -19,37 +19,8 @@ #define %shadow %insert("shadow") #define %pythoncode %insert("python") -%{ -/* Auxiliar swig macros */ +%include "pymacros.swg" -#ifdef __cplusplus -#define SWIGSTATICINLINE(a) static inline a -#define SWIGSTATIC(a) static a -#define swig_new_array(type, size) (new type[(size)]) -#define swig_delete_array(cptr) delete[] cptr -#define swig_const_cast(type,a) const_cast(a) -#define swig_static_cast(type,a) static_cast(a) -#define swig_reinterpret_cast(type,a) reinterpret_cast(a) - -#ifdef HAVE_NUMERIC_CAST -#define swig_numeric_cast(type,a) numeric_cast(a) -#else -#define swig_numeric_cast(type,a) static_cast(a) -#endif - -#else /* C case */ - -#define SWIGSTATICINLINE(a) static a -#define SWIGSTATIC(a) static a -#define swig_new_array(type, size) ((type*) malloc((size)*sizeof(type))) -#define swig_delete_array(cptr) free((char*)cptr) -#define swig_const_cast(type,a) (type)(a) -#define swig_static_cast(type,a) (type)(a) -#define swig_reinterpret_cast(type,a) (type)(a) -#define swig_numeric_cast(type,a) (type)(a) - -#endif /* __cplusplus */ -%} /* ----------------------------------------------------------------------------- * SWIGTYPE typemaps @@ -110,3 +81,4 @@ SWIGEXPORT(void) SWIG_init(void) { } SWIG_InstallConstants(d,swig_const_table); %} + diff --git a/Lib/python/pyvaltypes.swg b/Lib/python/pyvaltypes.swg index 1880e1ed2..eca6d28aa 100644 --- a/Lib/python/pyvaltypes.swg +++ b/Lib/python/pyvaltypes.swg @@ -1,10 +1,16 @@ +/* + Value typemaps (Type, const Type&) for value types, such as + fundamental types (int, double), that define the As/AsVal/From + methods. +*/ + /* in */ -%define PY_IN_TYPEMAP(type, pyobj_as) - %typemap(in,fragment=#pyobj_as) type +%define PYVAL_IN_TYPEMAP(pyobj_as,pyfrag,...) + %typemap(in,fragment=pyfrag) __VA_ARGS__ "$1 = ($1_type) pyobj_as($input); - if (PyErr_Occurred()) SWIG_fail;" - %typemap(in) const type& ($basetype temp) + if (PyErr_Occurred()) SWIG_fail;"; + %typemap(in,fragment=pyfrag) const __VA_ARGS__ & ($basetype temp) "temp = ($basetype) pyobj_as($input); if (PyErr_Occurred()) SWIG_fail; $1 = &temp;"; @@ -12,17 +18,17 @@ /* out */ -%define PY_OUT_TYPEMAP(type, pyobj_from) - %typemap(out,fragment=#pyobj_from) type - "$result = pyobj_from((type)$1);"; - %typemap(out,fragment=#pyobj_from) const type& - "$result = pyobj_from((type)*($1));"; +%define PYVAL_OUT_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(out,fragment=pyfrag) __VA_ARGS__ + "$result = pyobj_from((__VA_ARGS__)$1);"; + %typemap(out,fragment=pyfrag) const __VA_ARGS__& + "$result = pyobj_from((__VA_ARGS__)*($1));"; %enddef /* varin */ -%define PY_VARIN_TYPEMAP(type, pyobj_as) - %typemap(varin,fragment=#pyobj_as) type { +%define PYVAL_VARIN_TYPEMAP(pyobj_as,pyfrag,...) + %typemap(varin,fragment=pyfrag) __VA_ARGS__ { $1_type temp = ($1_type) pyobj_as($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); @@ -34,95 +40,145 @@ /* varout */ -%define PY_VAROUT_TYPEMAP(type, pyobj_from) - %typemap(varout,fragment=#pyobj_from) - type, const type& "$result = pyobj_from((type)$1);"; +%define PYVAL_VAROUT_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(varout,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& + "$result = pyobj_from((__VA_ARGS__)$1);"; %enddef - /* Primitive types */ -%define PY_CONSTCODE_TYPEMAP(type, pyobj_from) - %typemap(constcode,fragment=#pyobj_from) type - "PyDict_SetItemString(d,\"$symname\", pyobj_from((type)$value));"; +%define PYVAL_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(constcode,fragment=pyfrag) __VA_ARGS__ + "PyDict_SetItemString(d,\"$symname\", pyobj_from((__VA_ARGS__)$value));"; %enddef + /* directorin */ -%define PY_DIRECTORIN_TYPEMAP(type, pyobj_from) - %typemap(directorin,fragment=#pyobj_from) type *DIRECTORIN - "$input = pyobj_from((type)*$1_name);"; - %typemap(directorin,fragment=#pyobj_from) type, const type& - "$input = pyobj_from((type)$1_name);"; +%define PYVAL_DIRECTORIN_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(directorin,fragment=pyfrag) __VA_ARGS__ *DIRECTORIN + "$input = pyobj_from((__VA_ARGS__)*$1_name);"; + %typemap(directorin,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& + "$input = pyobj_from((__VA_ARGS__)$1_name);"; %enddef /* directorout */ -%define PY_DIRECTOROUT_TYPEMAP(Type, pyobj_as) - %typemap(directorargout,fragment=#pyobj_as) Type *DIRECTOROUT +%define PYVAL_DIRECTOROUT_TYPEMAP(pyobj_as,pyfrag,...) + %typemap(directorargout,fragment=pyfrag) __VA_ARGS__ *DIRECTOROUT "*$result = ($basetype) pyobj_as($input); if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; -%typemap(directorout,fragment=#pyobj_as) Type +%typemap(directorout,fragment=pyfrag) __VA_ARGS__ "$result = ($basetype) pyobj_as($input); if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; -%typemap(directorout,fragment=#pyobj_as) const Type& +%typemap(directorout,fragment=pyfrag) const __VA_ARGS__& "$basetype temp = ($basetype) pyobj_as($input); $result = &temp; if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; - %typemap(directorout,fragment=#pyobj_as) Type &DIRECTOROUT = Type + %typemap(directorout,fragment=pyfrag) __VA_ARGS__ &DIRECTOROUT = __VA_ARGS__ %enddef /* throws */ -%define PY_THROWS_TYPEMAP(type, pyobj_from) - %typemap(throws,fragment=#pyobj_from) type { - PyErr_SetObject(PyExc_RuntimeError, pyobj_from((type)$1)); +%define PYVAL_THROWS_TYPEMAP(pyobj_from,pyfrag,...) + %typemap(throws,fragment=pyfrag) __VA_ARGS__ { + PyErr_SetObject(PyExc_RuntimeError, pyobj_from((__VA_ARGS__)$1)); SWIG_fail; } %enddef /* typecheck */ -%define PY_TYPECHECK_TYPEMAP(check, type, pyobj_check) -%typemap(typecheck,precedence=SWIG_TYPECHECK_##check, - fragment=#pyobj_check) type, const type& +%define PYVAL_TYPECHECK_TYPEMAP(check,pyobj_check,pyfrag,...) +%typemap(typecheck,precedence=check,fragment=pyfrag) + __VA_ARGS__, const __VA_ARGS__& "$1 = pyobj_check($input);"; %enddef /* - typemap definition for types with As/From/Check methods - */ + typemap definition for types with As/Check methods +*/ +%define %typemap_ascheck(CheckCode, AsMeth, CheckMeth, + AsFrag, CheckFrag, ...) + PYVAL_IN_TYPEMAP(SWIG_arg(AsMeth), SWIG_arg(AsFrag), __VA_ARGS__); + PYVAL_VARIN_TYPEMAP(SWIG_arg(AsMeth), SWIG_arg(AsFrag), __VA_ARGS__); + PYVAL_DIRECTOROUT_TYPEMAP(SWIG_arg(AsMeth), SWIG_arg(AsFrag), __VA_ARGS__); + PYVAL_TYPECHECK_TYPEMAP(SWIG_arg(CheckCode), SWIG_arg(CheckMeth), + SWIG_arg(CheckFrag), __VA_ARGS__); +%enddef -%define %typemap_asfromcheck(Type, CheckCode, AsType, FromType, CheckType) - PY_IN_TYPEMAP(Type, AsType); - PY_OUT_TYPEMAP(Type, FromType); - PY_VARIN_TYPEMAP(Type, AsType); - PY_VAROUT_TYPEMAP(Type, FromType); - PY_CONSTCODE_TYPEMAP(Type, FromType); - PY_DIRECTORIN_TYPEMAP(Type, FromType); - PY_DIRECTOROUT_TYPEMAP(Type, AsType); - PY_THROWS_TYPEMAP(Type, FromType); - PY_TYPECHECK_TYPEMAP(CheckCode, Type, CheckType); + +/* + typemap definition for types with AsVal method +*/ +%define %typemap_asvaln(CheckCode, ...) +%fragment(SWIG_As_frag(__VA_ARGS__),"header", + fragment=SWIG_AsVal_frag(__VA_ARGS__)) %{ +SWIGSTATICINLINE(__VA_ARGS__) +SWIG_As_meth(__VA_ARGS__)(PyObject* obj) +{ + __VA_ARGS__ v; + SWIG_AsVal_meth(__VA_ARGS__)(obj, &v); + return v; +} +%} +%fragment(SWIG_Check_frag(__VA_ARGS__),"header", + fragment=SWIG_AsVal_frag(__VA_ARGS__)) %{ +SWIGSTATICINLINE(int) +SWIG_Check_meth(__VA_ARGS__)(PyObject* obj) +{ + return SWIG_AsVal_meth(__VA_ARGS__)(obj, (__VA_ARGS__*)0); +} +%} +%typemap_ascheck(SWIG_arg(CheckCode), + SWIG_As_meth(__VA_ARGS__), + SWIG_Check_meth(__VA_ARGS__), + SWIG_arg(SWIG_As_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Check_frag(__VA_ARGS__)), + __VA_ARGS__); %enddef /* - typemap for simple swig types with only As/From conversor methods - named as SWIG_As##Name/SWIG_From##Name. + typemap definition for types with from method */ -%define %typemap_stype(Type, CheckCode, Name) -%fragment("SWIG_Check"#Name,"header", - fragment="SWIG_As"#Name) %{ -SWIGSTATICINLINE(int) -SWIG_Check##Name(PyObject* obj) -{ - SWIG_As##Name(obj); - if (PyErr_Occurred()) { - PyErr_Clear(); - return 0; - } else { - return 1; - } -} -%} -%typemap_asfromcheck(Type, CheckCode, SWIG_As##Name, - SWIG_From##Name, SWIG_Check##Name) +%define %typemap_from(FromMeth, FromFrag, ...) + PYVAL_OUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYVAL_VAROUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYVAL_CONSTCODE_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYVAL_DIRECTORIN_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + PYVAL_THROWS_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag),__VA_ARGS__); +%enddef + + +%define %typemap_ascheckfrom(CheckCode, AsMeth, CheckMeth, FromMeth, + AsFrag, CheckFrag, FromFrag, ...) + %typemap_ascheck(SWIG_arg(CheckCode), SWIG_arg(AsMeth), SWIG_arg(CheckMeth), + SWIG_arg(AsFrag), SWIG_arg(CheckFrag), __VA_ARGS__); + %typemap_from(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); +%enddef + + + +/* + typemap definition for types with asval/from method +*/ +%define %typemap_asvalfromn(CheckCode, ...) + %typemap_asvaln(SWIG_arg(CheckCode), __VA_ARGS__); + %typemap_from(SWIG_arg(SWIG_From_meth(__VA_ARGS__)), + SWIG_arg(SWIG_From_frag(__VA_ARGS__)), + __VA_ARGS__); +%enddef + + +/* + typemap definition for types with as/check/from method +*/ +%define %typemap_ascheckfromn(CheckCode, ...) + %typemap_ascheckfrom(SWIG_arg(CheckCode), + SWIG_As_meth(__VA_ARGS__), + SWIG_From_meth(__VA_ARGS__), + SWIG_Check_meth(__VA_ARGS__), + SWIG_arg(SWIG_As_frag(__VA_ARGS__)), + SWIG_arg(SWIG_From_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Check_frag(__VA_ARGS__)), + __VA_ARGS__); %enddef diff --git a/Lib/python/std_common.i b/Lib/python/std_common.i index d0a002bff..089aac3f7 100644 --- a/Lib/python/std_common.i +++ b/Lib/python/std_common.i @@ -1,30 +1,347 @@ // -// SWIG typemaps for STL - common utilities -// Luigi Ballabio -// Aug 3, 2002 -// // Python implementation -%apply size_t { std::size_t }; - +%include pyptrtypes.swg %{ #include +#include +%} + + +%apply size_t { std::size_t }; +%apply ptrdiff_t { std::ptrdiff_t } + +%fragment("PyObject_var","header") +%{ + namespace swigpy + { + struct PyObject_var + { + PyObject* ptr; + PyObject_var(PyObject* obj = 0) + : ptr(obj) + { + } + + ~PyObject_var() + { + if (ptr) Py_DECREF(ptr); + } + + operator PyObject*() + { + return ptr; + } + }; + } +%} + +%fragment("traits","header") +%{ +namespace swigpy { + /* + General traits that provides type_name and type_info + */ + template struct traits + { + }; + /* + type category + */ + struct pointer_category + { + }; + + struct value_category + { + }; + + + template + inline const char* type_name() { + return traits::type_name(); + } + + template + struct traits_info + { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name()); + return info; + } + }; + + template + inline swig_type_info *type_info() { + return traits_info::type_info(); + } + + /* + Traits that provides the from method + */ + template struct traits_from { + typedef Type value_type; + static PyObject *from(value_type *val, int owner = 0) { + return SWIG_NewPointerObj(val, type_info(), owner); + } + + static PyObject *from(const value_type& val) { + return traits_from::from(new value_type(val), 1); + } + }; + + template + inline PyObject *from(const Type& val) { + return traits_from::from(val); + } + + template + inline PyObject *from(Type* val, int owner = 0) { + return traits_from::from(val, owner); + } + + /* + Traits that provides the asval/as/check method + */ + + template + struct traits_asptr { + typedef Type value_type; + static int asptr(PyObject *obj, value_type **val) { + value_type *p; + int res = (SWIG_ConvertPtr(obj, (void**)&p, + type_info(), 0) != -1) ? 1 : 0; + if (val) { + if (res) { + *val = p; + } else { + PyErr_Format(PyExc_TypeError, "a '%s *' is expected", + type_name()); + } + } + return res; + } + }; + + template + inline int asptr(PyObject *obj, Type **vptr) { + return traits_asptr::asptr(obj, vptr); + } + + template + struct traits_asval + { + typedef Type value_type; + static bool asval(PyObject *obj, value_type *val) { + if (val) { + value_type *p; + int res = asptr(obj, &p); + if (res) { + *val = *p; + if (res > 1) delete p; + } + return res; + } else { + return asptr(obj, (value_type **)(0)); + } + } + }; + + template + inline bool asval(PyObject *obj, Type *val) { + return traits_asval::asval(obj, val); + } + + + template + struct traits_as + { + }; + + template + struct traits_as + { + typedef Type value_type; + static value_type as(PyObject *obj) { + value_type v; + if (!asval(obj, &v)) { + std::string msg= "a value of type '"; + msg += swigpy::type_name(); + msg += "' is expected"; + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, msg.c_str()); + } + throw std::invalid_argument(msg); + } + return v; + } + }; + + template + struct traits_as + { + typedef Type value_type; + static value_type as(PyObject *obj) { + value_type *v = 0; + int res = asptr(obj, &v); + if (res) { + if (res > 1) { + value_type r(*v); + delete v; + return r; + } else { + return *v; + } + } else { + std::string msg= "a value of type '"; + msg += swigpy::type_name(); + msg += "' is expected"; + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, msg.c_str()); + } + throw std::invalid_argument(msg); + } + } + }; + + template + inline Type as(PyObject *obj) { + return traits_as::category>::as(obj); + } + + template + struct traits_check + { + }; + + template + struct traits_check + { + typedef Type value_type; + static bool check(PyObject *obj) { + return asval(obj, (value_type *)(0)); + } + }; + + template + struct traits_check + { + typedef Type value_type; + static bool check(PyObject *obj) { + return asptr(obj, (value_type **)(0)); + } + }; + + template + inline bool check(PyObject *obj) { + return traits_check::category>::check(obj); + } + + /* + Partial specialization for pointers + */ + template struct traits { + typedef pointer_category category; + + static std::string make_ptr_name(const char* name) + { + std::string ptrname = name; + ptrname += " *"; + return ptrname; + } + + static const char* type_name() + { + static std::string name = make_ptr_name(swigpy::type_name()); + return name.c_str(); + } + }; -PyObject* SwigInt_FromBool(bool b) { - return PyInt_FromLong(b ? 1L : 0L); -} -int SwigNumber_Check(PyObject* o) { - return PyFloat_Check(o) || PyInt_Check(o) || PyLong_Check(o); -} -double SwigNumber_AsDouble(PyObject* o) { - return PyFloat_Check(o) ? PyFloat_AsDouble(o) - : (PyInt_Check(o) ? double(PyInt_AsLong(o)) - : double(PyLong_AsLong(o))); -} -PyObject* SwigString_FromString(const std::string& s) { - return PyString_FromStringAndSize(s.data(),s.size()); -} -std::string SwigString_AsString(PyObject* o) { - return std::string(PyString_AsString(o)); } %} + +/* + Generate the traits for a swigtype +*/ + +%define %traits_swigtype(...) +%fragment(SWIG_Traits_frag(__VA_ARGS__),"header",fragment="traits") { + namespace swigpy { + template <> struct traits<__VA_ARGS__ > { + typedef pointer_category category; + static const char* type_name() { return #__VA_ARGS__; } + }; + } +} +%enddef + +/* + Generate the traits for a 'primitive' type, such as 'double', + for which the SWIG_AsVal and SWIG_From method are already defined. +*/ + +%define %traits_ptypen(...) + %fragment(SWIG_Traits_frag(__VA_ARGS__),"header", + fragment=SWIG_AsVal_frag(__VA_ARGS__), + fragment=SWIG_From_frag(__VA_ARGS__), + fragment="traits") { + namespace swigpy { + template <> struct traits<__VA_ARGS__ > { + typedef value_category category; + static const char* type_name() { return #__VA_ARGS__; } + }; + + template <> struct traits_asval<__VA_ARGS__ > { + typedef __VA_ARGS__ value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal_meth(__VA_ARGS__)(obj, val); + } + }; + + template <> struct traits_from<__VA_ARGS__ > { + typedef __VA_ARGS__ value_type; + static PyObject *from(const value_type& val) { + return SWIG_From_meth(__VA_ARGS__)(val); + } + }; + } + } +%enddef + +%apply_cpptypes(%traits_ptypen); + +/* + Generate the typemaps for a class which the traits are + already defined +*/ + +%define %typemap_traits(Code,...) + %typemap_ascheckfrom(SWIG_arg(Code), + SWIG_arg(swigpy::as<__VA_ARGS__ >), + SWIG_arg(swigpy::check<__VA_ARGS__ >), + SWIG_arg(swigpy::from), + SWIG_arg(SWIG_Traits_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Traits_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Traits_frag(__VA_ARGS__)), + __VA_ARGS__); +%enddef + +/* + Generate the typemaps for a class that behaves more like + a ptr or plain wrapped Swigtype. +*/ + +%define %typemap_traits_ptr(Code,...) + %typemap_asptrfrom(SWIG_arg(Code), + SWIG_arg(swigpy::asptr), + SWIG_arg(swigpy::from), + SWIG_arg(SWIG_Traits_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Traits_frag(__VA_ARGS__)), + __VA_ARGS__); +%enddef + diff --git a/Lib/python/std_complex.i b/Lib/python/std_complex.i index 4ca975fd8..0a85b67a0 100644 --- a/Lib/python/std_complex.i +++ b/Lib/python/std_complex.i @@ -3,23 +3,21 @@ %include "complex_common.i" - %{ #include %} /* defining the complex as/from converters */ -%swig_cplxdbl_conv(std::complex, StdCplxDbl, - std::complex, std::real, std::imag) +%swig_cplxdbl_convn(std::complex, + std::complex, std::real, std::imag) -%swig_cplxflt_conv(std::complex, StdCplxFlt, - std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, + std::complex, std::real, std::imag) -/* declaring the typemaps */ -%typemap_stype(std::complex, CPLXDBL, StdCplxDbl); -%typemap_stype(std::complex, CPLXFLT, StdCplxFlt); +%typemap_primitive(SWIG_CCode(CPLXDBL), std::complex); +%typemap_primitive(SWIG_CCode(CPLXFLT), std::complex); #endif //SWIG_STD_COMPLEX_I_ diff --git a/Lib/python/std_container.i b/Lib/python/std_container.i new file mode 100644 index 000000000..11fceb353 --- /dev/null +++ b/Lib/python/std_container.i @@ -0,0 +1,210 @@ +%include std_common.i +%include pycontainer.i +%include exception.i + +%{ +#include +%} + +// Common container methods + +%define %std_container_methods(container) + container(); + container(const container&); + + bool empty() const; + size_type size() const; + void clear(); + + + %extend { + bool operator == (const container& v) { + return *self == v; + } + + bool operator != (const container& v) { + return *self != v; + } + } + + void swap(container& v); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; + #endif + +%enddef + +// Common sequence + +%define %std_sequence_methods_common(sequence) + + %std_container_methods(SWIG_arg(sequence)); + + sequence(size_type size); + void pop_back(); + + void resize(size_type new_size); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator pos); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + #endif + +%enddef + + +%define %std_sequence_methods(sequence) + + %std_sequence_methods_common(SWIG_arg(sequence)); + + sequence(size_type size, const value_type& value); + void push_back(const value_type& x); + + value_type& front(); + value_type& back(); + + const value_type& front() const; + const value_type& back() const; + + void assign(size_type n, const value_type& x); + + void resize(size_type new_size, const value_type& x); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator pos, const value_type& x); + void insert(iterator pos, size_type n, const value_type& x); + #endif + +%enddef + +%define %std_sequence_methods_val(sequence) + + %std_sequence_methods_common(SWIG_arg(sequence)); + + sequence(size_type size, value_type value); + void push_back(value_type x); + + value_type front() const; + value_type back() const; + + void assign(size_type n, value_type x); + + void resize(size_type new_size, value_type x); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator pos, value_type x); + void insert(iterator pos, size_type n, value_type x); + #endif + +%enddef + +// +// Common fragments +// + +%fragment("StdSequenceTraits","header", + fragment="traits",fragment="PyObject_var", + fragment="PySequence_Cont") +%{ + namespace swigpy { + template + void assign(const PySeq& pyseq, Seq* seq) { + seq->assign(pyseq.begin(), pyseq.end()); + } + + template + struct traits_asptr_stdseq { + typedef Seq sequence; + typedef T value_type; + + static int asptr(PyObject *obj, sequence **seq) { + if (PySequence_Check(obj)) { + try { + PySequence_Cont pyseq(obj); + if (seq) { + sequence *pseq = new sequence(); + assign(pyseq, pseq); + *seq = pseq; + return 2; + } else { + return pyseq.check(); + } + } catch (std::exception& e) { + if (seq) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, e.what()); + } + return 0; + } + } else { + sequence *p; + if (SWIG_ConvertPtr(obj,(void**)&p, + swigpy::type_info(),0) != -1) { + if (seq) *seq = p; + return 1; + } + } + if (seq) { + PyErr_Format(PyExc_TypeError, "a %s is expected", + swigpy::type_name()); + } + return 0; + } + }; + + template + struct traits_from_stdseq { + typedef Seq sequence; + typedef T value_type; + typedef typename Seq::size_type size_type; + typedef typename sequence::const_iterator const_iterator; + + static PyObject *from(const sequence& seq) { + size_type size = seq.size(); + if (size <= (size_type)INT_MAX) { + PyObject *obj = PyTuple_New((int)size); + int i = 0; + for (const_iterator it = seq.begin(); + it != seq.end(); ++it, ++i) { + PyTuple_SetItem(obj,i,swigpy::from(*it)); + } + return obj; + } else { + PyErr_SetString(PyExc_OverflowError, + "sequence size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + } + }; + } +%} + +%define %std_comp_methods(...) +%extend __VA_ARGS__ { + bool operator > (const __VA_ARGS__& v) { + return *self > v; + } + + bool operator < (const __VA_ARGS__& v) { + return *self < v; + } + + bool operator >= (const __VA_ARGS__& v) { + return *self >= v; + } + + bool operator <= (const __VA_ARGS__& v) { + return *self <= v; + } +} +%enddef diff --git a/Lib/python/std_deque.i b/Lib/python/std_deque.i index 499549cbf..7c7e212ac 100644 --- a/Lib/python/std_deque.i +++ b/Lib/python/std_deque.i @@ -1,23 +1,152 @@ -/* Default std_deque wrapper */ -%module std_deque +// +// std::deque +// Python implementation -%rename(__getitem__) std::deque::getitem; -%rename(__setitem__) std::deque::setitem; -%rename(__delitem__) std::deque::delitem; -%rename(__getslice__) std::deque::getslice; -%rename(__setslice__) std::deque::setslice; -%rename(__delslice__) std::deque::delslice; +%include std_container.i -%extend std::deque { - int __len__() { - return (int) self->size(); - } - int __nonzero__() { - return ! self->empty(); - } - void append(const T &x) { - self->push_back(x); - } -}; +// Deque + +%define %std_deque_methods(deque) + %std_sequence_methods(deque) + + void pop_front(); + void push_front(const value_type& x); +%enddef + +%define %std_deque_methods_val(deque) + %std_sequence_methods_val(deque) + + void pop_front(); + void push_front(value_type x); +%enddef + +// ------------------------------------------------------------------------ +// std::deque +// +// The aim of all that follows would be to integrate std::deque 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::deque), f(const std::deque&): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::deque can be passed. +// -- f(std::deque&), f(std::deque*): +// the parameter may be modified; therefore, only a wrapped std::deque +// can be passed. +// -- std::deque f(), const std::deque& f(): +// the deque is returned by copy; therefore, a Python sequence of T:s +// is returned which is most easily used in other Python functions +// -- std::deque& f(), std::deque* f(): +// the deque is returned by reference; therefore, a wrapped std::deque +// is returned +// -- const std::deque* f(), f(const std::deque*): +// for consistency, they expect and return a plain deque pointer. +// ------------------------------------------------------------------------ + +%{ +#include +%} + +%fragment("StdDequeTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + struct traits_asptr > { + typedef std::deque deque_type; + typedef T value_type; + static int asptr(PyObject *obj, deque_type **vec) { + return traits_asptr_stdseq::asptr(obj, vec); + } + }; + + template + struct traits_from > { + typedef std::deque deque_type; + static PyObject *from(const deque_type& vec) { + return traits_from_stdseq::from(vec); + } + }; + } +%} + +// exported classes + +namespace std { + + template class deque { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::deque), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdDequeTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::deque<" #T " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(DEQUE), std::deque); + + %std_deque_methods(std::deque); + %pysequence_methods(std::deque); + }; + + template class deque { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; + + %fragment(SWIG_Traits_frag(std::deque), "header", + fragment="StdDequeTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::deque<" #T " * >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(DEQUE), std::deque); + + %std_deque_methods_val(std::deque); + %pysequence_methods_val(std::deque); + }; + + // Add the order operations <,>,<=,=> as needed + + %define %std_order_deque(T) + %std_comp_methods(deque); + %enddef + + %apply_otypes(%std_order_deque); +} + + +%define %std_deque_ptypen(...) +%template() std::deque<__VA_ARGS__ >; +%enddef + +%apply_cpptypes(%std_deque_ptypen); -%include "_std_deque.i" diff --git a/Lib/python/std_list.i b/Lib/python/std_list.i index 83b956c88..68b457c6e 100644 --- a/Lib/python/std_list.i +++ b/Lib/python/std_list.i @@ -1,245 +1,167 @@ // -// SWIG typemaps for std::list types -// Jing Cao -// Aug 1st, 2002 -// +// std::list // Python implementation +%include std_container.i + +// List + +%define %std_list_methods(list) + %std_sequence_methods(list) + + void pop_front(); + void push_front(const value_type& x); + + void remove(const value_type& x); + void unique(); + void reverse(); + void sort(); + + void merge(list& x); +%enddef + + +%define %std_list_methods_val(list) + %std_sequence_methods_val(list) + + void pop_front(); + void push_front(value_type x); + + void remove(value_type x); + void unique(); + void reverse(); + void sort(); + + void merge(list& x); +%enddef + +// ------------------------------------------------------------------------ +// std::list +// +// The aim of all that follows would be to integrate std::list 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::list), f(const std::list&): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::list can be passed. +// -- f(std::list&), f(std::list*): +// the parameter may be modified; therefore, only a wrapped std::list +// can be passed. +// -- std::list f(), const std::list& f(): +// the list is returned by copy; therefore, a Python sequence of T:s +// is returned which is most easily used in other Python functions +// -- std::list& f(), std::list* f(): +// the list is returned by reference; therefore, a wrapped std::list +// is returned +// -- const std::list* f(), f(const std::list*): +// for consistency, they expect and return a plain list pointer. +// ------------------------------------------------------------------------ -%module std_list %{ #include -#include %} -%include "exception.i" +%fragment("StdListTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + struct traits_asptr > { + typedef std::list list_type; + typedef T value_type; + static int asptr(PyObject *obj, list_type **lis) { + return traits_asptr_stdseq::asptr(obj, lis); + } + }; -%exception std::list::__getitem__ { - try { - $action - } catch (std::out_of_range& e) { - SWIG_exception(SWIG_IndexError,const_cast(e.what())); - } -} + template + struct traits_from > { + typedef std::list list_type; + static PyObject *from(const list_type& vec) { + return traits_from_stdseq::from(vec); + } + }; + } +%} -%exception std::list::__setitem__ { - try { - $action - } catch (std::out_of_range& e) { - SWIG_exception(SWIG_IndexError,const_cast(e.what())); - } -} +// exported classes -%exception std::list::__delitem__ { - try { - $action - } catch (std::out_of_range& e) { - SWIG_exception(SWIG_IndexError,const_cast(e.what())); - } -} +namespace std { + template class list { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; -namespace std{ - template class list - { - public: - - typedef T &reference; - typedef const T& const_reference; - typedef T &iterator; - typedef const T& const_iterator; - - list(); - list(unsigned int size, const T& value = T()); - list(const list &); + %traits_swigtype(T); - ~list(); - void assign(unsigned int n, const T& value); - void swap(list &x); - - const_reference front(); - const_reference back(); - const_iterator begin(); - const_iterator end(); - - void resize(unsigned int n, T c = T()); - bool empty() const; - - void push_front(const T& x); - void push_back(const T& x); - - - void pop_front(); - void pop_back(); - void clear(); - unsigned int size() const; - unsigned int max_size() const; - void resize(unsigned int n, const T& value); - - void remove(const T& value); - void unique(); - void reverse(); - void sort(); - - - - %extend - { - const_reference __getitem__(int i) - { - std::list::iterator first = self->begin(); - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && i::iterator first = self->begin(); - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && i::iterator first = self->begin(); - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && ierase(first); - } - else throw std::out_of_range("list index out of range"); - } - std::list __getslice__(int i,int j) - { - std::list::iterator first = self->begin(); - std::list::iterator end = self->end(); - - int size = int(self->size()); - if (i<0) i += size; - if (j<0) j += size; - if (i<0) i = 0; - if (j>size) j = size; - if (i>=j) i=j; - if (i>=0 && i=0) - { - for (int k=0;k tmp(j-i); - if (j>i) std::copy(first,end,tmp.begin()); - return tmp; - } - else throw std::out_of_range("list index out of range"); - } - void __delslice__(int i,int j) - { - std::list::iterator first = self->begin(); - std::list::iterator end = self->end(); - - int size = int(self->size()); - if (i<0) i += size; - if (j<0) j += size; - if (i<0) i = 0; - if (j>size) j = size; - - for (int k=0;kerase(first,end); - } - void __setslice__(int i,int j, const std::list& v) - { - std::list::iterator first = self->begin(); - std::list::iterator end = self->end(); - - int size = int(self->size()); - if (i<0) i += size; - if (j<0) j += size; - if (i<0) i = 0; - if (j>size) j = size; - - for (int k=0;kerase(first,end); - if (i+1 <= int(self->size())) - { - first = self->begin(); - for (int k=0;kinsert(first,v.begin(),v.end()); - } - else self->insert(self->end(),v.begin(),v.end()); - } - - } - unsigned int __len__() - { - return self->size(); - } - bool __nonzero__() - { - return !(self->empty()); - } - void append(const T& x) - { - self->push_back(x); - } - void pop() - { - self->pop_back(); - } - - }; - + %fragment(SWIG_Traits_frag(std::list), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdListTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::list<" #T " >"; + } }; + } + } + + %typemap_traits_ptr(SWIG_CCode(LIST), std::list); + + %std_list_methods(std::list); + %pysequence_methods(std::list); + }; + + template class list { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; + + %fragment(SWIG_Traits_frag(std::list), "header", + fragment="StdListTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::list<" #T " * >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(LIST), std::list); + + %std_list_methods_val(std::list); + %pysequence_methods_val(std::list); + }; + + // Add the order operations <,>,<=,=> as needed + + %define %std_order_list(T) + %std_comp_methods(list); + %enddef + + %apply_otypes(%std_order_list); } +%define %std_list_ptypen(...) +%template() std::list<__VA_ARGS__ >; +%enddef - - +%apply_cpptypes(%std_list_ptypen); diff --git a/Lib/python/std_map.i b/Lib/python/std_map.i index d3c643427..006a929a7 100644 --- a/Lib/python/std_map.i +++ b/Lib/python/std_map.i @@ -1,63 +1,71 @@ // -// SWIG typemaps for std::map -// Luigi Ballabio -// Jan. 2003 -// +// std::map // Python implementation -%include std_common.i -%include exception.i +%include std_pair.i +%include std_container.i -%exception std::map::__getitem__ { - try { - $action - } catch (std::out_of_range& e) { - PyErr_SetString(PyExc_KeyError,const_cast(e.what())); - SWIG_fail; - } -} +%define %std_map_methods_common(map) + %std_container_methods(SWIG_arg(map)); -%exception std::map::__delitem__ { - try { - $action - } catch (std::out_of_range& e) { - PyErr_SetString(PyExc_KeyError,const_cast(e.what())); - SWIG_fail; - } -} + size_type erase(const key_type& x); + size_type count(const key_type& x) const; -%exception std::map::__iter__ { - try { - $action - } catch (std::runtime_error& e) { - PyErr_SetString(PyExc_RuntimeError,const_cast(e.what())); - SWIG_fail; - } -} + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator position, const value_type& x); + void erase(iterator position); + void erase(iterator first, iterator last); + iterator find(const key_type& x); + const_iterator find(const key_type& x) const; + iterator lower_bound(const key_type& x); + const_iterator lower_bound(const key_type& x) const; + iterator upper_bound(const key_type& x); + const_iterator upper_bound(const key_type& x) const; + #endif +%enddef + +%define %std_map_methods(...) + %std_map_methods_common(SWIG_arg(__VA_ARGS__)); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(const value_type& x); + #endif +%enddef + +%define %std_multimap_methods(...) + %std_map_methods_common(SWIG_arg(__VA_ARGS__)); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + pair insert(const value_type& x); + pair equal_range(const key_type& x); + pair equal_range(const key_type& x) const; + #endif +%enddef // ------------------------------------------------------------------------ // std::map -// -// The aim of all that follows would be to integrate std::map with -// Python as much as possible, namely, to allow the user to pass and -// be returned Python dictionaries. +// +// The aim of all that follows would be to integrate std::map with +// Python as much as possible, namely, to allow the user to pass and +// be returned Python tuples or maps. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: -// -// -- f(std::map), f(const std::map&), f(const std::map*): -// the parameter being read-only, either a Python dictionary or a +// +// -- f(std::map), f(const std::map&): +// the parameter being read-only, either a Python sequence or a // previously wrapped std::map can be passed. // -- f(std::map&), f(std::map*): -// the parameter must be modified; therefore, only a wrapped std::map +// the parameter may be modified; therefore, only a wrapped std::map // can be passed. -// -- std::map f(): -// the map is returned by copy; therefore, a Python dictionary +// -- std::map f(), const std::map& f(): +// the map is returned by copy; therefore, a Python sequence of T:s // is returned which is most easily used in other Python functions -// -- std::map& f(), std::map* f(), const std::map& f(), -// const std::map* f(): +// -- std::map& f(), std::map* f(): // the map is returned by reference; therefore, a wrapped std::map // is returned +// -- const std::map* f(), f(const std::map*): +// for consistency, they expect and return a plain map pointer. // ------------------------------------------------------------------------ %{ @@ -68,1480 +76,147 @@ // exported class +%fragment("StdMapTraits","header",fragment="StdSequenceTraits") +{ + namespace swigpy { + template + void assign(const PySeq& pyseq, std::map *map) { + typename PySeq::const_iterator it = pyseq.begin(); + for (;it != pyseq.end(); ++ it) { + (*map)[it->first] = it->second; + } + } + + template + struct traits_asptr > { + typedef std::map map_type; + typedef K key_type; + typedef T value_type; + + static int asptr(PyObject *obj, map_type **val) { + if (PyDict_Check(obj)) { + PyObject_var items = PyMapping_Items(obj); + return traits_asptr_stdseq, std::pair > + ::asptr(items, val); + } + if (val) { + PyErr_SetString(PyExc_TypeError, "a dictionary is expected"); + } + return 0; + } + }; + + template + struct traits_from > { + typedef std::map map_type; + typedef typename map_type::const_iterator const_iterator; + typedef typename map_type::size_type size_type; + + static PyObject *from(const map_type& map) { + size_type size = map.size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "map size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + PyObject *obj = PyDict_New(); + for (const_iterator i= map.begin(); i!= map.end(); ++i) { + PyDict_SetItem(obj, + swigpy::from(i->first), + swigpy::from(i->second)); + } + return obj; + } + }; + } +} + namespace std { - template class map { - %typemap(in) map (std::map* m) { - if (PyDict_Check($input)) { - $1 = std::map(); - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) { - $1 = *m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(in) const map& (std::map temp, - std::map* m), - const map* (std::map temp, - std::map* m) { - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - temp = std::map(); - $1 = &temp; - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) { - $1 = m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(out) map { - $result = PyDict_New(); - for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { - K* key = new K(i->first); - T* obj = new T(i->second); - PyDict_SetItem($result, - SWIG_NewPointerObj((void *) key, - $descriptor(K *), 1), - SWIG_NewPointerObj((void *) obj, - $descriptor(T *), 1)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - T* x; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map&, - const map* { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - T* x; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - map(); - map(const map &); - - %rename(__len__) size; - unsigned int size() const; - void clear(); - %extend { - bool __nonzero__() { - return !(self->empty()); - } - T& __getitem__(const K& key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(const K& key, const T& x) { - (*self)[key] = x; - } - void __delitem__(const K& key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* keys() { - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - PyList_SetItem(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - return keyList; - } - PyObject* values() { - PyObject* valueList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - T* ptr = new T(i->second); - PyList_SetItem(valueList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(T *),1)); - } - return valueList; - } - PyObject* items() { - PyObject* itemList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* k_ptr = new K(i->first); - T* t_ptr = new T(i->second); - PyObject* item = PyTuple_New(2); - PyTuple_SetItem(item,0, - SWIG_NewPointerObj((void *) k_ptr, - $descriptor(K *),1)); - PyTuple_SetItem(item,1, - SWIG_NewPointerObj((void *) t_ptr, - $descriptor(T *),1)); - PyList_SetItem(itemList,j,item); - } - return itemList; - } - // Python 2.2 methods - bool __contains__(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* __iter__() { - %#if PY_VERSION_HEX >= 0x02020000 - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - PyList_SetItem(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - PyObject* iter = PyObject_GetIter(keyList); - Py_DECREF(keyList); - return iter; - %#else - throw std::runtime_error("Python 2.2 or later is needed" - " for iterator support"); - %#endif - } - } - }; + template class map { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; - // specializations for built-ins + %traits_swigtype(K); + %traits_swigtype(T); - %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) - template class map { - %typemap(in) map (std::map* m) { - if (PyDict_Check($input)) { - $1 = std::map(); - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) { - $1 = *m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(in) const map& (std::map temp, - std::map* m), - const map* (std::map temp, - std::map* m) { - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - temp = std::map(); - $1 = &temp; - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) { - $1 = m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(out) map { - $result = PyDict_New(); - for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { - T* obj = new T(i->second); - PyDict_SetItem($result, - CONVERT_TO(i->first), - SWIG_NewPointerObj((void *) obj, - $descriptor(T *), 1)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (CHECK(key) && - SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map&, - const map* { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (CHECK(key) && - SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - map(); - map(const map &); - - %rename(__len__) size; - unsigned int size() const; - void clear(); - %extend { - bool __nonzero__() { - return !(self->empty()); - } - T& __getitem__(K key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(K key, const T& x) { - (*self)[key] = x; - } - void __delitem__(K key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* keys() { - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(keyList,j, - CONVERT_TO(i->first)); - } - return keyList; - } - PyObject* values() { - PyObject* valueList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - T* ptr = new T(i->second); - PyList_SetItem(valueList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(T *),1)); - } - return valueList; - } - PyObject* items() { - PyObject* itemList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - T* t_ptr = new T(i->second); - PyObject* item = PyTuple_New(2); - PyTuple_SetItem(item,0, - CONVERT_TO(i->first)); - PyTuple_SetItem(item,1, - SWIG_NewPointerObj((void *) t_ptr, - $descriptor(T *),1)); - PyList_SetItem(itemList,j,item); - } - return itemList; - } - // Python 2.2 methods - bool __contains__(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* __iter__() { - %#if PY_VERSION_HEX >= 0x02020000 - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(keyList,j, - CONVERT_TO(i->first)); - } - PyObject* iter = PyObject_GetIter(keyList); - Py_DECREF(keyList); - return iter; - %#else - throw std::runtime_error("Python 2.2 or later is needed" - " for iterator support"); - %#endif - } - } - }; - %enddef + %fragment(SWIG_Traits_frag(std::map), "header", + fragment=SWIG_Traits_frag(std::pair), + fragment="StdMapTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::map<" #K "," #T " >"; + } + }; + } + } - %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) - template class map { - %typemap(in) map (std::map* m) { - if (PyDict_Check($input)) { - $1 = std::map(); - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) { - $1 = *m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(in) const map& (std::map temp, - std::map* m), - const map* (std::map temp, - std::map* m) { - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - temp = std::map(); - $1 = &temp; - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) { - $1 = m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(out) map { - $result = PyDict_New(); - for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { - K* key = new K(i->first); - PyDict_SetItem($result, - SWIG_NewPointerObj((void *) key, - $descriptor(K *), 1), - CONVERT_TO(i->second)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - CHECK(o)) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map&, - const map* { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - CHECK(o)) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - map(); - map(const map &); - - %rename(__len__) size; - unsigned int size() const; - void clear(); - %extend { - bool __nonzero__() { - return !(self->empty()); - } - T __getitem__(const K& key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(const K& key, T x) { - (*self)[key] = x; - } - void __delitem__(const K& key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* keys() { - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - PyList_SetItem(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - return keyList; - } - PyObject* values() { - PyObject* valueList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(valueList,j, - CONVERT_TO(i->second)); - } - return valueList; - } - PyObject* items() { - PyObject* itemList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* k_ptr = new K(i->first); - PyObject* item = PyTuple_New(2); - PyTuple_SetItem(item,0, - SWIG_NewPointerObj((void *) k_ptr, - $descriptor(K *),1)); - PyTuple_SetItem(item,1, - CONVERT_TO(i->second)); - PyList_SetItem(itemList,j,item); - } - return itemList; - } - // Python 2.2 methods - bool __contains__(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* __iter__() { - %#if PY_VERSION_HEX >= 0x02020000 - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - PyList_SetItem(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - PyObject* iter = PyObject_GetIter(keyList); - Py_DECREF(keyList); - return iter; - %#else - throw std::runtime_error("Python 2.2 or later is needed" - " for iterator support"); - %#endif - } - } - }; - %enddef + %typemap_traits_ptr(SWIG_CCode(MAP), std::map); + + %std_map_methods(std::map); + %pydict_methods(SWIG_arg(std::map)); + }; - %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, - T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) - template<> class map { - %typemap(in) map (std::map* m) { - if (PyDict_Check($input)) { - $1 = std::map(); - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) { - $1 = *m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(in) const map& (std::map temp, - std::map* m), - const map* (std::map temp, - std::map* m) { - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - temp = std::map(); - $1 = &temp; - for (unsigned int i=0; i expected"); - SWIG_fail; - } - } - Py_DECREF(items); - } else if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) { - $1 = m; - } else { - PyErr_SetString(PyExc_TypeError, - "map<" #K "," #T "> expected"); - SWIG_fail; - } - } - %typemap(out) map { - $result = PyDict_New(); - for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { - PyDict_SetItem($result, - CONVERT_K_TO(i->first), - CONVERT_T_TO(i->second)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (CHECK_K(key) && CHECK_T(o)) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map&, - const map* { - /* native sequence? */ - if (PyDict_Check($input)) { - PyObject* items = PyMapping_Items($input); - unsigned int size = PyList_Size(items); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - PyObject* pair = PySequence_GetItem(items,0); - PyObject* key = PySequence_GetItem(pair,0); - PyObject* o = PySequence_GetItem(pair,1); - if (CHECK_K(key) && CHECK_T(o)) - $1 = 1; - else - $1 = 0; - Py_DECREF(key); - Py_DECREF(o); - Py_DECREF(pair); - } - Py_DECREF(items); - } else { - /* wrapped map? */ - std::map* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - map(); - map(const map &); - - %rename(__len__) size; - unsigned int size() const; - void clear(); - %extend { - bool __nonzero__() { - return !(self->empty()); - } - T __getitem__(K key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(K key, T x) { - (*self)[key] = x; - } - void __delitem__(K key) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* keys() { - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(keyList,j, - CONVERT_K_TO(i->first)); - } - return keyList; - } - PyObject* values() { - PyObject* valueList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(valueList,j, - CONVERT_T_TO(i->second)); - } - return valueList; - } - PyObject* items() { - PyObject* itemList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyObject* item = PyTuple_New(2); - PyTuple_SetItem(item,0, - CONVERT_K_TO(i->first)); - PyTuple_SetItem(item,1, - CONVERT_T_TO(i->second)); - PyList_SetItem(itemList,j,item); - } - return itemList; - } - // Python 2.2 methods - bool __contains__(K key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } - PyObject* __iter__() { - %#if PY_VERSION_HEX >= 0x02020000 - PyObject* keyList = PyList_New(self->size()); - std::map::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - PyList_SetItem(keyList,j, - CONVERT_K_TO(i->first)); - } - PyObject* iter = PyObject_GetIter(keyList); - Py_DECREF(keyList); - return iter; - %#else - throw std::runtime_error("Python 2.2 or later is needed" - " for iterator support"); - %#endif - } - } - }; - %enddef + template class multimap { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + typedef std::pair value_type; - specialize_std_map_on_key(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_key(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_key(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_key(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_key(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_key(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_key(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_key(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_key(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_key(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; - specialize_std_map_on_value(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_value(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_value(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_value(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_value(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_value(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_value(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_value(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_value(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_value(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); + %traits_swigtype(K); + %traits_swigtype(T); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_map_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); + %fragment(SWIG_Traits_frag(std::multimap), "header", + fragment=SWIG_Traits_frag(std::pair), + fragment="StdMapTraits") { + namespace swigpy { + + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::multimap<" #K "," #T " >"; + } + }; + } + } + %typemap_traits_ptr(SWIG_CCode(MULTIMAP), std::multimap); + + %std_multimap_methods(std::multimap); + %pydict_methods(SWIG_arg(std::multimap)); + }; } + +// map +%define std_map_ptypen(...) + %template() std::map< __VA_ARGS__ >; +%enddef + +%apply_cpptypes_2(std_map_ptypen); + +// multimap +%define std_multimap_ptypen(...) + %template() std::multimap< __VA_ARGS__ >; +%enddef + +%apply_cpptypes_2(std_multimap_ptypen); diff --git a/Lib/python/std_pair.i b/Lib/python/std_pair.i index f4ac406c9..440c507e2 100644 --- a/Lib/python/std_pair.i +++ b/Lib/python/std_pair.i @@ -1,1007 +1,162 @@ -// -// SWIG typemaps for std::pair -// Luigi Ballabio -// July 2003 -// -// Python implementation - %include std_common.i -%include exception.i - - -// ------------------------------------------------------------------------ -// std::pair -// -// See std_vector.i for the rationale of typemap application -// ------------------------------------------------------------------------ %{ #include %} -// exported class +%fragment("StdPairTraits","header", + fragment="traits",fragment="PyObject_var") { + namespace swigpy { + template + struct traits_asval > { + typedef std::pair value_type; + typedef T first_type; + typedef U second_type; + + static int asval(PyObject *obj, value_type *val) { + if (PySequence_Check(obj) && (PySequence_Size(obj) == 2)) { + swigpy::PyObject_var first = PySequence_GetItem(obj,0); + swigpy::PyObject_var second = PySequence_GetItem(obj,1); + first_type *pfirst = val ? &(val->first) : 0; + second_type *psecond = val ? &(val->second) : 0; + if (swigpy::asval(first,pfirst) && swigpy::asval(second,psecond)) { + return 1; + } + } else { + value_type *p; + if (SWIG_ConvertPtr(obj,(void**)&p, + swigpy::type_info(),0) != -1) { + if (val) *val = *p; + return 1; + } + } + if (val) { + PyErr_Format(PyExc_TypeError, "a %s is expected", + swigpy::type_name()); + } + return 0; + } + }; + + template + struct traits_from > { + typedef std::pair value_type; + static PyObject *from(const value_type& val) { + PyObject* obj = PyTuple_New(2); + PyTuple_SetItem(obj,0,swigpy::from(val.first)); + PyTuple_SetItem(obj,1,swigpy::from(val.second)); + return obj; + } + }; + } + } namespace std { + template struct pair { + typedef T fisrt_type; + typedef U second_type; + + %traits_swigtype(T); + %traits_swigtype(U); + + %fragment(SWIG_Traits_frag(std::pair), "header", + fragment=SWIG_Traits_frag(T), + fragment=SWIG_Traits_frag(U), + fragment="StdPairTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::pair<" #T "," #U " >"; + } + }; + } + } - template struct pair { - %typemap(in) pair (std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = std::make_pair(x,y); - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) { - $1 = *p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(in) const pair& (std::pair temp, - std::pair* p), - const pair* (std::pair temp, - std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - temp = std::make_pair(x,y); - $1 = &temp; - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) { - $1 = p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(out) pair { - $result = PyTuple_New(2); - T* x = new T($1.first); - U* y = new U($1.second); - PyTuple_SetItem($result,0, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 1)); - PyTuple_SetItem($result,1, - SWIG_NewPointerObj((void *) y, - $descriptor(U *), 1)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - T* x; - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair&, - const pair* { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - T* x; - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - T first; - U second; - }; + %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); + + T first; + U second; + }; + + template struct pair { + typedef T fisrt_type; + typedef U* second_type; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::pair), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdPairTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::pair<" #T "," #U " * >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); + + T first; + U* second; + }; - // specializations for built-ins + template struct pair { + typedef T* fisrt_type; + typedef U second_type; + + %traits_swigtype(U); + + %fragment(SWIG_Traits_frag(std::pair), "header", + fragment=SWIG_Traits_frag(U), + fragment="StdPairTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::pair<" #T *"," #U " >"; + } + }; + } + } - %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) - template struct pair { - %typemap(in) pair (std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = std::make_pair(CONVERT_FROM(first),y); - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) { - $1 = *p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(in) const pair& (std::pair temp, - std::pair* p), - const pair* (std::pair temp, - std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - temp = std::make_pair(CONVERT_FROM(first),y); - $1 = &temp; - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) { - $1 = p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(out) pair { - $result = PyTuple_New(2); - U* y = new U($1.second); - PyTuple_SetItem($result,0,CONVERT_TO($1.first)); - PyTuple_SetItem($result,1, - SWIG_NewPointerObj((void *) y, - $descriptor(U *), 1)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair&, - const pair* { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - U* y; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - T first; - U second; - }; - %enddef + %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); - %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) - template struct pair { - %typemap(in) pair (std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) { - $1 = std::make_pair(x,CONVERT_FROM(second)); - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) { - $1 = *p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(in) const pair& (std::pair temp, - std::pair* p), - const pair* (std::pair temp, - std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) { - temp = std::make_pair(x,CONVERT_FROM(second)); - $1 = &temp; - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) { - $1 = p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(out) pair { - $result = PyTuple_New(2); - T* x = new T($1.first); - PyTuple_SetItem($result,0, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 1)); - PyTuple_SetItem($result,1,CONVERT_TO($1.second)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - T* x; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair&, - const pair* { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - T* x; - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - T first; - U second; - }; - %enddef + T* first; + U second; + }; - %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, - U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) - template<> struct pair { - %typemap(in) pair (std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK_T(first) && CHECK_U(second)) { - $1 = std::make_pair(CONVERT_T_FROM(first), - CONVERT_U_FROM(second)); - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) { - $1 = *p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(in) const pair& (std::pair temp, - std::pair* p), - const pair* (std::pair temp, - std::pair* p) { - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK_T(first) && CHECK_U(second)) { - temp = std::make_pair(CONVERT_T_FROM(first), - CONVERT_U_FROM(second)); - $1 = &temp; - Py_DECREF(first); - Py_DECREF(second); - } else { - Py_DECREF(first); - Py_DECREF(second); - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } else if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) { - $1 = p; - } else { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - } - %typemap(out) pair { - $result = PyTuple_New(2); - PyTuple_SetItem($result,0,CONVERT_T_TO($1.first)); - PyTuple_SetItem($result,1,CONVERT_U_TO($1.second)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK_T(first) && CHECK_U(second)) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair&, - const pair* { - /* native sequence? */ - if (PyTuple_Check($input)) { - if (PyTuple_Size($input) != 2) { - /* not a pair anyway */ - $1 = 0; - } else { - PyObject* first = PySequence_GetItem($input,0); - PyObject* second = PySequence_GetItem($input,1); - if (CHECK_T(first) && CHECK_U(second)) { - $1 = 1; - } else { - $1 = 0; - } - } - } else { - /* wrapped pair? */ - std::pair* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - T first; - U second; - }; - %enddef + template struct pair { + typedef T* fisrt_type; + typedef U* second_type; + + %fragment(SWIG_Traits_frag(std::pair), "header", + fragment="StdPairTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::pair<" #T *"," #U " * >"; + } + }; + } + } - specialize_std_pair_on_first(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_first(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_first(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_first(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_first(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_first(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_first(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong, - PyLong_FromUnsignedLong); - specialize_std_pair_on_first(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_first(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_first(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); + %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); - specialize_std_pair_on_second(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_second(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_second(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_second(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_second(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_second(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_second(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong, - PyLong_FromUnsignedLong); - specialize_std_pair_on_second(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_second(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_second(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - bool,PyInt_Check, - PyInt_AsLong,SwigInt_FromBool); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - long,PyLong_Check, - PyLong_AsLong,PyLong_FromLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned int,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned short,PyInt_Check, - PyInt_AsLong,PyInt_FromLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - unsigned long,PyLong_Check, - PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - double,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - float,SwigNumber_Check, - SwigNumber_AsDouble,PyFloat_FromDouble); - specialize_std_pair_on_both(std::string,PyString_Check, - SwigString_AsString,SwigString_FromString, - std::string,PyString_Check, - SwigString_AsString,SwigString_FromString); + T* first; + U* second; + }; } + +/* + Pairs for all the C++ types +*/ +#define std_pair_ptypen(...) %template() std::pair< __VA_ARGS__ >; + +%apply_cpptypes_2(std_pair_ptypen); diff --git a/Lib/python/std_set.i b/Lib/python/std_set.i new file mode 100644 index 000000000..e96ebf1bb --- /dev/null +++ b/Lib/python/std_set.i @@ -0,0 +1,228 @@ +// +// std::set +// Python implementation + +%include std_container.i + +// Set + +%define %std_set_methods_common(set) + %std_container_methods(set); + + size_type erase(const key_type& x); + size_type count(const key_type& x) const; + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator pos, const value_type& x); + void insert(iterator pos, size_type n, const value_type& x); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + + iterator find(const key_type& x) const; + iterator lower_bound(const key_type& x) const; + iterator upper_bound(const key_type& x) const; + std::pair equal_range(const key_type& x); + iterator begin() const; + iterator end() const; + #endif +%enddef + +%define %std_set_methods(set) + %std_set_methods_common(set); + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator insert(iterator pos); + #endif +%enddef + +%define %std_multiset_methods(multiset) + %std_set_methods_common(multiset); + #ifdef SWIG_EXPORT_ITERATOR_METHODS + pair insert(iterator pos); + #endif +%enddef + + +// ------------------------------------------------------------------------ +// std::set +// +// The aim of all that follows would be to integrate std::set with +// Python as much as possible, namely, to allow the user to pass and +// be returned Python tuples or sets. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::set), f(const std::set&): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::set can be passed. +// -- f(std::set&), f(std::set*): +// the parameter may be modified; therefore, only a wrapped std::set +// can be passed. +// -- std::set f(), const std::set& f(): +// the set is returned by copy; therefore, a Python sequence of T:s +// is returned which is most easily used in other Python functions +// -- std::set& f(), std::set* f(): +// the set is returned by reference; therefore, a wrapped std::set +// is returned +// -- const std::set* f(), f(const std::set*): +// for consistency, they expect and return a plain set pointer. +// ------------------------------------------------------------------------ + +%{ +#include +%} + +%fragment("StdSetTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + void assign(const PySeq& pyseq, std::set* seq) { + seq->insert(pyseq.begin(), pyseq.end()); + } + + template + struct traits_asptr > { + typedef std::set set_type; + static int asptr(PyObject *obj, set_type **s) { + return traits_asptr_stdseq >::asptr(obj, s); + } + }; + + template + struct traits_from > { + static PyObject *from(const std::set& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + +%fragment("StdMultisetTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + void assign(const PySeq& pyseq, std::multiset* seq) { + seq->insert(pyseq.begin(), pyseq.end()); + } + + template + struct traits_asptr > { + typedef std::multiset multiset_type; + static int asptr(PyObject *obj, multiset_type **m) { + return traits_asptr_stdseq >::asptr(obj, m); + } + }; + + template + struct traits_from > { + static PyObject *from(const std::multiset& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + + +// exported classes + +namespace std { + + template class set { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T key_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::set), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdSetTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::set<" #T " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(SET), std::set); + + %std_set_methods(std::set); + %pycontainer_methods(std::set); + }; + + // Add the order operations <,>,<=,=> as needed + + %define %std_order_set(T) + %std_comp_methods(set); + %enddef + + %apply_otypes(%std_order_set); + + + //multiset + + template class multiset { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T key_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::multiset), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdMultisetTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::multiset<" #T " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(MULTISET), std::multiset); + + %std_multiset_methods(std::multiset); + %pycontainer_methods(std::multiset); + }; + + // Add the order operations <,>,<=,=> as needed + + %define %std_order_multiset(T) + %std_comp_methods(multiset); + %enddef + + %apply_otypes(%std_order_multiset); + +} + +// set + +%define %std_set_ptypen(...) +%template() std::set<__VA_ARGS__ >; +%enddef + +%apply_cpptypes(%std_set_ptypen); + +// multiset + +%define %std_multiset_ptypen(...) +%template() std::multiset<__VA_ARGS__ >; +%enddef + +%apply_cpptypes(%std_multiset_ptypen); diff --git a/Lib/python/std_string.i b/Lib/python/std_string.i index 2e2dd0152..1127cf984 100644 --- a/Lib/python/std_string.i +++ b/Lib/python/std_string.i @@ -16,56 +16,38 @@ #include %} -/* defining the std::string as/from/check methods */ -%fragment("SWIG_TryStdString","header", - fragment="SWIG_AsCharPtrAndSize") %{ +/* defining the std::string as/from methods */ + +%fragment(SWIG_AsVal_frag(std::string),"header", + fragment="SWIG_AsCharPtrAndSize") { SWIGSTATICINLINE(int) -SWIG_TryStdString(PyObject* obj, char*& buf, size_t& size) { - SWIG_AsCharPtrAndSize(obj, &buf, &size); - if (PyErr_Occurred() || !buf) { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - return 1; -} -%} - -%fragment("SWIG_CheckStdString","header", - fragment="SWIG_TryStdString") %{ -SWIGSTATICINLINE(int) -SWIG_CheckStdString(PyObject* obj) { + SWIG_AsVal_meth(std::string)(PyObject* obj, std::string *val) +{ char* buf = 0 ; size_t size = 0; - return SWIG_TryStdString(obj, buf, size); -} -%} - - -%fragment("SWIG_AsStdString","header", - fragment="SWIG_TryStdString") %{ -SWIGSTATICINLINE(std::string) -SWIG_AsStdString(PyObject* obj) { - char* buf = 0 ; size_t size = 0; - if (SWIG_TryStdString(obj, buf, size)) { - return std::string(buf, size); + if (SWIG_AsCharPtrAndSize(obj, &buf, &size)) { + if (buf) { + if (val) val->assign(buf, size); + return 1; + } } else { + PyErr_Clear(); + } + if (val) { PyErr_SetString(PyExc_TypeError,"a string is expected"); - return std::string(); } + return 0; +} } -%} -%fragment("SWIG_FromStdString","header", - fragment="SWIG_FromCharArray") %{ +%fragment(SWIG_From_frag(std::string),"header", + fragment="SWIG_FromCharArray") { SWIGSTATICINLINE(PyObject*) -SWIG_FromStdString(const std::string& s) { + SWIG_From_meth(std::string)(const std::string& s) { return SWIG_FromCharArray(s.data(), s.size()); } -%} +} + +%typemap_primitive(SWIG_CCode(STRING), std::string); /* declaring the typemaps */ - -%typemap_asfromcheck(std::string, STRING, - SWIG_AsStdString, - SWIG_FromStdString, - SWIG_CheckStdString); diff --git a/Lib/python/std_vector.i b/Lib/python/std_vector.i index 4a85c8056..c93972e63 100644 --- a/Lib/python/std_vector.i +++ b/Lib/python/std_vector.i @@ -1,46 +1,25 @@ // -// SWIG typemaps for std::vector types -// Luigi Ballabio -// Apr 8, 2002 -// +// std::vector // Python implementation -%include std_common.i -%include exception.i +%include std_container.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())); - } -} +// Vector -%exception std::vector::__setitem__ { - try { - $action - } catch (std::out_of_range& e) { - SWIG_exception(SWIG_IndexError,const_cast(e.what())); - } -} +%define %std_vector_methods(vector) + %std_sequence_methods(vector) + + void reserve(size_type n); + size_type capacity() const; +%enddef -%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())); - } -} +%define %std_vector_methods_val(vector) + %std_sequence_methods_val(vector) + + void reserve(size_type n); + size_type capacity() const; +%enddef // ------------------------------------------------------------------------ @@ -52,867 +31,144 @@ // 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*): +// -- f(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 +// the parameter may be modified; therefore, only a wrapped std::vector // can be passed. -// -- std::vector f(): +// -- std::vector f(), const 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(): +// -- std::vector& f(), std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned +// -- const std::vector* f(), f(const std::vector*): +// for consistency, they expect and return a plain vector pointer. // ------------------------------------------------------------------------ %{ #include -#include -#include %} -// exported class + +%fragment("StdVectorTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + struct traits_asptr > { + typedef std::vector vector_type; + typedef T value_type; + static int asptr(PyObject *obj, vector_type **vec) { + return traits_asptr_stdseq::asptr(obj, vec); + } + }; + + template + struct traits_from > { + typedef std::vector vector_type; + static PyObject *from(const vector_type& vec) { + return traits_from_stdseq::from(vec); + } + }; + } +%} + +// exported classes 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); - } - } - }; + template class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef T& reference; + typedef const T& const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::vector), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdVectorTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" #T " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_CCode(VECTOR), std::vector); + + %std_vector_methods(vector); + %pysequence_methods(std::vector); + }; - // Partial specialization for vectors of pointers. [ beazley ] + // *** + // This especialization should dissapears or + // get simplified when a 'const SWIGTYPE*&' can be + // be defined + // *** + template class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; - 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 &); + %traits_swigtype(T); - %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); - } - } - }; + %fragment(SWIG_Traits_frag(std::vector), "header", + fragment="StdVectorTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::vector<" #T " * >"; + } + }; + } + } - // specializations for built-ins + %typemap_traits_ptr(SWIG_CCode(VECTOR), std::vector); - %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 + %std_vector_methods_val(vector); + %pysequence_methods_val(std::vector); + }; - 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); + // Add the order operations <,>,<=,=> as needed + + %define %std_order_vector(T) + %std_comp_methods(vector); + %enddef + + %apply_otypes(%std_order_vector); + + // bool specialization + %extend vector { + void flip() + { + self->flip(); + } + } } + +%define %std_vector_ptypen(...) + namespace std { + %template() vector<__VA_ARGS__ >; + } +%enddef + +%apply_cpptypes(%std_vector_ptypen); + diff --git a/Lib/python/std_vectora.i b/Lib/python/std_vectora.i new file mode 100644 index 000000000..d61a5aceb --- /dev/null +++ b/Lib/python/std_vectora.i @@ -0,0 +1,194 @@ +// +// std::vector +// Python implementation +// +// First attemp to add allocators. Still, the plain version +// works much better. So, if tyou don't need allocators, use +// std_vector.i instead. +// + +%include std_container.i + +// Vector + +%define %std_vector_methods(vector) + %std_sequence_methods(SWIG_arg(vector)) + + void reserve(size_type n); + size_type capacity() const; +%enddef + + +%define %std_vector_methods_val(vector) + %std_sequence_methods_val(SWIG_arg(vector)) + + void reserve(size_type n); + size_type capacity() const; +%enddef + + +// ------------------------------------------------------------------------ +// 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&): +// 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 may be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(), const 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(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// -- const std::vector* f(), f(const std::vector*): +// for consistency, they expect and return a plain vector pointer. +// ------------------------------------------------------------------------ + +%{ +#include +%} + + +%fragment("StdVectorTraits","header",fragment="StdSequenceTraits") +%{ + namespace swigpy { + template + struct traits_asptr > { + typedef std::vector vector_type; + typedef T value_type; + static int asptr(PyObject *obj, vector_type **vec) { + return traits_asptr_stdseq::asptr(obj, vec); + } + }; + + template + struct traits_from > { + typedef std::vector vector_type; + static PyObject *from(const vector_type& vec) { + return traits_from_stdseq::from(vec); + } + }; + } +%} + +// exported classes + +namespace std { + + template > + class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef T& reference; + typedef const T& const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::vector), "header", + fragment=SWIG_Traits_frag(T), + fragment="StdVectorTraits") { + namespace swigpy { + template <> struct traits > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" #T "," #A " >"; + } + }; + } + } + + %typemap_traits(SWIG_CCode(VECTOR), std::vector); + + %std_vector_methods(SWIG_arg(vector)); + %pysequence_methods(SWIG_arg(std::vector)); + }; + + + // *** + // This pointer especialization should dissapears or get + // simplified when a 'const SWIGTYPE*&' can be be defined. + // *** + template > + class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; + + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::vector), "header", + fragment="StdVectorTraits") { + namespace swigpy { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::vector<" #T " *,"#A" >"; + } + }; + } + } + + %typemap_traits(SWIG_CCode(VECTOR), std::vector); + + %std_vector_methods_val(vector); + %pysequence_methods_val(SWIG_arg(std::vector)); + }; + + // Add the order operations <,>,<=,=> as needed + /* + %define %std_order_vector(T) + %std_comp_methods(vector); + %enddef + + %apply_otypes(%std_order_vector); + + // bool specialization + %extend vector { + void flip() + { + self->flip(); + } + } + */ +} + + +%define %std_vector_ptypen(...) +namespace std { + %template() vector<__VA_ARGS__, std::allocator<__VA_ARGS__ > >; + + // + // These extra %apply are needed since swig doesn't try + // std::vector and std::vector > as + // the same type yet. When this get fixed, these %apply should be + // removed (and maybe we will be able to have an unique std_vector.i + // definition too). + // + %apply vector<__VA_ARGS__, std::allocator<__VA_ARGS__ > > { + vector<__VA_ARGS__ > + } + %apply const vector<__VA_ARGS__, std::allocator<__VA_ARGS__ > >& { + const vector<__VA_ARGS__ >& + } +} +%enddef + +%apply_cpptypes(%std_vector_ptypen); +