From 7afe6bc139287b03ebdd7d0bf55aedc245ae8e90 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Sun, 21 Mar 2004 23:26:18 +0000 Subject: [PATCH] normalizing the inout typemaps and other cosmetic fixes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5782 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/python/argcargv.i | 20 ++-- Lib/python/attribute.i | 37 ++----- Lib/python/ccomplex.i | 6 +- Lib/python/fragments.i | 13 ++- Lib/python/implicit.i | 18 ++-- Lib/python/pycontainer.i | 25 +++-- Lib/python/pyinout.swg | 215 +++++++++++++++++++++++++++++++++++++ Lib/python/pymacros.swg | 38 ++++++- Lib/python/pyprimtypes.swg | 148 +++++++++++++++++-------- Lib/python/pyptrtypes.swg | 90 +++++++++------- Lib/python/pyrun.swg | 1 + Lib/python/pystrings.swg | 4 +- Lib/python/python.swg | 2 + Lib/python/pyvaltypes.swg | 60 ++++++----- Lib/python/std_common.i | 133 ++++++++++++++++++----- Lib/python/std_complex.i | 2 +- Lib/python/std_container.i | 39 +------ Lib/python/std_deque.i | 14 +-- Lib/python/std_list.i | 14 +-- Lib/python/std_map.i | 67 ++---------- Lib/python/std_multimap.i | 148 +++++++++++++++++++++++++ Lib/python/std_multiset.i | 114 ++++++++++++++++++++ Lib/python/std_pair.i | 23 ++-- Lib/python/std_set.i | 99 +---------------- Lib/python/std_string.i | 53 +++++---- Lib/python/std_vector.i | 39 +++---- Lib/python/std_vectora.i | 14 +-- Lib/python/typemaps.i | 175 +++++------------------------- 28 files changed, 978 insertions(+), 633 deletions(-) create mode 100644 Lib/python/pyinout.swg create mode 100644 Lib/python/std_multimap.i create mode 100644 Lib/python/std_multiset.i diff --git a/Lib/python/argcargv.i b/Lib/python/argcargv.i index 0fb80cbad..fe8c4c9b5 100644 --- a/Lib/python/argcargv.i +++ b/Lib/python/argcargv.i @@ -2,12 +2,12 @@ * --- Argc & Argv --- * ------------------------------------------------------------ */ -%fragment("SWIG_AsArgcArgv","header") %{ +%fragment("SWIG_AsArgcArgv","header", + fragment="SWIG_AsCharPtr") %{ SWIGSTATIC(char**) -SWIG_AsArgcArgv(PyObject* input, - swig_type_info* ppchar_info, - swig_type_info* pchar_info, - size_t* argc, int* owner) + SWIG_AsArgcArgv(PyObject* input, + swig_type_info* ppchar_info, + size_t* argc, int* owner) { char **argv = 0; size_t i = 0; @@ -20,8 +20,7 @@ SWIG_AsArgcArgv(PyObject* input, *owner = 1; for (; i < *argc; ++i) { PyObject *obj = list ? PyList_GetItem(input,i) : PyTuple_GetItem(input,i); - argv[i] = SWIG_AsCharPtr(obj, pchar_info); - if (PyErr_Occurred()) { + if (!SWIG_AsCharPtr(obj, &(argv[i]))) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError,"list or tuple must contain strings only"); } @@ -51,8 +50,7 @@ SWIG_AsArgcArgv(PyObject* input, %typemap(in,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int owner) { size_t argc = 0; - char **argv = SWIG_AsArgcArgv($input, $descriptor(char**), - $descriptor(char*), &argc, &owner); + char **argv = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &owner); if (PyErr_Occurred()) { $1 = 0; $2 = 0; SWIG_fail; @@ -62,7 +60,7 @@ SWIG_AsArgcArgv(PyObject* input, } } -%typemap(freearg) (int ARGC, char **ARGV) (owner) { - if (owner) swig_delete_array($2); +%typemap(freearg) (int ARGC, char **ARGV) { + if (owner$argnum) swig_delete_array($2); } diff --git a/Lib/python/attribute.i b/Lib/python/attribute.i index b494ca68a..69d7cd913 100644 --- a/Lib/python/attribute.i +++ b/Lib/python/attribute.i @@ -1,5 +1,5 @@ %{ -#include +#include %} /* @@ -69,49 +69,34 @@ */ -%define %_attribute(Class, type, attr, get, set) +%define %_attribute(Class, type, attr, getcode, setcode) %extend Class { type attr; } %{ - template - inline type Class ##_## attr ## _get(C *t) { - return get; - } - template - inline void Class ##_## attr ## _set(C *t, const type& val) { - set; - } +#define Class ##_## attr ## _get(_t) getcode +#define Class ##_## attr ## _set(_t, _val) setcode %} %enddef %define %attribute(Class, type, attr, get, ...) +%ignore Class::get; #if #__VA_ARGS__ != "" + %ignore Class::__VA_ARGS__; %_attribute(SWIG_arg(Class), SWIG_arg(type), - attr, t->get(), t->__VA_ARGS__(val)) + attr, _t->get(), _t->__VA_ARGS__(_val)) #else %_attribute(SWIG_arg(Class), SWIG_arg(type), - attr, t->get(), - std::cerr << "'attr' is a read-only attribute" << std::endl); + attr, _t->get(), + fprintf(stderr,"'attr' is a read-only attribute")) #endif %enddef %define %_attribute_ref(Class, type, attr, ref_name) -%extend Class { - type attr; -} %ignore Class::ref_name(); %ignore Class::ref_name() const; -%{ - template - inline type Class ##_## attr ## _get(C *t) { - return t->ref_name(); - } - template - inline void Class ##_## attr ## _set(C *t, const type& val) { - t->ref_name() = val; - } -%} +%_attribute(SWIG_arg(Class), SWIG_arg(type), + attr, _t->ref_name(), _t->ref_name() = _val) %enddef %define %attribute_ref(Class, type, attr, ...) diff --git a/Lib/python/ccomplex.i b/Lib/python/ccomplex.i index 04e95e349..9ca9f80c0 100644 --- a/Lib/python/ccomplex.i +++ b/Lib/python/ccomplex.i @@ -1,7 +1,7 @@ #ifndef __python_ccomplex_i__ #define __python_ccomplex_i__ -%include "complex_common.i" +%include complex_common.i /* * C complex wrap @@ -32,7 +32,11 @@ %typemap_primitive(SWIG_TYPECHECK_CPLXFLT, float_complex); %typemap_primitive(SWIG_TYPECHECK_CPLXDBL, double_complex); +/* empty complex. hack in the meantime */ %apply double_complex { complex }; +%apply const double_complex& { const complex& }; +%apply double_complex& { complex& }; +%apply double_complex* { complex* }; diff --git a/Lib/python/fragments.i b/Lib/python/fragments.i index 0fbe1f2f8..5d5b18896 100644 --- a/Lib/python/fragments.i +++ b/Lib/python/fragments.i @@ -1,21 +1,20 @@ /* Helper function to return tuples */ %fragment("t_output_helper","header") %{ -static PyObject* t_output_helper(PyObject* target, PyObject* o) { + static PyObject* t_output_helper(PyObject* target, PyObject* o) { PyObject* o2; PyObject* o3; - + if (!target) { target = o; } else if (target == Py_None) { Py_DECREF(Py_None); target = o; } else { - if (!PyTuple_Check(target)) { - o2 = target; - target = PyTuple_New(1); - PyTuple_SetItem(target, 0, o2); - } + o2 = target; + target = PyTuple_New(1); + PyTuple_SetItem(target, 0, o2); + o3 = PyTuple_New(1); PyTuple_SetItem(o3, 0, o); diff --git a/Lib/python/implicit.i b/Lib/python/implicit.i index 442f99f0e..32835e2cc 100644 --- a/Lib/python/implicit.i +++ b/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 SWIG_NEWPTR; + return SWIG_NEWOBJ; } %enddef @@ -58,7 +58,7 @@ %formacro_1(%implicit_type,__VA_ARGS__); %fragment(SWIG_Traits_frag(Type),"header", - fragment="traits" + fragment="StdTraits" %formacro_1(%implicit_frag,__VA_ARGS__)) %{ namespace swigpy { template <> struct traits { @@ -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 SWIG_OLDPTR; + return SWIG_OLDOBJ; } else { if (PyErr_Occurred()) PyErr_Clear(); %formacro_1(%implicit_code,__VA_ARGS__) @@ -97,7 +97,7 @@ namespace swigpy { %traits_swigtype(Imp1); %fragment(SWIG_Traits_frag(Type),"header", - fragment="traits", + fragment="StdTraits", fragment=SWIG_Traits_frag(Imp1)) %{ namespace swigpy { template <> struct traits< Type > { @@ -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 SWIG_OLDPTR; + return SWIG_OLDOBJ; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); @@ -137,7 +137,7 @@ namespace swigpy { %traits_swigtype(Imp2); %fragment(SWIG_Traits_frag(Type),"header", - fragment="traits", + fragment="StdTraits", fragment=SWIG_Traits_frag(Imp1), fragment=SWIG_Traits_frag(Imp2)) %{ namespace swigpy { @@ -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 SWIG_OLDPTR; + return SWIG_OLDOBJ; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); @@ -180,7 +180,7 @@ namespace swigpy { %traits_swigtype(Imp3); %fragment(SWIG_Traits_frag(Type),"header", - fragment="traits", + fragment="StdTraits", fragment=SWIG_Traits_frag(Imp1), fragment=SWIG_Traits_frag(Imp2), fragment=SWIG_Traits_frag(Imp3)) %{ @@ -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 SWIG_OLDPTR; + return SWIG_OLDOBJ; } else { if (PyErr_Occurred()) PyErr_Clear(); %implicit_code(Imp1); diff --git a/Lib/python/pycontainer.i b/Lib/python/pycontainer.i index a906a2158..f3bb7a6d4 100644 --- a/Lib/python/pycontainer.i +++ b/Lib/python/pycontainer.i @@ -17,10 +17,13 @@ #if PY_VERSION_HEX < 0x02000000 #define PySequence_Size PySequence_Length #endif +#if PY_VERSION_HEX < 0x02020000 +#define PyObject_GetIter Py_INCREF +#endif %} %fragment("PySequence_Cont","header", - fragment="traits", + fragment="StdTraits", fragment="PyObject_var") %{ #include @@ -334,8 +337,8 @@ namespace swigpy return tmp; } - void __setslice__(difference_type i, - difference_type j, const Sequence& v) { + 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; @@ -362,8 +365,7 @@ namespace swigpy throw std::out_of_range("index out of range"); } - void __delslice__(difference_type i, - difference_type j) { + void __delslice__(difference_type i, difference_type j) { Sequence::size_type size = self->size(); if (i<0) i +=size; if (j<0) j +=size; @@ -455,6 +457,7 @@ namespace swigpy void append(value_type x) { self->push_back(x); } + } %enddef @@ -472,7 +475,7 @@ namespace swigpy } void __setitem__(const key_type& key, const mapped_type& x) { - (*self)[key] = x; + self->insert(Dict::value_type(key,x)); } void __delitem__(const key_type& key) { @@ -542,11 +545,11 @@ namespace swigpy } // Python 2.2 methods - bool __contains__(const key_type& key) const { - Dict::const_iterator i = self->find(key); - return i != self->end(); + bool __contains__(const key_type& key) { + return self->find(key) != self->end(); } + PyObject* __iter__() { Dict::size_type size = self->size(); int pysize = size <= INT_MAX ? (int) size : 0; @@ -562,13 +565,9 @@ namespace swigpy 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/pyinout.swg b/Lib/python/pyinout.swg new file mode 100644 index 000000000..4ad75e279 --- /dev/null +++ b/Lib/python/pyinout.swg @@ -0,0 +1,215 @@ +// +// Uncomment the following definition if you don't want the in/out +// typemaps by default, ie, you prefer to use typemaps.i. +// +//#define SWIG_INOUT_NODEF + +// +// Use the following definition to enable the INPUT parameters to +// accept both 'by value' and 'pointer' objects. +// +#define SWIG_INPUT_ACCEPT_PTRS + +// ------------------------------------------------------------------------ +// Pointer handling +// +// These mappings provide support for input/output arguments and common +// uses for C/C++ pointers. +// ------------------------------------------------------------------------ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ +#ifdef SWIG_INPUT_ACCEPT_PTRS +#define SWIG_CheckInputPtr(input,arg,desc,disown) (SWIG_ConvertPtr(input,arg,desc,disown) != -1) +#else +#define SWIG_CheckInputPtr(input,arg,desc,disown) (0) +#endif + +%define _PYVAL_INPUT_TYPEMAP(code,as_meth,check_meth,as_frag,check_frag,Type) + %typemap(in,fragment=as_frag) Type *INPUT ($*1_ltype temp, int res = 0) { + if (!SWIG_CheckInputPtr($input,(void **)(&$1),$1_descriptor,$disown)) { + temp = as_meth($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp; + res = SWIG_NEWOBJ; + } + } + %typemap(in,fragment=as_frag) Type &INPUT($*1_ltype temp, int res = 0) { + if (!SWIG_CheckInputPtr($input,(void **)(&$1),$1_descriptor,$disown)) { + temp = as_meth($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp; + res = SWIG_NEWOBJ; + } + if (!$1) SWIG_fail; + } + %typemap(typecheck,precedence=code,fragment=check_frag) Type *INPUT, Type &INPUT { + void *ptr; + $1 = (check_meth($input) || (SWIG_CheckInputPtr($input,&ptr,$1_descriptor,0))); + } +%enddef + +%define _PYPTR_INPUT_TYPEMAP(code,asptr_meth,asptr_frag,Type) + %typemap(in,fragment=asptr_frag) Type *INPUT(int res) + "if (!(res = asptr_meth($input, &$1))) SWIG_fail;"; + %typemap(in,fragment=asptr_frag) Type &INPUT(int res) + "if (!(res = asptr_meth($input, &$1)) || !($1)) SWIG_fail;"; + %typemap(freearg) Type *INPUT, Type &INPUT + "if (res$argnum == SWIG_NEWOBJ) delete $1;"; + %typemap(typecheck,precedence=code,fragment=asptr_frag) Type *INPUT, Type &INPUT + "$1 = asptr_meth($input, (Type*)0) != 0;" +%enddef + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// These typemaps contributed by Robin Dunn +//---------------------------------------------------------------------- +// +// T_OUTPUT typemap (and helper function) to return multiple argouts as +// a tuple instead of a list. +// +// Author: Robin Dunn +//---------------------------------------------------------------------- + +%include fragments.i + +%define _PYVAL_OUTPUT_TYPEMAP(from_meth, from_frag, Type) + %typemap(in,numinputs=0) Type *OUTPUT ($*1_ltype temp, int res = 0), + Type &OUTPUT ($*1_ltype temp, int res = 0) + "$1 = &temp; res = SWIG_NEWOBJ;"; + %fragment("t_out_helper"{Type},"header", + fragment="t_output_helper",fragment=from_frag) {} + %typemap(argout,fragment="t_out_helper"{Type}) Type *OUTPUT, Type &OUTPUT + "$result = t_output_helper($result, ((res$argnum == SWIG_NEWOBJ) ? + from_meth((*$1)) : SWIG_NewPointerObj((void*)($1), $1_descriptor, 0)));"; + +%enddef + + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + void neg(double *INOUT); + +or you can use the %apply directive : + + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%define _PYVAL_INOUT_TYPEMAP(Type) + %typemap(in) Type *INOUT = Type *INPUT; + %typemap(in) Type &INOUT = Type &INPUT; + %typemap(typecheck) Type *INOUT = Type *INPUT; + %typemap(typecheck) Type &INOUT = Type &INPUT; + %typemap(argout) Type *INOUT = Type *OUTPUT; + %typemap(argout) Type &INOUT = Type &OUTPUT; +%enddef + + +%define _PYPTR_INOUT_TYPEMAP(Type) + _PYVAL_INOUT_TYPEMAP(SWIG_arg(Type)) + %typemap(freearg) Type *INOUT = Type *INPUT; + %typemap(freearg) Type &INOUT = Type &INPUT; +%enddef + +#ifndef SWIG_INOUT_NODEF +#define PYVAL_INPUT_TYPEMAP(code,_a,_c,_af,_cf,...) \ + _PYVAL_INPUT_TYPEMAP(SWIG_arg(code),SWIG_arg(_a),SWIG_arg(_c), \ + SWIG_arg(_af),SWIG_arg(_cf),SWIG_arg(__VA_ARGS__)) + +#define PYPTR_INPUT_TYPEMAP(code,_a,_af,...) \ + _PYPTR_INPUT_TYPEMAP(SWIG_arg(code),SWIG_arg(_a),SWIG_arg(_af), \ + SWIG_arg(__VA_ARGS__)) + +#define PYVAL_OUTPUT_TYPEMAP(_f,_ff,...) \ + _PYVAL_OUTPUT_TYPEMAP(SWIG_arg(_f),SWIG_arg(_ff),SWIG_arg(__VA_ARGS__)) + +#define PYVAL_INOUT_TYPEMAP(...) _PYVAL_INOUT_TYPEMAP(SWIG_arg(__VA_ARGS__)) +#define PYPTR_INOUT_TYPEMAP(...) _PYPTR_INOUT_TYPEMAP(SWIG_arg(__VA_ARGS__)) +#else /* You need to include typemaps.i */ +#define PYVAL_OUTPUT_TYPEMAP(...) +#define PYVAL_INPUT_TYPEMAP(...) +#define PYVAL_INOUT_TYPEMAP(...) +#define PYPTR_INPUT_TYPEMAP(...) +#define PYPTR_INOUT_TYPEMAP(...) +#endif /* SWIG_INOUT_DEFAULT */ diff --git a/Lib/python/pymacros.swg b/Lib/python/pymacros.swg index 1f5e51b8c..fd6eb675c 100644 --- a/Lib/python/pymacros.swg +++ b/Lib/python/pymacros.swg @@ -1,8 +1,8 @@ %{ /* Auxiliar swig macros that appear in the header */ -#define SWIG_OLDPTR 1 -#define SWIG_NEWPTR 2 +#define SWIG_OLDOBJ 1 +#define SWIG_NEWOBJ 2 #ifdef __cplusplus #define SWIGSTATICINLINE(a) static inline a @@ -46,7 +46,8 @@ #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_OrderType(...) SWIG_MethodType(OrderType, __VA_ARGS__) +#define SWIG_EqualType(...) SWIG_MethodType(EqualType, __VA_ARGS__) #define SWIG_Traits_frag(...) SWIG_StringType(Traits, __VA_ARGS__) #define SWIG_AsPtr_frag(...) SWIG_StringType(AsPtr, __VA_ARGS__) @@ -94,3 +95,34 @@ macro(arg1, arg2) %define %formacro_2(macro,...) %_formacro_2(macro, __VA_ARGS__, __fordone__) %enddef + + +%define %swig_mark_flag(x) +%ignore x; +#define x 1 +%enddef + +%define %_apply_if(x,macro) +#if x == 1 +macro +#endif +%enddef + +%define %_apply_if2(x,y,macro) +#if x == 1 && #y == 1 +macro +#endif +%enddef + +%define %apply_if(x,...) + %_apply_if(SWIG_arg(x),SWIG_arg(__VA_ARGS__)) +%enddef + +%define %apply_if2(x,y,...) + %_apply_if2(SWIG_arg(x),SWIG_arg(y),SWIG_arg(__VA_ARGS__)) +%enddef + +#define %swig_equal_type(...) %swig_mark_flag(SWIG_EqualType(__VA_ARGS__)) +#define %swig_order_type(...) \ + %swig_mark_flag(SWIG_EqualType(__VA_ARGS__)) \ + %swig_mark_flag(SWIG_OrderType(__VA_ARGS__)) diff --git a/Lib/python/pyprimtypes.swg b/Lib/python/pyprimtypes.swg index 91cb6d0f8..5aa9311ff 100644 --- a/Lib/python/pyprimtypes.swg +++ b/Lib/python/pyprimtypes.swg @@ -30,10 +30,6 @@ SWIG_define(SWIG_From_meth(double), PyFloat_FromDouble); SWIGSTATICINLINE(int) SWIG_AsVal_meth(unsigned long)(PyObject * obj, unsigned long *val) { - if (PyLong_Check(obj)) { - if (val) *val = PyLong_AsUnsignedLong(obj); - return 1; - } if (PyInt_Check(obj)) { long v = PyInt_AsLong(obj); if (v >= 0) { @@ -41,8 +37,18 @@ SWIGSTATICINLINE(int) return 1; } } + if (PyLong_Check(obj)) { + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return 1; + } else { + if (!val) PyErr_Clear(); + return 0; + } + } if (val) { - PyErr_SetString(PyExc_TypeError, "a unsigned long is expected"); + PyErr_SetString(PyExc_TypeError, "an unsigned long is expected"); } return 0; } @@ -101,14 +107,20 @@ SWIGSTATICINLINE(int) 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 (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return 1; + } else { + if (!val) PyErr_Clear(); + return 0; + } + } if (val) { PyErr_SetString(PyExc_TypeError, "a double is expected"); } @@ -120,14 +132,20 @@ SWIGSTATICINLINE(int) SWIGSTATICINLINE(int) SWIG_AsVal_meth(long)(PyObject * obj, long* val) { - 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 (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return 1; + } else { + if (!val) PyErr_Clear(); + return 0; + } + } if (val) { PyErr_SetString(PyExc_TypeError, "a long is expected"); } @@ -164,8 +182,14 @@ SWIGSTATICINLINE(int) SWIG_AsVal_meth(long long)(PyObject *obj, long long *val) { if (PyLong_Check(obj)) { - if (val) *val = PyLong_AsLongLong(obj); - return 1; + long long v = PyLong_AsLongLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return 1; + } else { + if (!val) PyErr_Clear(); + return 0; + } } if (PyInt_Check(obj)) { if (val) *val = PyInt_AsLong(obj); @@ -184,8 +208,14 @@ SWIGSTATICINLINE(int) SWIG_AsVal_meth(unsigned long long)(PyObject *obj, unsigned long long *val) { if (PyLong_Check(obj)) { - if (val) *val = PyLong_AsUnsignedLongLong(obj); - return 1; + unsigned long long v = PyLong_AsUnsignedLongLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return 1; + } else { + if (!val) PyErr_Clear(); + return 0; + } } unsigned long v; if (SWIG_AsVal_meth(unsigned long)(obj,&v)) { @@ -195,7 +225,7 @@ SWIGSTATICINLINE(int) PyErr_Clear(); } if (val) { - PyErr_SetString(PyExc_TypeError, "a long long is expected"); + PyErr_SetString(PyExc_TypeError, "an unsigned long long is expected"); } return 0; } @@ -314,7 +344,7 @@ SWIG_AsVal_meth(unsigned int)(PyObject *obj, unsigned int *val) PyErr_Clear(); } if (val) { - PyErr_SetString(PyExc_TypeError, "a unsigned int is expected"); + PyErr_SetString(PyExc_TypeError, "an unsigned int is expected"); } return 0; } @@ -356,7 +386,7 @@ SWIGSTATICINLINE(int) PyErr_Clear(); } if (val) { - PyErr_SetString(PyExc_TypeError, "a unsigned char is expected"); + PyErr_SetString(PyExc_TypeError, "an unsigned char is expected"); } return 0; } @@ -381,7 +411,7 @@ SWIGSTATICINLINE(int) PyErr_Clear(); } if (val) { - PyErr_SetString(PyExc_TypeError, "a unsigned short is expected"); + PyErr_SetString(PyExc_TypeError, "an unsigned short is expected"); } return 0; } @@ -515,20 +545,6 @@ SWIGSTATICINLINE(int) %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); /* ------------------------------------------------------------ @@ -546,7 +562,8 @@ SWIGSTATICINLINE(int) %enddef /* Apply macro to the order types */ -%define %apply_otypes(Macro,...) +%define %apply_ctypes(Macro,...) +_apply_macro(Macro, bool , __VA_ARGS__); _apply_macro(Macro, signed char , __VA_ARGS__); _apply_macro(Macro, unsigned char , __VA_ARGS__); _apply_macro(Macro, short , __VA_ARGS__); @@ -562,19 +579,12 @@ _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_ctypes(Macro, __VA_ARGS__) _apply_macro(Macro, std::basic_string, __VA_ARGS__); -_apply_macro(Macro, std::complex, __VA_ARGS__); -_apply_macro(Macro, std::complex, __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 */ @@ -582,3 +592,49 @@ _apply_macro(Macro, std::complex, __VA_ARGS__); %apply_cpptypes(%apply_cpptypes, Macro2) %enddef +%define %apply_checkctypes(Macro) +Macro(SWIG_CCode(BOOL), bool); +Macro(SWIG_CCode(INT8), signed char); +Macro(SWIG_CCode(UINT8), unsigned char); +Macro(SWIG_CCode(INT16), short); +Macro(SWIG_CCode(UINT16), unsigned short); +Macro(SWIG_CCode(INT32), int); +Macro(SWIG_CCode(UINT32), unsigned int); +Macro(SWIG_CCode(INT64), long); +Macro(SWIG_CCode(UINT64), unsigned long); +Macro(SWIG_CCode(INT128), long long); +Macro(SWIG_CCode(UINT128), unsigned long long); +Macro(SWIG_CCode(FLOAT), float); +Macro(SWIG_CCode(DOUBLE), double); +Macro(SWIG_CCode(CHAR), char); +%enddef + +/* ------------------------------------------------------------ + * Apply the primitive typemap for all the types with checkcode + * ------------------------------------------------------------ */ + +%apply_checkctypes(%typemap_primitive) + + +/* ------------------------------------------------------------ + * equal and order types definition + * ------------------------------------------------------------ */ + +%swig_equal_type(bool); +%swig_equal_type(std::complex); +%swig_equal_type(std::complex); + +%swig_order_type(std::basic_string); +%swig_order_type(signed char); +%swig_order_type(unsigned char); +%swig_order_type(short); +%swig_order_type(unsigned short); +%swig_order_type(int); +%swig_order_type(unsigned int); +%swig_order_type(long); +%swig_order_type(unsigned long); +%swig_order_type(long long); +%swig_order_type(unsigned long long); +%swig_order_type(float); +%swig_order_type(double); +%swig_order_type(char); diff --git a/Lib/python/pyptrtypes.swg b/Lib/python/pyptrtypes.swg index 66b0a5286..5ca9207e4 100644 --- a/Lib/python/pyptrtypes.swg +++ b/Lib/python/pyptrtypes.swg @@ -5,74 +5,74 @@ /* in */ -%define PYPTR_IN_TYPEMAP(pyobj_asptr,pyfrag,...) +%define PYPTR_IN_TYPEMAP(asptr_meth,pyfrag,...) %typemap(in,fragment=pyfrag) __VA_ARGS__ { __VA_ARGS__ *ptr = (__VA_ARGS__ *)0; - int res = pyobj_asptr($input, &ptr); + int res = asptr_meth($input, &ptr); if (!res || !ptr) SWIG_fail; $1 = *ptr; - if (res == SWIG_NEWPTR) delete ptr; + if (res == SWIG_NEWOBJ) delete ptr; } %typemap(in,fragment=pyfrag) const __VA_ARGS__ & (int res = 0) - "if (!(res = pyobj_asptr($input, &$1)) || !($1)) SWIG_fail;"; + "if (!(res = asptr_meth($input, &$1)) || !($1)) SWIG_fail;"; %typemap(freearg) const __VA_ARGS__ & - "if (res$argnum > 1) delete $1;"; + "if (res$argnum == SWIG_NEWOBJ) delete $1;"; %enddef /* varin */ -%define PYPTR_VARIN_TYPEMAP(pyobj_asptr,pyfrag,...) +%define PYPTR_VARIN_TYPEMAP(asptr_meth,pyfrag,...) %typemap(varin,fragment=pyfrag) __VA_ARGS__ { __VA_ARGS__ *ptr = (__VA_ARGS__ *)0; - int res = pyobj_asptr($input, &ptr); + int res = asptr_meth($input, &ptr); if (!res || !ptr) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = *ptr; - if (res == SWIG_NEWPTR) delete ptr; + if (res == SWIG_NEWOBJ) delete ptr; } %enddef /* directorout */ -%define PYPTR_DIRECTOROUT_TYPEMAP(pyobj_asptr,pyfrag,...) +%define PYPTR_DIRECTOROUT_TYPEMAP(asptr_meth,pyfrag,...) %typemap(directorargout,fragment=pyfrag) __VA_ARGS__ *DIRECTOROUT ($*1_ltype temp) { __VA_ARGS__ *ptr = 0; - int res = pyobj_asptr($input, &ptr); + int res = asptr_meth($input, &ptr); if (!res || !ptr) - throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth"); temp = *ptr; $result = &temp; - if (res == SWIG_NEWPTR) delete ptr; + if (res == SWIG_NEWOBJ) delete ptr; } %typemap(directorout,fragment=pyfrag) __VA_ARGS__ { __VA_ARGS__ *ptr = 0; - int res = pyobj_asptr($input, &ptr); + int res = asptr_meth($input, &ptr); if (!res || !ptr) - throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth"); $result = *ptr; - if (res == SWIG_NEWPTR) delete ptr; + if (res == SWIG_NEWOBJ) delete ptr; } %typemap(directorout,fragment=pyfrag) const __VA_ARGS__& ($*1_ltype temp) { __VA_ARGS__ *ptr = 0; - int res = pyobj_asptr($input, &ptr); + int res = asptr_meth($input, &ptr); if (!res || !ptr) - throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr"); + throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth"); temp = *ptr; $result = &temp; - if (res == SWIG_NEWPTR) delete ptr; + if (res == SWIG_NEWOBJ) delete ptr; } %typemap(directorout,fragment=pyfrag) __VA_ARGS__ &DIRECTOROUT = __VA_ARGS__ %enddef /* typecheck */ -%define PYPTR_TYPECHECK_TYPEMAP(check,pyobj_asptr,pyfrag,...) +%define PYPTR_TYPECHECK_TYPEMAP(check,asptr_meth,pyfrag,...) %typemap(typecheck,precedence=check,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& - "$1 = pyobj_asptr($input, (__VA_ARGS__**)(0));"; + "$1 = asptr_meth($input, (__VA_ARGS__**)(0));"; %enddef /* @@ -80,16 +80,41 @@ */ %define %typemap_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, ...) + %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_NEWOBJ) delete v; + } + return 1; + } + %} + %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; + } + %} PYPTR_IN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); PYPTR_VARIN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); PYPTR_DIRECTOROUT_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__); PYPTR_TYPECHECK_TYPEMAP(SWIG_arg(CheckCode), SWIG_arg(AsPtrMeth), 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__); + %typemap_from(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + + PYPTR_INPUT_TYPEMAP(SWIG_arg(CheckCode),SWIG_arg(AsPtrMeth), + SWIG_arg(AsPtrFrag),__VA_ARGS__); + PYPTR_INOUT_TYPEMAP(__VA_ARGS__); %enddef /* @@ -97,21 +122,6 @@ */ %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_arg(SWIG_AsPtr_meth(__VA_ARGS__)), SWIG_arg(SWIG_From_meth(__VA_ARGS__)), diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index 8e6fcf814..4fd41cd26 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -300,6 +300,7 @@ cobject: return 0; type_error: + PyErr_Clear(); if (flags & SWIG_POINTER_EXCEPTION) { if (ty && c) { PyErr_Format(PyExc_TypeError, diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg index d144bd120..acf7fb3f5 100644 --- a/Lib/python/pystrings.swg +++ b/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 SWIG_OLDPTR; + return SWIG_OLDOBJ; } 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 SWIG_NEWPTR; + return SWIG_NEWOBJ; } } if (cptr || size) { diff --git a/Lib/python/python.swg b/Lib/python/python.swg index 8a055bb22..29c0ab956 100644 --- a/Lib/python/python.swg +++ b/Lib/python/python.swg @@ -31,6 +31,8 @@ /* ----------------------------------------------------------------------------- * Typemap specializations * ----------------------------------------------------------------------------- */ + +%include "pyinout.swg" %include "pyvoid.swg" %include "pyobject.swg" %include "pystrings.swg" diff --git a/Lib/python/pyvaltypes.swg b/Lib/python/pyvaltypes.swg index 8baa7efc4..dfdaf20aa 100644 --- a/Lib/python/pyvaltypes.swg +++ b/Lib/python/pyvaltypes.swg @@ -6,30 +6,30 @@ /* in */ -%define PYVAL_IN_TYPEMAP(pyobj_as,pyfrag,...) +%define PYVAL_IN_TYPEMAP(as_meth,pyfrag,...) %typemap(in,fragment=pyfrag) __VA_ARGS__ - "$1 = ($1_type) pyobj_as($input); + "$1 = ($1_type) as_meth($input); if (PyErr_Occurred()) SWIG_fail;"; %typemap(in,fragment=pyfrag) const __VA_ARGS__ & ($basetype temp) - "temp = ($basetype) pyobj_as($input); + "temp = ($basetype) as_meth($input); if (PyErr_Occurred()) SWIG_fail; $1 = &temp;"; %enddef /* out */ -%define PYVAL_OUT_TYPEMAP(pyobj_from,pyfrag,...) +%define PYVAL_OUT_TYPEMAP(from_meth,pyfrag,...) %typemap(out,fragment=pyfrag) __VA_ARGS__ - "$result = pyobj_from((__VA_ARGS__)$1);"; + "$result = from_meth((__VA_ARGS__)$1);"; %typemap(out,fragment=pyfrag) const __VA_ARGS__& - "$result = pyobj_from((__VA_ARGS__)*($1));"; + "$result = from_meth((__VA_ARGS__)*($1));"; %enddef /* varin */ -%define PYVAL_VARIN_TYPEMAP(pyobj_as,pyfrag,...) +%define PYVAL_VARIN_TYPEMAP(as_meth,pyfrag,...) %typemap(varin,fragment=pyfrag) __VA_ARGS__ { - $1_type temp = ($1_type) pyobj_as($input); + $1_type temp = ($1_type) as_meth($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; @@ -40,48 +40,48 @@ /* varout */ -%define PYVAL_VAROUT_TYPEMAP(pyobj_from,pyfrag,...) +%define PYVAL_VAROUT_TYPEMAP(from_meth,pyfrag,...) %typemap(varout,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& - "$result = pyobj_from((__VA_ARGS__)$1);"; + "$result = from_meth((__VA_ARGS__)$1);"; %enddef /* constant installation code */ -%define PYVAL_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...) +%define PYVAL_CONSTCODE_TYPEMAP(from_meth,pyfrag,...) %typemap(constcode,fragment=pyfrag) __VA_ARGS__ - "PyDict_SetItemString(d,\"$symname\", pyobj_from((__VA_ARGS__)$value));"; + "PyDict_SetItemString(d,\"$symname\", from_meth((__VA_ARGS__)$value));"; %enddef /* directorin */ -%define PYVAL_DIRECTORIN_TYPEMAP(pyobj_from,pyfrag,...) +%define PYVAL_DIRECTORIN_TYPEMAP(from_meth,pyfrag,...) %typemap(directorin,fragment=pyfrag) __VA_ARGS__ *DIRECTORIN - "$input = pyobj_from((__VA_ARGS__)*$1_name);"; + "$input = from_meth((__VA_ARGS__)*$1_name);"; %typemap(directorin,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__& - "$input = pyobj_from((__VA_ARGS__)$1_name);"; + "$input = from_meth((__VA_ARGS__)$1_name);"; %enddef /* directorout */ -%define PYVAL_DIRECTOROUT_TYPEMAP(pyobj_as,pyfrag,...) +%define PYVAL_DIRECTOROUT_TYPEMAP(as_meth,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\");"; + "*$result = ($basetype) as_meth($input); + if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using as_meth\");"; %typemap(directorout,fragment=pyfrag) __VA_ARGS__ - "$result = ($basetype) pyobj_as($input); - if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; + "$result = ($basetype) as_meth($input); + if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using as_meth\");"; %typemap(directorout,fragment=pyfrag) const __VA_ARGS__& - "$basetype temp = ($basetype) pyobj_as($input); + "$basetype temp = ($basetype) as_meth($input); $result = &temp; - if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; + if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using as_meth\");"; %typemap(directorout,fragment=pyfrag) __VA_ARGS__ &DIRECTOROUT = __VA_ARGS__ %enddef /* throws */ -%define PYVAL_THROWS_TYPEMAP(pyobj_from,pyfrag,...) +%define PYVAL_THROWS_TYPEMAP(from_meth,pyfrag,...) %typemap(throws,fragment=pyfrag) __VA_ARGS__ { - PyErr_SetObject(PyExc_RuntimeError, pyobj_from((__VA_ARGS__)$1)); + PyErr_SetObject(PyExc_RuntimeError, from_meth((__VA_ARGS__)$1)); SWIG_fail; } %enddef @@ -104,6 +104,9 @@ 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__); + + PYVAL_INPUT_TYPEMAP(SWIG_arg(CheckCode), SWIG_arg(AsMeth), SWIG_arg(CheckMeth), + SWIG_arg(AsFrag), SWIG_arg(CheckFrag), __VA_ARGS__); %enddef @@ -146,6 +149,9 @@ SWIG_Check_meth(__VA_ARGS__)(PyObject* obj) 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__); + + PYVAL_OUTPUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__); + %enddef @@ -154,6 +160,9 @@ SWIG_Check_meth(__VA_ARGS__)(PyObject* obj) %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__); + + PYVAL_INOUT_TYPEMAP(__VA_ARGS__); + %enddef @@ -166,6 +175,9 @@ SWIG_Check_meth(__VA_ARGS__)(PyObject* obj) %typemap_from(SWIG_arg(SWIG_From_meth(__VA_ARGS__)), SWIG_arg(SWIG_From_frag(__VA_ARGS__)), __VA_ARGS__); + + PYVAL_INOUT_TYPEMAP(__VA_ARGS__); + %enddef diff --git a/Lib/python/std_common.i b/Lib/python/std_common.i index a60660e2c..5b76cd4b7 100644 --- a/Lib/python/std_common.i +++ b/Lib/python/std_common.i @@ -1,5 +1,28 @@ // -// Python implementation +// Define or uncomment the following macro to instantiate by default +// all the basic std typemaps (std::pair, std::vector, etc) +// for all the primitive C++ types (int, double, etc). +// +// Note that this is equivalent to do something similar to +// +// %template() std::vector; +// +// but for all the std and basic C++ types, ie, no wrapping is +// generated for std::vector, only the basic typemaps +// (in, out, typecheck, throw, input, etc.). +// +//#define SWIG_STD_DEFAULT_INSTANTIATION + +// +// Use the following macro to enable the generation of the comparison +// methods, ie, ==, !=, <=, >=, <,>, whenever is needed. +// +#define SWIG_STD_EXTEND_COMPARISON + + +// +// Common code for supporting the STD C++ namespace +// %include pyptrtypes.swg %{ @@ -36,7 +59,7 @@ } %} -%fragment("traits","header") +%fragment("StdTraits","header") %{ namespace swigpy { /* @@ -56,7 +79,6 @@ namespace swigpy { { }; - template inline const char* type_name() { return traits::type_name(); @@ -108,7 +130,6 @@ namespace swigpy { /* Traits that provides the asval/as/check method */ - template struct traits_asptr { typedef Type value_type; @@ -116,13 +137,11 @@ namespace swigpy { 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()); - } + if (res) { + if (val) *val = p; + } else { + PyErr_Format(PyExc_TypeError, "a '%s *' is expected", + type_name()); } return res; } @@ -139,13 +158,15 @@ namespace swigpy { typedef Type value_type; static bool asval(PyObject *obj, value_type *val) { if (val) { - value_type *p; + value_type *p = 0; int res = asptr(obj, &p); - if (res) { + if (res && p) { *val = *p; - if (res == SWIG_NEWPTR) delete p; + if (res == SWIG_NEWOBJ) delete p; + return true; + } else { + return false; } - return res; } else { return asptr(obj, (value_type **)(0)); } @@ -157,7 +178,6 @@ namespace swigpy { return traits_asval::asval(obj, val); } - template struct traits_as { @@ -190,7 +210,7 @@ namespace swigpy { value_type *v = 0; int res = obj ? asptr(obj, &v) : 0; if (res) { - if (res == SWIG_NEWPTR) { + if (res == SWIG_NEWOBJ) { value_type r(*v); delete v; return r; @@ -261,7 +281,6 @@ namespace swigpy { return name.c_str(); } }; - } %} @@ -270,7 +289,7 @@ namespace swigpy { */ %define %traits_swigtype(...) -%fragment(SWIG_Traits_frag(__VA_ARGS__),"header",fragment="traits") { +%fragment(SWIG_Traits_frag(__VA_ARGS__),"header",fragment="StdTraits") { namespace swigpy { template <> struct traits<__VA_ARGS__ > { typedef pointer_category category; @@ -282,14 +301,14 @@ namespace swigpy { /* Generate the traits for a 'primitive' type, such as 'double', - for which the SWIG_AsVal and SWIG_From method are already defined. + for which the SWIG_AsVal and SWIG_From methods 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") { + fragment="StdTraits") { namespace swigpy { template <> struct traits<__VA_ARGS__ > { typedef value_category category; @@ -316,8 +335,7 @@ namespace swigpy { %apply_cpptypes(%traits_ptypen); /* - Generate the typemaps for a class which the traits are - already defined + Generate the typemaps for a class that has 'value' traits */ %define %typemap_traits(Code,...) @@ -332,8 +350,8 @@ namespace swigpy { %enddef /* - Generate the typemaps for a class that behaves more like - a ptr or plain wrapped Swigtype. + Generate the typemaps for a class that behaves more like a 'pointer' or + plain wrapped Swigtype. */ %define %typemap_traits_ptr(Code,...) @@ -345,3 +363,68 @@ namespace swigpy { __VA_ARGS__); %enddef + +/* + Equality methods +*/ +%define %std_equal_methods(...) +%extend __VA_ARGS__ { + bool operator == (const __VA_ARGS__& v) { + return *self == v; + } + + bool operator != (const __VA_ARGS__& v) { + return *self != v; + } +} + +%enddef + +/* + Order methods +*/ + +%define %std_order_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 + +#ifdef SWIG_STD_EXTEND_COMPARISON +%define %std_extcomp(Class,T) + %apply_if(SWIG_EqualType(T), %std_equal_methods(std::Class)) + %apply_if(SWIG_OrderType(T), %std_order_methods(std::Class)) +%enddef +%define %_std_extcomp_2(Class,T,U) + %apply_if2(SWIG_EqualType(T),SWIG_EqualType(U),%std_equal_methods(std::Class)) + %apply_if2(SWIG_OrderType(T),SWIG_EqualType(U),%std_order_methods(std::Class)) +%enddef +%define %std_extcomp_2(Class,T,...) + %_std_extcomp_2(Class,T,__VA_ARGS__) +%enddef +#else +#define %std_extcomp(Class,...) +#define %std_extcomp_2(Class,...) +#endif + +#ifdef SWIG_STD_DEFAULT_INSTANTIATION +#define %std_definst(Class,...) %template() std::Class< __VA_ARGS__ >; +#define %std_definst_2(Class,...) %template() std::Class< __VA_ARGS__ >; +#else +#define %std_definst(Class,...) +#define %std_definst_2(Class,...) +#endif diff --git a/Lib/python/std_complex.i b/Lib/python/std_complex.i index 0a85b67a0..671419d4a 100644 --- a/Lib/python/std_complex.i +++ b/Lib/python/std_complex.i @@ -1,7 +1,7 @@ #ifndef SWIG_STD_COMPLEX_I_ #define SWIG_STD_COMPLEX_I_ -%include "complex_common.i" +%include complex_common.i %{ #include diff --git a/Lib/python/std_container.i b/Lib/python/std_container.i index 4991d656c..1da599e77 100644 --- a/Lib/python/std_container.i +++ b/Lib/python/std_container.i @@ -16,17 +16,6 @@ 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 @@ -67,10 +56,7 @@ %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(); + void push_back(const value_type& x); const value_type& front() const; const value_type& back() const; @@ -112,7 +98,7 @@ // %fragment("StdSequenceTraits","header", - fragment="traits",fragment="PyObject_var", + fragment="StdTraits",fragment="PyObject_var", fragment="PySequence_Cont") %{ namespace swigpy { @@ -134,7 +120,7 @@ sequence *pseq = new sequence(); assign(pyseq, pseq); *seq = pseq; - return SWIG_NEWPTR; + return SWIG_NEWOBJ; } else { return pyseq.check(); } @@ -189,22 +175,3 @@ } %} -%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 7c7e212ac..2ef88df0d 100644 --- a/Lib/python/std_deque.i +++ b/Lib/python/std_deque.i @@ -134,19 +134,13 @@ namespace std { %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__ >; + %std_extcomp(deque, __VA_ARGS__); + %std_definst(deque, __VA_ARGS__); %enddef +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) %apply_cpptypes(%std_deque_ptypen); - +#endif diff --git a/Lib/python/std_list.i b/Lib/python/std_list.i index 68b457c6e..faceb8b67 100644 --- a/Lib/python/std_list.i +++ b/Lib/python/std_list.i @@ -149,19 +149,13 @@ namespace std { %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__ >; + %std_extcomp(list, __VA_ARGS__); + %std_definst(list, __VA_ARGS__); %enddef +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) %apply_cpptypes(%std_list_ptypen); - +#endif diff --git a/Lib/python/std_map.i b/Lib/python/std_map.i index 006a929a7..4e858a633 100644 --- a/Lib/python/std_map.i +++ b/Lib/python/std_map.i @@ -33,15 +33,6 @@ #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 @@ -81,9 +72,10 @@ namespace swigpy { template void assign(const PySeq& pyseq, std::map *map) { + typedef typename std::map::value_type value_type; typename PySeq::const_iterator it = pyseq.begin(); - for (;it != pyseq.end(); ++ it) { - (*map)[it->first] = it->second; + for (;it != pyseq.end(); ++it) { + map->insert(value_type(it->first, it->second)); } } @@ -91,7 +83,6 @@ 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)) { @@ -170,53 +161,13 @@ namespace std { %pydict_methods(SWIG_arg(std::map)); }; - 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; - - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - %traits_swigtype(K); - %traits_swigtype(T); - - %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__ >; +%define %std_map_ptypen(...) + %std_extcomp_2(map, __VA_ARGS__); + %std_definst_2(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); +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) +%apply_cpptypes_2(%std_map_ptypen); +#endif diff --git a/Lib/python/std_multimap.i b/Lib/python/std_multimap.i new file mode 100644 index 000000000..42f13fe67 --- /dev/null +++ b/Lib/python/std_multimap.i @@ -0,0 +1,148 @@ +// +// std::map +// Python implementation + +%include std_map.i + + +%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::multimap +// +// The aim of all that follows would be to integrate std::multimap 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::multimap), f(const std::multimap&): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::multimap can be passed. +// -- f(std::multimap&), f(std::multimap*): +// the parameter may be modified; therefore, only a wrapped std::multimap +// can be passed. +// -- std::multimap f(), const std::multimap& 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::multimap& f(), std::multimap* f(): +// the map is returned by reference; therefore, a wrapped std::multimap +// is returned +// -- const std::multimap* f(), f(const std::multimap*): +// for consistency, they expect and return a plain map pointer. +// ------------------------------------------------------------------------ + + +// exported class + +%fragment("StdMultimapTraits","header",fragment="StdSequenceTraits") +{ + namespace swigpy { + template + void assign(const PySeq& pyseq, std::multimap *multimap) { + typedef typename std::map::value_type value_type; + typename PySeq::const_iterator it = pyseq.begin(); + for (;it != pyseq.end(); ++it) { + multimap->insert(value_type(it->first, it->second)); + } + } + + template + struct traits_asptr > { + typedef std::multimap multimap_type; + typedef K key_type; + + static int asptr(PyObject *obj, multimap_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::multimap multimap_type; + typedef typename multimap_type::const_iterator const_iterator; + typedef typename multimap_type::size_type size_type; + + static PyObject *from(const multimap_type& multimap) { + size_type size = multimap.size(); + int pysize = size <= INT_MAX ? (int) size : 0; + if (!pysize) { + PyErr_SetString(PyExc_OverflowError, + "multimap size not valid in python"); + Py_INCREF(Py_None); + return Py_None; + } + PyObject *obj = PyDict_New(); + for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) { + PyDict_SetItem(obj, + swigpy::from(i->first), + swigpy::from(i->second)); + } + return obj; + } + }; + } +} + +namespace std { + 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; + + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + %traits_swigtype(K); + %traits_swigtype(T); + + %fragment(SWIG_Traits_frag(std::multimap), "header", + fragment=SWIG_Traits_frag(std::pair), + fragment="StdMultimapTraits") { + 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)); + }; +} + +%define %std_multimap_ptypen(...) + %std_extcomp_2(multimap, __VA_ARGS__); + %std_definst_2(multimap, __VA_ARGS__); +%enddef + +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) +%apply_cpptypes_2(%std_multimap_ptypen); +#endif diff --git a/Lib/python/std_multiset.i b/Lib/python/std_multiset.i new file mode 100644 index 000000000..10a141b70 --- /dev/null +++ b/Lib/python/std_multiset.i @@ -0,0 +1,114 @@ +// +// std::set +// Python implementation + +%include std_set.i + +// Multiset + +%define %std_multiset_methods(multiset) + %std_set_methods_common(multiset); + #ifdef SWIG_EXPORT_ITERATOR_METHODS + pair insert(iterator pos); + #endif +%enddef + + +// ------------------------------------------------------------------------ +// std::multiset +// +// The aim of all that follows would be to integrate std::multiset 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::multiset), f(const std::multiset&): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::multiset can be passed. +// -- f(std::multiset&), f(std::multiset*): +// the parameter may be modified; therefore, only a wrapped std::multiset +// can be passed. +// -- std::multiset f(), const std::multiset& 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::multiset& f(), std::multiset* f(): +// the set is returned by reference; therefore, a wrapped std::multiset +// is returned +// -- const std::multiset* f(), f(const std::multiset*): +// for consistency, they expect and return a plain set pointer. +// ------------------------------------------------------------------------ + +%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 { + + //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); + }; + +} + +%define %std_multiset_ptypen(...) + %std_extcomp(multiset, __VA_ARGS__); + %std_definst(multiset, __VA_ARGS__); +%enddef + +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) +%apply_cpptypes(%std_multiset_ptypen); +#endif diff --git a/Lib/python/std_pair.i b/Lib/python/std_pair.i index 0b447a44b..9539664b0 100644 --- a/Lib/python/std_pair.i +++ b/Lib/python/std_pair.i @@ -5,7 +5,7 @@ %} %fragment("StdPairTraits","header", - fragment="traits",fragment="PyObject_var") { + fragment="StdTraits",fragment="PyObject_var") { namespace swigpy { template struct traits_asval > { @@ -79,6 +79,10 @@ namespace std { U second; }; + // *** + // The following specializations should dissapear or get + // simplified when a 'const SWIGTYPE*&' can be defined + // *** template struct pair { typedef T fisrt_type; typedef U* second_type; @@ -104,7 +108,6 @@ namespace std { U* second; }; - template struct pair { typedef T* fisrt_type; typedef U second_type; @@ -124,7 +127,7 @@ namespace std { } } - %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); + %typemap_traits(SWIG_CCode(PAIR), std::pair); T* first; U second; @@ -146,7 +149,7 @@ namespace std { } } - %typemap_traits_ptr(SWIG_CCode(PAIR), std::pair); + %typemap_traits(SWIG_CCode(PAIR), std::pair); T* first; U* second; @@ -154,9 +157,11 @@ namespace std { } -/* - Pairs for all the C++ types -*/ -#define std_pair_ptypen(...) %template() std::pair< __VA_ARGS__ >; +%define %std_pair_ptypen(...) + %std_extcomp_2(pair, __VA_ARGS__); + %std_definst_2(pair, __VA_ARGS__); +%enddef -%apply_cpptypes_2(std_pair_ptypen); +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) +%apply_cpptypes_2(%std_pair_ptypen); +#endif diff --git a/Lib/python/std_set.i b/Lib/python/std_set.i index e96ebf1bb..6e1864352 100644 --- a/Lib/python/std_set.i +++ b/Lib/python/std_set.i @@ -34,14 +34,6 @@ #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 // @@ -96,31 +88,6 @@ } %} -%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 @@ -158,71 +125,13 @@ namespace std { %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__ >; + %std_extcomp(set, __VA_ARGS__); + %std_definst(set, __VA_ARGS__); %enddef +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) %apply_cpptypes(%std_set_ptypen); - -// multiset - -%define %std_multiset_ptypen(...) -%template() std::multiset<__VA_ARGS__ >; -%enddef - -%apply_cpptypes(%std_multiset_ptypen); +#endif diff --git a/Lib/python/std_string.i b/Lib/python/std_string.i index 547fba4fa..6604424ee 100644 --- a/Lib/python/std_string.i +++ b/Lib/python/std_string.i @@ -13,7 +13,7 @@ // ------------------------------------------------------------------------ %include exception.i -%include pycontainer.i +%include std_container.i %{ #include @@ -32,32 +32,20 @@ namespace std { static const size_type npos; - basic_string(); - basic_string(const basic_string& __str); basic_string(const _CharT* __s, size_type __n); // 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); @@ -71,8 +59,6 @@ namespace std { basic_string& append(size_type __n, _CharT __c); - void push_back(_CharT __c); - basic_string& assign(const basic_string& __str); @@ -82,9 +68,6 @@ namespace std { 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); @@ -115,6 +98,13 @@ namespace std { basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c); + %ignore pop_back(); + %ignore front() const; + %ignore back() const; + %ignore basic_string(size_type n); + %std_sequence_methods_val(basic_string); + + %ignore pop(); %pysequence_methods_val(std::basic_string<_CharT>); @@ -157,7 +147,24 @@ namespace std { replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2); #endif }; - + + /* + swig workaround. if used as expected, __iadd__ deletes 'self'. + */ + %newobject basic_string::__iadd__; + %extend basic_string { + std::string* __iadd__(const std::string& v) { + *self += v; + return new std::string(*self); + } + std::string __str__() { + return *self; + } + } + + %std_equal_methods(basic_string); + %std_order_methods(basic_string); + typedef basic_string string; } @@ -169,17 +176,18 @@ namespace std { SWIGSTATICINLINE(int) SWIG_AsPtr_meth(std::basic_string)(PyObject* obj, std::string **val) { - static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string *"); + static swig_type_info* string_info = SWIG_TypeQuery("std::string *"); std::string *vptr; if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) != -1) { if (val) *val = vptr; - return SWIG_OLDPTR; + return SWIG_OLDOBJ; } else { + PyErr_Clear(); 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; + return SWIG_NEWOBJ; } } else { PyErr_Clear(); @@ -203,3 +211,4 @@ SWIGSTATICINLINE(PyObject*) %typemap_asptrfromn(SWIG_CCode(STRING), std::basic_string); + diff --git a/Lib/python/std_vector.i b/Lib/python/std_vector.i index c93972e63..c4fb6a2e1 100644 --- a/Lib/python/std_vector.i +++ b/Lib/python/std_vector.i @@ -109,11 +109,18 @@ namespace std { %pysequence_methods(std::vector); }; + // bool specialization + %extend vector { + void flip() + { + self->flip(); + } + } + // *** - // This especialization should dissapears or - // get simplified when a 'const SWIGTYPE*&' can be - // be defined + // This specialization should dissapear or get simplified when + // a 'const SWIGTYPE*&' can be defined // *** template class vector { public: @@ -144,31 +151,13 @@ namespace std { %std_vector_methods_val(vector); %pysequence_methods_val(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_extcomp(vector, __VA_ARGS__); + %std_definst(vector, __VA_ARGS__); %enddef +#if defined(SWIG_STD_EXTEND_COMPARISON) || defined(SWIG_STD_DEFAULT_INSTANTIATION) %apply_cpptypes(%std_vector_ptypen); - +#endif diff --git a/Lib/python/std_vectora.i b/Lib/python/std_vectora.i index d61a5aceb..6f9045c42 100644 --- a/Lib/python/std_vectora.i +++ b/Lib/python/std_vectora.i @@ -151,24 +151,17 @@ namespace std { %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 { + %extend vector > { void flip() { self->flip(); } } - */ } +#ifdef SWIG_STD_DEFAULT_INSTANTIATION %define %std_vector_ptypen(...) namespace std { @@ -181,14 +174,17 @@ namespace std { // removed (and maybe we will be able to have an unique std_vector.i // definition too). // +#if 1 %apply vector<__VA_ARGS__, std::allocator<__VA_ARGS__ > > { vector<__VA_ARGS__ > } %apply const vector<__VA_ARGS__, std::allocator<__VA_ARGS__ > >& { const vector<__VA_ARGS__ >& } +#endif } %enddef %apply_cpptypes(%std_vector_ptypen); +#endif diff --git a/Lib/python/typemaps.i b/Lib/python/typemaps.i index 39d878e37..4f27b6cd2 100644 --- a/Lib/python/typemaps.i +++ b/Lib/python/typemaps.i @@ -61,41 +61,6 @@ or you can use the %apply directive : */ -%define INPUT_TYPEMAP(type, converter) -%typemap(in) type *INPUT($*1_ltype temp), type &INPUT($*1_ltype temp) -{ - temp = converter($input); - if (PyErr_Occurred()) SWIG_fail; - $1 = &temp; -} -%typemap(typecheck) type *INPUT = type; -%typemap(typecheck) type &INPUT = type; -%enddef - -INPUT_TYPEMAP(float, PyFloat_AsDouble); -INPUT_TYPEMAP(double, PyFloat_AsDouble); -INPUT_TYPEMAP(int, PyInt_AsLong); -INPUT_TYPEMAP(short, PyInt_AsLong); -INPUT_TYPEMAP(long, PyInt_AsLong); -INPUT_TYPEMAP(long long, PyLong_AsLongLong); -INPUT_TYPEMAP(unsigned int, PyInt_AsLong); -INPUT_TYPEMAP(unsigned short, PyInt_AsLong); -INPUT_TYPEMAP(unsigned long, PyInt_AsLong); -INPUT_TYPEMAP(unsigned long long, PyLong_AsUnsignedLongLong); -INPUT_TYPEMAP(unsigned char, PyInt_AsLong); -INPUT_TYPEMAP(signed char, PyInt_AsLong); - -#undef INPUT_TYPEMAP - -%typemap(in) bool *INPUT(bool temp), bool &INPUT(bool temp) -{ - temp = PyInt_AsLong($input) ? true : false; - if (PyErr_Occurred()) SWIG_fail; - $1 = &temp; -} -%typemap(typecheck) bool *INPUT = bool; -%typemap(typecheck) bool &INPUT = bool; - // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. @@ -141,41 +106,6 @@ output values. */ -// These typemaps contributed by Robin Dunn -//---------------------------------------------------------------------- -// -// T_OUTPUT typemap (and helper function) to return multiple argouts as -// a tuple instead of a list. -// -// Author: Robin Dunn -//---------------------------------------------------------------------- - -%include "fragments.i" - -%define OUTPUT_TYPEMAP(type, converter, convtype) -%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"; -%typemap(argout,fragment="t_output_helper") type *OUTPUT, type &OUTPUT { - PyObject *o = converter(convtype (*$1)); - $result = t_output_helper($result,o); -} -%enddef - -OUTPUT_TYPEMAP(int, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(short, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(long, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(long long, PyLong_FromLongLong, ($*1_ltype)); -OUTPUT_TYPEMAP(unsigned int, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(unsigned short, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(unsigned long, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(unsigned long long, PyLong_FromUnsignedLongLong, ($*1_ltype)); -OUTPUT_TYPEMAP(unsigned char, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(signed char, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(bool, PyInt_FromLong, (long)); -OUTPUT_TYPEMAP(float, PyFloat_FromDouble, (double)); -OUTPUT_TYPEMAP(double, PyFloat_FromDouble, (double)); - -#undef OUTPUT_TYPEMAP - // INOUT // Mappings for an argument that is both an input and output // parameter @@ -229,89 +159,32 @@ phased out in future releases. */ -%typemap(in) int *INOUT = int *INPUT; -%typemap(in) short *INOUT = short *INPUT; -%typemap(in) long *INOUT = long *INPUT; -%typemap(in) long long *INOUT = long long *INPUT; -%typemap(in) unsigned *INOUT = unsigned *INPUT; -%typemap(in) unsigned short *INOUT = unsigned short *INPUT; -%typemap(in) unsigned long *INOUT = unsigned long *INPUT; -%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; -%typemap(in) unsigned char *INOUT = unsigned char *INPUT; -%typemap(in) bool *INOUT = bool *INPUT; -%typemap(in) float *INOUT = float *INPUT; -%typemap(in) double *INOUT = double *INPUT; - -%typemap(in) int &INOUT = int &INPUT; -%typemap(in) short &INOUT = short &INPUT; -%typemap(in) long &INOUT = long &INPUT; -%typemap(in) long long &INOUT = long long &INPUT; -%typemap(in) unsigned &INOUT = unsigned &INPUT; -%typemap(in) unsigned short &INOUT = unsigned short &INPUT; -%typemap(in) unsigned long &INOUT = unsigned long &INPUT; -%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; -%typemap(in) unsigned char &INOUT = unsigned char &INPUT; -%typemap(in) bool &INOUT = bool &INPUT; -%typemap(in) float &INOUT = float &INPUT; -%typemap(in) double &INOUT = double &INPUT; - -%typemap(argout) int *INOUT = int *OUTPUT; -%typemap(argout) short *INOUT = short *OUTPUT; -%typemap(argout) long *INOUT = long *OUTPUT; -%typemap(argout) long long *INOUT = long long *OUTPUT; -%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; -%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; -%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; -%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; -%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; -%typemap(argout) bool *INOUT = bool *OUTPUT; -%typemap(argout) float *INOUT = float *OUTPUT; -%typemap(argout) double *INOUT = double *OUTPUT; - -%typemap(argout) int &INOUT = int &OUTPUT; -%typemap(argout) short &INOUT = short &OUTPUT; -%typemap(argout) long &INOUT = long &OUTPUT; -%typemap(argout) long long &INOUT = long long &OUTPUT; -%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; -%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; -%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; -%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; -%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; -%typemap(argout) bool &INOUT = bool &OUTPUT; -%typemap(argout) float &INOUT = float &OUTPUT; -%typemap(argout) double &INOUT = double &OUTPUT; - -/* Overloading information */ - -%typemap(typecheck) double *INOUT = double; -%typemap(typecheck) bool *INOUT = bool; -%typemap(typecheck) signed char *INOUT = signed char; -%typemap(typecheck) unsigned char *INOUT = unsigned char; -%typemap(typecheck) unsigned long *INOUT = unsigned long; -%typemap(typecheck) unsigned long long *INOUT = unsigned long long; -%typemap(typecheck) unsigned short *INOUT = unsigned short; -%typemap(typecheck) unsigned int *INOUT = unsigned int; -%typemap(typecheck) long *INOUT = long; -%typemap(typecheck) long long *INOUT = long long; -%typemap(typecheck) short *INOUT = short; -%typemap(typecheck) int *INOUT = int; -%typemap(typecheck) float *INOUT = float; - -%typemap(typecheck) double &INOUT = double; -%typemap(typecheck) bool &INOUT = bool; -%typemap(typecheck) signed char &INOUT = signed char; -%typemap(typecheck) unsigned char &INOUT = unsigned char; -%typemap(typecheck) unsigned long &INOUT = unsigned long; -%typemap(typecheck) unsigned long long &INOUT = unsigned long long; -%typemap(typecheck) unsigned short &INOUT = unsigned short; -%typemap(typecheck) unsigned int &INOUT = unsigned int; -%typemap(typecheck) long &INOUT = long; -%typemap(typecheck) long long &INOUT = long long; -%typemap(typecheck) short &INOUT = short; -%typemap(typecheck) int &INOUT = int; -%typemap(typecheck) float &INOUT = float; +%include pyinout.swg +#ifdef SWIG_INOUT_NODEF +/* + Apply the INPUT/OUTPUT typemaps to all the C types (int, double) if + not already defined. +*/ +%define %typemap_inout(Code,AsMeth, CheckMeth, FromMeth, AsFrag, CheckFrag, FromFrag, ...) + _PYVAL_INPUT_TYPEMAP(SWIG_arg(Code), SWIG_arg(AsMeth), SWIG_arg(CheckMeth), + SWIG_arg(AsFrag), SWIG_arg(CheckFrag), SWIG_arg(__VA_ARGS__)); + _PYVAL_OUTPUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), SWIG_arg(__VA_ARGS__)); + _PYVAL_INOUT_TYPEMAP(SWIG_arg(__VA_ARGS__)); +%enddef +%define %typemap_inoutn(Code,...) + %typemap_inout(SWIG_arg(Code), + SWIG_arg(SWIG_As_meth(__VA_ARGS__)), + SWIG_arg(SWIG_Check_meth(__VA_ARGS__)), + SWIG_arg(SWIG_From_meth(__VA_ARGS__)), + SWIG_arg(SWIG_As_frag(__VA_ARGS__)), + SWIG_arg(SWIG_Check_frag(__VA_ARGS__)), + SWIG_arg(SWIG_From_frag(__VA_ARGS__)), + SWIG_arg(__VA_ARGS__)); +%enddef +%apply_checkctypes(%typemap_inoutn) +#endif