diff --git a/SWIG/Lib/python/implicit.i b/SWIG/Lib/python/implicit.i index ab3531976..442f99f0e 100644 --- a/SWIG/Lib/python/implicit.i +++ b/SWIG/Lib/python/implicit.i @@ -47,7 +47,7 @@ %define %implicit_code(...) if (swigpy::check<__VA_ARGS__ >(obj)) { if (val) *val = new value_type(swigpy::as<__VA_ARGS__ >(obj)); - return 2; + return SWIG_NEWPTR; } %enddef @@ -73,7 +73,7 @@ namespace swigpy { static swig_type_info* desc = SWIG_TypeQuery("Type *"); if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { if (val) *val = vptr; - return 1; + return SWIG_OLDPTR; } else { if (PyErr_Occurred()) PyErr_Clear(); %formacro_1(%implicit_code,__VA_ARGS__) @@ -112,7 +112,7 @@ namespace swigpy { static swig_type_info* desc = SWIG_TypeQuery("Type *"); if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { if (val) *val = vptr; - return 1; + return SWIG_OLDPTR; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); @@ -153,7 +153,7 @@ namespace swigpy { static swig_type_info* desc = SWIG_TypeQuery("Type *"); if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { if (val) *val = vptr; - return 1; + return SWIG_OLDPTR; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); @@ -197,7 +197,7 @@ namespace swigpy { static swig_type_info* desc = SWIG_TypeQuery("Type *"); if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) { if (val) *val = vptr; - return 1; + return SWIG_OLDPTR; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); diff --git a/SWIG/Lib/python/pycontainer.i b/SWIG/Lib/python/pycontainer.i index c2e51e52a..a906a2158 100644 --- a/SWIG/Lib/python/pycontainer.i +++ b/SWIG/Lib/python/pycontainer.i @@ -37,7 +37,13 @@ namespace swigpy operator T () const { swigpy::PyObject_var item = PySequence_GetItem(_seq, _index); - return swigpy::as(item); + try { + return swigpy::as(item, true); + } catch (std::exception& e) { + PyErr_Format(PyExc_TypeError, + "error in sequence element %d: %s", _index, e.what()); + throw; + } } PySequence_Ref& operator=(const T& v) diff --git a/SWIG/Lib/python/pymacros.swg b/SWIG/Lib/python/pymacros.swg index ee0275442..1f5e51b8c 100644 --- a/SWIG/Lib/python/pymacros.swg +++ b/SWIG/Lib/python/pymacros.swg @@ -1,6 +1,9 @@ %{ /* Auxiliar swig macros that appear in the header */ +#define SWIG_OLDPTR 1 +#define SWIG_NEWPTR 2 + #ifdef __cplusplus #define SWIGSTATICINLINE(a) static inline a #define SWIGSTATIC(a) static a diff --git a/SWIG/Lib/python/pyprimtypes.swg b/SWIG/Lib/python/pyprimtypes.swg index 96f82f75b..91cb6d0f8 100644 --- a/SWIG/Lib/python/pyprimtypes.swg +++ b/SWIG/Lib/python/pyprimtypes.swg @@ -572,7 +572,7 @@ _apply_macro(Macro, bool, __VA_ARGS__); %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::basic_string, __VA_ARGS__); _apply_macro(Macro, std::complex, __VA_ARGS__); _apply_macro(Macro, std::complex, __VA_ARGS__); %enddef diff --git a/SWIG/Lib/python/pyptrtypes.swg b/SWIG/Lib/python/pyptrtypes.swg index cd42ca3c9..66b0a5286 100644 --- a/SWIG/Lib/python/pyptrtypes.swg +++ b/SWIG/Lib/python/pyptrtypes.swg @@ -7,106 +7,66 @@ %define PYPTR_IN_TYPEMAP(pyobj_asptr,pyfrag,...) %typemap(in,fragment=pyfrag) __VA_ARGS__ { - __VA_ARGS__ *ptr; + __VA_ARGS__ *ptr = (__VA_ARGS__ *)0; int res = pyobj_asptr($input, &ptr); - if (!res) SWIG_fail; + if (!res || !ptr) SWIG_fail; $1 = *ptr; - if (res > 1) delete ptr; + if (res == SWIG_NEWPTR) delete ptr; } %typemap(in,fragment=pyfrag) const __VA_ARGS__ & (int res = 0) - "if (!(res = pyobj_asptr($input, &$1))) SWIG_fail;"; + "if (!(res = pyobj_asptr($input, &$1)) || !($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; + __VA_ARGS__ *ptr = (__VA_ARGS__ *)0; int res = pyobj_asptr($input, &ptr); - if (!res) { + if (!res || !ptr) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } - if (!res) SWIG_fail; $1 = *ptr; - if (res > 1) delete ptr; + if (res == SWIG_NEWPTR) 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; + __VA_ARGS__ *ptr = 0; int res = pyobj_asptr($input, &ptr); - if (!res) + if (!res || !ptr) throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); temp = *ptr; $result = &temp; - if (res > 1) delete ptr; + if (res == SWIG_NEWPTR) delete ptr; } %typemap(directorout,fragment=pyfrag) __VA_ARGS__ { - __VA_ARGS__ *ptr; + __VA_ARGS__ *ptr = 0; int res = pyobj_asptr($input, &ptr); - if (!res) + if (!res || !ptr) throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); $result = *ptr; - if (res > 1) delete ptr; + if (res == SWIG_NEWPTR) delete ptr; } %typemap(directorout,fragment=pyfrag) const __VA_ARGS__& ($*1_ltype temp) { - __VA_ARGS__ *ptr; + __VA_ARGS__ *ptr = 0; int res = pyobj_asptr($input, &ptr); - if (!res) + if (!res || !ptr) throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); temp = *ptr; $result = &temp; - if (res > 1) delete ptr; + if (res == SWIG_NEWPTR) 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,...) @@ -121,25 +81,40 @@ %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__); + SWIG_arg(AsPtrFrag), __VA_ARGS__); + PYVAL_DIRECTORIN_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + 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_THROWS_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag),__VA_ARGS__); %enddef /* - typemap for simple swig types with only AsPtr/From conversor methods + typemap for simple swig types with only AsPtr/From methods */ %define %typemap_asptrfromn(CheckCode, ...) +%fragment(SWIG_AsVal_frag(__VA_ARGS__),"header", + fragment=SWIG_AsPtr_frag(__VA_ARGS__)) %{ +SWIGSTATICINLINE(int) + SWIG_AsVal_meth(__VA_ARGS__)(PyObject* obj, __VA_ARGS__ *val) +{ + __VA_ARGS__ *v = (__VA_ARGS__ *)0; + int res = SWIG_AsPtr_meth(__VA_ARGS__)(obj, &v); + if (!res || !v) return 0; + if (val) { + *val = *v; + if (res == SWIG_NEWPTR) delete v; + } + return 1; +} +%} %typemap_asptrfrom(SWIG_arg(CheckCode), - SWIG_AsPtr_meth(__VA_ARGS__), - SWIG_From_meth(__VA_ARGS__), + SWIG_arg(SWIG_AsPtr_meth(__VA_ARGS__)), + SWIG_arg(SWIG_From_meth(__VA_ARGS__)), SWIG_arg(SWIG_AsPtr_frag(__VA_ARGS__)), SWIG_arg(SWIG_From_frag(__VA_ARGS__)), __VA_ARGS__); diff --git a/SWIG/Lib/python/pystrings.swg b/SWIG/Lib/python/pystrings.swg index 499cc5d8a..d144bd120 100644 --- a/SWIG/Lib/python/pystrings.swg +++ b/SWIG/Lib/python/pystrings.swg @@ -18,7 +18,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size) if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_info, 0) != -1) { if (cptr) *cptr = vptr; if (size) *size = vptr ? (strlen(vptr) + 1) : 0; - return 1; + return SWIG_OLDPTR; } else { if (PyString_Check(obj)) { #if PY_VERSION_HEX >= 0x02000000 @@ -29,7 +29,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size) #endif if (cptr) *cptr = vptr; if (size) *size = vsize; - return 2; + return SWIG_NEWPTR; } } if (cptr || size) { diff --git a/SWIG/Lib/python/python.swg b/SWIG/Lib/python/python.swg index bb9a3fa28..8a055bb22 100644 --- a/SWIG/Lib/python/python.swg +++ b/SWIG/Lib/python/python.swg @@ -35,6 +35,7 @@ %include "pyobject.swg" %include "pystrings.swg" %include "pyvaltypes.swg" +%include "pyptrtypes.swg" %include "pyprimtypes.swg" %include "pymisctypes.swg" diff --git a/SWIG/Lib/python/pyvaltypes.swg b/SWIG/Lib/python/pyvaltypes.swg index eca6d28aa..8baa7efc4 100644 --- a/SWIG/Lib/python/pyvaltypes.swg +++ b/SWIG/Lib/python/pyvaltypes.swg @@ -45,7 +45,7 @@ "$result = pyobj_from((__VA_ARGS__)$1);"; %enddef -/* Primitive types */ +/* constant installation code */ %define PYVAL_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...) %typemap(constcode,fragment=pyfrag) __VA_ARGS__ "PyDict_SetItemString(d,\"$symname\", pyobj_from((__VA_ARGS__)$value));"; diff --git a/SWIG/Lib/python/std_common.i b/SWIG/Lib/python/std_common.i index 089aac3f7..ad92be105 100644 --- a/SWIG/Lib/python/std_common.i +++ b/SWIG/Lib/python/std_common.i @@ -143,7 +143,7 @@ namespace swigpy { int res = asptr(obj, &p); if (res) { *val = *p; - if (res > 1) delete p; + if (res == SWIG_NEWPTR) delete p; } return res; } else { @@ -167,16 +167,16 @@ namespace swigpy { struct traits_as { typedef Type value_type; - static value_type as(PyObject *obj) { + static value_type as(PyObject *obj, bool throw_error) { value_type v; - if (!asval(obj, &v)) { - std::string msg= "a value of type '"; + if (!obj || !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); + if (throw_error) throw std::invalid_argument(msg); } return v; } @@ -186,9 +186,9 @@ namespace swigpy { struct traits_as { typedef Type value_type; - static value_type as(PyObject *obj) { + static value_type as(PyObject *obj, bool throw_error) { value_type *v = 0; - int res = asptr(obj, &v); + int res = obj ? asptr(obj, &v) : 0; if (res) { if (res > 1) { value_type r(*v); @@ -198,20 +198,20 @@ namespace swigpy { return *v; } } else { - std::string msg= "a value of type '"; + 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); + if (throw_error) throw std::invalid_argument(msg); } } }; template - inline Type as(PyObject *obj) { - return traits_as::category>::as(obj); + inline Type as(PyObject *obj, bool te = false) { + return traits_as::category>::as(obj, te); } template @@ -224,7 +224,7 @@ namespace swigpy { { typedef Type value_type; static bool check(PyObject *obj) { - return asval(obj, (value_type *)(0)); + return obj && asval(obj, (value_type *)(0)); } }; @@ -233,7 +233,7 @@ namespace swigpy { { typedef Type value_type; static bool check(PyObject *obj) { - return asptr(obj, (value_type **)(0)); + return obj && asptr(obj, (value_type **)(0)); } }; diff --git a/SWIG/Lib/python/std_container.i b/SWIG/Lib/python/std_container.i index 11fceb353..4991d656c 100644 --- a/SWIG/Lib/python/std_container.i +++ b/SWIG/Lib/python/std_container.i @@ -134,7 +134,7 @@ sequence *pseq = new sequence(); assign(pyseq, pseq); *seq = pseq; - return 2; + return SWIG_NEWPTR; } else { return pyseq.check(); } diff --git a/SWIG/Lib/python/std_string.i b/SWIG/Lib/python/std_string.i index 1127cf984..547fba4fa 100644 --- a/SWIG/Lib/python/std_string.i +++ b/SWIG/Lib/python/std_string.i @@ -12,42 +12,194 @@ // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ +%include exception.i +%include pycontainer.i + %{ #include %} +namespace std { + template + class basic_string + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _CharT value_type; + typedef value_type reference; + typedef value_type const_reference; + + static const size_type npos; -/* defining the std::string as/from methods */ + basic_string(); + basic_string(const basic_string& __str); + basic_string(const _CharT* __s, size_type __n); -%fragment(SWIG_AsVal_frag(std::string),"header", + // Capacity: + size_type size() const; + + size_type length() const; + + size_type max_size() const; + + void resize(size_type __n, _CharT __c); + + void resize(size_type __n); + + size_type capacity() const; + + void reserve(size_type __res_arg = 0); + + void clear(); + + bool empty() const; + + // Modifiers: + basic_string + operator+=(const basic_string& __str); + + basic_string& + append(const basic_string& __str); + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + basic_string& + append(const _CharT* __s, size_type __n); + + basic_string& + append(size_type __n, _CharT __c); + + void push_back(_CharT __c); + + basic_string& + assign(const basic_string& __str); + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n); + + basic_string& + assign(const _CharT* __s, size_type __n); + + basic_string& + assign(size_type __n, _CharT __c); + + basic_string& + insert(size_type __pos1, const basic_string& __str); + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n); + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n); + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c); + + basic_string& + erase(size_type __pos = 0, size_type __n = npos); + + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str); + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2); + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2); + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c); + + %ignore pop(); + %pysequence_methods_val(std::basic_string<_CharT>); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + iterator + insert(iterator __p, _CharT __c = _CharT()); + + iterator + erase(iterator __position); + + iterator + erase(iterator __first, iterator __last); + + void + insert(iterator __p, size_type __n, _CharT __c); + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str); + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __s, size_type __n); + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s); + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c); + + basic_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2); + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2); + + basic_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2); + + basic_string& + replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2); + #endif + }; + + typedef basic_string string; + +} + +/* defining the std::string asptr/from methods */ + +%fragment(SWIG_AsPtr_frag(std::basic_string),"header", fragment="SWIG_AsCharPtrAndSize") { SWIGSTATICINLINE(int) - SWIG_AsVal_meth(std::string)(PyObject* obj, std::string *val) -{ - char* buf = 0 ; size_t size = 0; - if (SWIG_AsCharPtrAndSize(obj, &buf, &size)) { - if (buf) { - if (val) val->assign(buf, size); - return 1; + SWIG_AsPtr_meth(std::basic_string)(PyObject* obj, std::string **val) + { + static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string *"); + std::string *vptr; + if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) != -1) { + if (val) *val = vptr; + return SWIG_OLDPTR; + } else { + char* buf = 0 ; size_t size = 0; + if (SWIG_AsCharPtrAndSize(obj, &buf, &size)) { + if (buf) { + if (val) *val = new std::string(buf, size); + return SWIG_NEWPTR; + } + } else { + PyErr_Clear(); + } + if (val) { + PyErr_SetString(PyExc_TypeError,"a string is expected"); + } + return 0; } - } else { - PyErr_Clear(); - } - if (val) { - PyErr_SetString(PyExc_TypeError,"a string is expected"); } - return 0; -} } -%fragment(SWIG_From_frag(std::string),"header", +%fragment(SWIG_From_frag(std::basic_string),"header", fragment="SWIG_FromCharArray") { SWIGSTATICINLINE(PyObject*) - SWIG_From_meth(std::string)(const std::string& s) { - return SWIG_FromCharArray(s.data(), s.size()); -} + SWIG_From_meth(std::basic_string)(const std::string& s) + { + return SWIG_FromCharArray(s.data(), s.size()); + } } -%typemap_primitive(SWIG_CCode(STRING), std::string); +%typemap_asptrfromn(SWIG_CCode(STRING), std::basic_string); -/* declaring the typemaps */