1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
%module python_typemap_macro
/*
This testcase pushes $typemap() to the limit, but does show how the UTL could be replaced with a different approach.
It results in very bloated code as all the typemaps expanded by $typemap() are inline and recursive use such as with
containers of containers or pairs of pairs demonstrated here.
The other gotcha using this approach is using local variables declared within the typemap body does not usually work
if the typemaps are recursively called and the temporary variables are used for typemap outputs, such as $1 or $result.
Using typemap temporary variables does work around this, such as temp in:
%typemap(out) (int temp) { ... }
This works as each typemap temporary is renamed and given a unique numeric suffix, for example temp1, temp2.
Consider this approach to using typemaps experimental and use at your own risk!
*/
%include <std_string.i>
#if 0
%include <std_pair.i>
#else
namespace std {
template <class T, class U > struct pair {
// Adaption of PyObject *swig::traits_from<std::pair<T,U> >::from((const std::pair<T,U>& val)) in Lib/python/std_pair.i
%typemap(out) pair(PyObject *resultobj_pair_first, PyObject *resultobj_pair_second) {
/* pair out $1_type start */
$result = PyTuple_New(2);
$typemap(out, T, 1=$1.first, result=resultobj_pair_first)
PyTuple_SetItem($result, 0, resultobj_pair_first);
$typemap(out, U, 1=$1.second, result=resultobj_pair_second)
PyTuple_SetItem($result, 1, resultobj_pair_second);
/* pair out $1_type end */
}
// Adaption of int traits_asptr<std::pair<T,U> >::asptr(PyObject *obj, std::pair<T,U> **val) in Lib/python/std_pair.i
%typemap(in) pair {
/* pair in $1_type start */
PyObject *obj = $input;
if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == 2) {
PyObject *first = PyTuple_GET_ITEM(obj, 0);
PyObject *second = PyTuple_GET_ITEM(obj, 1);
$typemap(in, T, input=first, 1=$1.first)
$typemap(in, U, input=second, 1=$1.second)
} else if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
swig::SwigVar_PyObject first = PySequence_GetItem(obj, 0);
swig::SwigVar_PyObject second = PySequence_GetItem(obj, 1);
$typemap(in, T, input=(PyObject*)first, 1=$1.first)
$typemap(in, U, input=(PyObject*)second, 1=$1.second)
} else {
void *argp;
int res = SWIG_ConvertPtr($input, &argp, $&descriptor, 0);
if (!SWIG_IsOK(res)) {
%argument_fail(res, "$type", $symname, $argnum);
}
if (!argp) {
%argument_nullref("$type", $symname, $argnum);
} else {
$<ype temp = %reinterpret_cast(argp, $<ype);
$1 = *temp;
if (SWIG_IsNewObj(res)) %delete(temp);
}
}
/* pair in $1_type end */
}
%typemap(typecheck) pair {
/* pair typecheck $1_type start */
PyObject *obj = $input;
if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == 2) {
PyObject *first = PyTuple_GET_ITEM(obj, 0);
PyObject *second = PyTuple_GET_ITEM(obj, 1);
$typemap(typecheck, T, input=first)
if ($1) {
$typemap(typecheck, U, input=second)
}
} else if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
swig::SwigVar_PyObject first = PySequence_GetItem(obj, 0);
swig::SwigVar_PyObject second = PySequence_GetItem(obj, 1);
$typemap(typecheck, T, input=(PyObject*)first)
if ($1) {
$typemap(typecheck, U, input=(PyObject*)second)
}
} else {
void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res);
}
/* pair typecheck $1_type end */
}
typedef T first_type;
typedef U second_type;
pair();
pair(T first, U second);
// pair(const pair& other); // TODO: similar typemaps for pair&
pair(pair other);
template <class U1, class U2> pair(const pair< U1, U2 > &other);
T first;
U second;
};
}
#endif
%template(PairStringInt) std::pair<std::string, int>;
%template(PairCharPairStringInt) std::pair<char, std::pair<std::string, int> >;
%inline %{
std::pair<std::string, int> PairInputOutput(std::pair<std::string, int> ppp) {
return ppp;
}
std::pair<char, std::pair<std::string, int> > PairInputOutput2(std::pair<char, std::pair<std::string, int> > p) {
return p;
}
std::pair<char, std::pair<std::string, int> > MakePair() {
return std::pair<char, std::pair<std::string, int> >('x', std::pair<std::string, int>("outstring", 111));
}
/*
*/
%}
|