Salome HOME
Merge branch 'V8_3_BR' into ngr/python3_dev
[modules/yacs.git] / src / engine_swig / engtypemaps.i
1 // Copyright (C) 2006-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 %include std_except.i
21 %include std_string.i
22 %include std_map.i
23 %include std_list.i
24 %include std_vector.i
25 %include std_set.i
26
27 // ----------------------------------------------------------------------------
28
29 %{
30 #include "yacsconfig.h"
31
32 #ifdef OMNIORB
33 #include <omniORB4/CORBA.h>
34
35 #include <omniORBpy.h>
36 omniORBpyAPI* api=0;
37
38 #define OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS \
39 catch (const CORBA::SystemException& ex) { \
40   return api->handleCxxSystemException(ex); \
41 }
42 #else
43 #define OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS 
44 #endif
45
46 #include "Node.hxx"
47 #include "InlineNode.hxx"
48 #include "ComposedNode.hxx"
49 #include "ServiceNode.hxx"
50 #include "ServiceInlineNode.hxx"
51 #include "ServerNode.hxx"
52 #include "Proc.hxx"
53 #include "Bloc.hxx"
54 #include "ForLoop.hxx"
55 #include "WhileLoop.hxx"
56 #include "ForEachLoop.hxx"
57 #include "Switch.hxx"
58 #include "InputPort.hxx"
59 #include "OutputPort.hxx"
60 #include "InPropertyPort.hxx"
61 #include "InputDataStreamPort.hxx"
62 #include "OutputDataStreamPort.hxx"
63 #include "OptimizerLoop.hxx"
64 #include "HomogeneousPoolContainer.hxx"
65
66 #include <sstream>
67
68 class InterpreterUnlocker
69 {
70 public:
71   InterpreterUnlocker() 
72     {
73       _save = PyEval_SaveThread(); // allow Python threads to run
74     }
75   ~InterpreterUnlocker() 
76     {
77       PyEval_RestoreThread(_save); // restore the thread state
78     }
79 private:
80   PyThreadState *_save;
81 };
82
83 static PyObject* convertNode(YACS::ENGINE::Node* node,int owner=0)
84 {
85   if (!node)
86     return SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Node,owner);
87   PyObject * ob;
88   //should use $descriptor(YACS::ENGINE::Bloc *) and so on but $descriptor is not defined here
89   // It is better to define a helper function to avoid code bloat
90   // First try to find a swig type info by its mangled name
91   std::string swigtypename="_p_"+node->typeName();
92   swig_type_info *ret = SWIG_MangledTypeQuery(swigtypename.c_str());
93   if (ret) 
94     ob=SWIG_NewPointerObj((void*)node,ret,owner);
95   else
96     {
97       //typeName not known by swig. Try dynamic_cast on known classes
98       //You must respect inheritance order in casting : Bloc before ComposedNode and so on
99       if(dynamic_cast<YACS::ENGINE::Proc *>(node))
100         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Proc,owner);
101       else if(dynamic_cast<YACS::ENGINE::Bloc *>(node))
102         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Bloc,owner);
103       else if(dynamic_cast<YACS::ENGINE::ForLoop *>(node))
104         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ForLoop,owner);
105       else if(dynamic_cast<YACS::ENGINE::WhileLoop *>(node))
106         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__WhileLoop,owner);
107       else if(dynamic_cast<YACS::ENGINE::ForEachLoop *>(node))
108         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ForEachLoop,owner);
109       else if(dynamic_cast<YACS::ENGINE::Switch *>(node))
110         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Switch,owner);
111       else if(dynamic_cast<YACS::ENGINE::ComposedNode *>(node))
112         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ComposedNode,owner);
113       else if(dynamic_cast<YACS::ENGINE::InlineFuncNode *>(node))
114         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__InlineFuncNode,owner);
115       else if(dynamic_cast<YACS::ENGINE::InlineNode *>(node))
116         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__InlineNode,owner);
117       else if(dynamic_cast<YACS::ENGINE::ServiceInlineNode *>(node))
118         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServiceInlineNode,owner);
119       else if(dynamic_cast<YACS::ENGINE::ServiceNode *>(node))
120         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServiceNode,owner);
121       else if(dynamic_cast<YACS::ENGINE::ServerNode *>(node))
122         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServerNode,owner);
123       else if(dynamic_cast<YACS::ENGINE::ElementaryNode *>(node))
124         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ElementaryNode,owner);
125       else
126         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Node,owner);
127     }
128   return ob;
129 }
130
131 static PyObject* convertPort(YACS::ENGINE::Port* port,int owner=0)
132 {
133   if(!port)
134     return SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__Port, owner);
135   PyObject * ob;
136   std::string swigtypename="_p_"+port->typeName();
137   swig_type_info *ret = SWIG_MangledTypeQuery(swigtypename.c_str());
138   if (ret)
139     {
140       YACS::ENGINE::InPropertyPort *inpropertyport = dynamic_cast<YACS::ENGINE::InPropertyPort*>(port);
141       if(inpropertyport)
142         return SWIG_NewPointerObj((void*)inpropertyport,ret,owner);
143
144       YACS::ENGINE::InputPort *inport = dynamic_cast<YACS::ENGINE::InputPort *>(port);
145       if(inport)
146         return SWIG_NewPointerObj((void*)inport,ret,owner);
147
148       YACS::ENGINE::OutputPort *outport = dynamic_cast<YACS::ENGINE::OutputPort *>(port);
149       if(outport)
150         return SWIG_NewPointerObj((void*)outport,ret,owner);
151
152       YACS::ENGINE::InputDataStreamPort *indsport = dynamic_cast<YACS::ENGINE::InputDataStreamPort *>(port);
153       if(indsport)
154         return SWIG_NewPointerObj((void*)indsport,ret,owner);
155
156       YACS::ENGINE::OutputDataStreamPort *outdsport = dynamic_cast<YACS::ENGINE::OutputDataStreamPort *>(port);
157       if(outdsport)
158         return SWIG_NewPointerObj((void*)outdsport,ret,owner);
159
160       return SWIG_NewPointerObj((void*)port,ret,owner);
161     }
162   else
163     {
164       if(YACS::ENGINE::AnyInputPort *cport =dynamic_cast<YACS::ENGINE::AnyInputPort *>(port))
165         ob=SWIG_NewPointerObj((void*)cport,SWIGTYPE_p_YACS__ENGINE__AnyInputPort,owner);
166       else if(YACS::ENGINE::AnyOutputPort *cport =dynamic_cast<YACS::ENGINE::AnyOutputPort *>(port))
167         ob=SWIG_NewPointerObj((void*)cport,SWIGTYPE_p_YACS__ENGINE__AnyOutputPort,owner);
168       else if(dynamic_cast<YACS::ENGINE::InPropertyPort*>(port))
169         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InPropertyPort,owner);
170       else if(dynamic_cast<YACS::ENGINE::InputPort *>(port))
171         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InputPort,owner);
172       else if(dynamic_cast<YACS::ENGINE::OutputPort *>(port))
173         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutputPort,owner);
174       else if(dynamic_cast<YACS::ENGINE::InputDataStreamPort *>(port))
175         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InputDataStreamPort, owner);
176       else if(dynamic_cast<YACS::ENGINE::OutputDataStreamPort *>(port))
177         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutputDataStreamPort, owner);
178       else if(dynamic_cast<YACS::ENGINE::InPort *>(port))
179         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InPort, owner);
180       else if(dynamic_cast<YACS::ENGINE::OutPort *>(port))
181         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutPort, owner);
182       else if(dynamic_cast<YACS::ENGINE::InGate *>(port))
183         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InGate, owner);
184       else if(dynamic_cast<YACS::ENGINE::OutGate *>(port))
185         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutGate, owner);
186       else
187         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__Port, owner);
188     }
189   return ob;
190 }
191
192 static PyObject *convertContainer(YACS::ENGINE::Container *cont, int owner=0)
193 {
194   if(!cont)
195     return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
196   if(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont))
197     {
198       return SWIG_NewPointerObj((void*)dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont),SWIGTYPE_p_YACS__ENGINE__HomogeneousPoolContainer, owner);
199     }
200   return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
201 }
202
203 //convertFromPyObjVectorOfObj<YACS::ENGINE::SequenceAny *>(pyLi,SWIGTYPE_p_YACS__ENGINE__SequenceAny,"SequenceAny")
204 template<class T>
205 static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector<T>& ret)
206 {
207   void *argp=0;
208   if(PyList_Check(pyLi))
209     {
210       int size=PyList_Size(pyLi);
211       ret.resize(size);
212       for(int i=0;i<size;i++)
213         {
214           PyObject *obj=PyList_GetItem(pyLi,i);
215           int status=SWIG_ConvertPtr(obj,&argp,ty,0|0);
216           if(!SWIG_IsOK(status))
217             {
218               std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : list is excepted to contain only " << typeStr << " instances !";
219               throw YACS::Exception(oss.str());
220             }
221           T arg=reinterpret_cast< T >(argp);
222           ret[i]=arg;
223         }
224     }
225   else if(PyTuple_Check(pyLi))
226     {
227       int size=PyTuple_Size(pyLi);
228       ret.resize(size);
229       for(int i=0;i<size;i++)
230         {
231           PyObject *obj=PyTuple_GetItem(pyLi,i);
232           int status=SWIG_ConvertPtr(obj,&argp,ty,0|0);
233           if(!SWIG_IsOK(status))
234             {
235               std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : tuple is excepted to contain only " << typeStr << " instances !";
236               throw YACS::Exception(oss.str());
237             }
238           T arg=reinterpret_cast< T >(argp);
239           ret[i]=arg;
240         }
241     }
242   else if(SWIG_IsOK(SWIG_ConvertPtr(pyLi,&argp,ty,0|0)))
243     {
244       ret.resize(1);
245       T arg=reinterpret_cast< T >(argp);
246       ret[0]=arg;
247     }
248   else
249     throw YACS::Exception("convertFromPyObjVectorOfObj : not a list nor a tuple");
250 }
251
252 %}
253
254 #if SWIG_VERSION >= 0x010329
255 %template()        std::list<int>;
256 %template()        std::list<std::string>;
257 #else
258
259 #ifdef SWIGPYTHON
260 %typemap(out) std::list<int>
261 {
262   int i;
263   std::list<int>::iterator iL;
264
265   $result = PyList_New($1.size());
266   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
267     PyList_SetItem($result,i,PyLong_FromLong((*iL))); 
268 }
269
270 %typemap(out) std::list<std::string>
271 {
272   int i;
273   std::list<std::string>::iterator iL;
274
275   $result = PyList_New($1.size());
276   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
277     PyList_SetItem($result,i,PyString_FromString((*iL).c_str())); 
278 }
279
280 %typemap(in) std::list<std::string>
281 {
282   /* Check if input is a list */
283   if (PyList_Check($input))
284     {
285       int size = PyList_Size($input);
286       int i = 0;
287       std::list<std::string> myList;
288       $1 = myList;
289       for (i = 0; i < size; i++)
290         {
291           PyObject *o = PyList_GetItem($input,i);
292           if (PyString_Check(o))
293             $1.push_back(std::string(PyString_AsString(PyList_GetItem($input,i))));
294           else
295             {
296               PyErr_SetString(PyExc_TypeError,"list must contain strings");
297               return NULL;
298             }
299         }
300     }
301   else
302     {
303       PyErr_SetString(PyExc_TypeError,"not a list");
304       return NULL;
305     }
306 }
307 #endif
308 #endif
309
310 #ifdef SWIGPYTHON
311
312 %typecheck(SWIG_TYPECHECK_POINTER) YACS::ENGINE::Any*
313 {
314   void *ptr;
315   if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == 0) 
316     $1 = 1;
317   else if (PyInt_Check($input))
318     $1 = 1;
319   else if(PyFloat_Check($input))
320     $1 = 1;
321   else if (PyString_Check($input))
322     $1 = 1;
323   else 
324     $1 = 0;
325 }
326
327 %typemap(in) YACS::ENGINE::Any* (int is_new_object)
328 {
329   if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == 0)
330     {
331       // It is an Any : it is converted by SWIG_ConvertPtr $input -> $1
332       is_new_object=0;
333     }
334   else if (PyInt_Check($input))
335     {
336       // It is an Int
337       $1=YACS::ENGINE::AtomAny::New((int)PyInt_AsLong($input));
338       is_new_object=1;
339     }
340   else if(PyFloat_Check($input))
341     {
342       // It is a Float
343       $1=YACS::ENGINE::AtomAny::New(PyFloat_AsDouble($input));
344       is_new_object=1;
345     }
346   else if(PyString_Check($input))
347     {
348       // It is a Float
349       $1=YACS::ENGINE::AtomAny::New(PyString_AsString($input));
350       is_new_object=1;
351     }
352   else
353     {
354       // It is an error
355       PyErr_SetString(PyExc_TypeError,"not a yacs any or a convertible type");
356       return NULL;
357     }
358 }
359
360 %typemap(directorout) YACS::ENGINE::Any*
361 {
362   if ((SWIG_ConvertPtr($1,(void **) &$result, $1_descriptor,SWIG_POINTER_EXCEPTION)) == 0)
363     {
364       // It is an Any : it is converted by SWIG_ConvertPtr $input -> $1
365     }
366   else if (PyInt_Check($1))
367     {
368       // It is an Int
369       $result=YACS::ENGINE::AtomAny::New((int)PyInt_AsLong($1));
370     }
371   else if(PyFloat_Check($1))
372     {
373       // It is a Float
374       $result=YACS::ENGINE::AtomAny::New(PyFloat_AsDouble($1));
375     }
376   else if(PyString_Check($1))
377     {
378       // It is a String
379       $result=YACS::ENGINE::AtomAny::New(PyString_AsString($1));
380     }
381   else
382     {
383       // It is an error
384       PyErr_SetString(PyExc_TypeError,"not a yacs any or a convertible type");
385       return NULL;
386     }
387 }
388
389 %typemap(freearg) YACS::ENGINE::Any *inSample
390 {
391   //a reference is taken by the routine called
392   if (!is_new_object$argnum) $1->incrRef();
393 }
394
395 %typemap(freearg) YACS::ENGINE::Any*
396 {
397   //no reference taken by the routine called
398   if (is_new_object$argnum) $1->decrRef();
399 }
400
401 %typemap(out) YACS::ENGINE::Any*
402 {
403   if(dynamic_cast<YACS::ENGINE::SequenceAny *>($1))
404     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__SequenceAny,$owner);
405   else if(dynamic_cast<YACS::ENGINE::ArrayAny *>($1))
406     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__ArrayAny,$owner);
407   else if(dynamic_cast<YACS::ENGINE::StructAny *>($1))
408     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__StructAny,$owner);
409   else
410     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__Any,$owner);
411 }
412
413 %typemap(out) YACS::ENGINE::TypeCode*
414 {
415   if(dynamic_cast<YACS::ENGINE::TypeCodeStruct *>($1))
416     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeStruct,$owner);
417   else if(dynamic_cast<YACS::ENGINE::TypeCodeSeq *>($1))
418     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeSeq,$owner);
419   else if(dynamic_cast<YACS::ENGINE::TypeCodeObjref *>($1))
420     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeObjref,$owner);
421   else
422     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCode,$owner);
423 }
424
425 %typemap(in) std::list<YACS::ENGINE::TypeCodeObjref*>
426 {
427   // Check if input is a list 
428   if (PyList_Check($input))
429     {
430       int size = PyList_Size($input);
431       int i = 0;
432       std::list<YACS::ENGINE::TypeCodeObjref*> myList;
433       $1 = myList;
434       for (i = 0; i < size; i++)
435         {
436           PyObject *o = PyList_GetItem($input,i);
437           YACS::ENGINE::TypeCode* temp;
438           if ((SWIG_ConvertPtr(o, (void **) &temp, $descriptor(YACS::ENGINE::TypeCode*),0)) == -1) 
439             {
440               PyErr_SetString(PyExc_TypeError,"not a YACS::ENGINE::TypeCode*");
441               return NULL;
442             }
443           else
444             {
445               if(temp->kind() == YACS::ENGINE::Objref)
446                 $1.push_back((YACS::ENGINE::TypeCodeObjref*)temp);
447               else
448                 {
449                   PyErr_SetString(PyExc_TypeError,"not a YACS::ENGINE::TypeCodeObjref*");
450                   return NULL;
451                 }
452             }
453         }
454     }
455   else
456     {
457       PyErr_SetString(PyExc_TypeError,"not a list");
458       return NULL;
459     }
460 }
461
462 %typemap(out) YACS::ENGINE::Node*
463 {
464   $result=convertNode($1,$owner);
465 }
466
467 %typemap(out) YACS::ENGINE::ServiceNode*
468 {
469   $result=convertNode($1,$owner);
470 }
471
472 %typemap(out) YACS::ENGINE::InlineNode*
473 {
474   $result=convertNode($1,$owner);
475 }
476
477 %typemap(out) YACS::ENGINE::InlineFuncNode*
478 {
479   $result=convertNode($1,$owner);
480 }
481
482 %typemap(out) YACS::ENGINE::ComposedNode*
483 {
484   $result=convertNode($1,$owner);
485 }
486
487 %typemap(out) YACS::ENGINE::OptimizerLoop*
488 {
489   $result=convertNode($1,$owner);
490 }
491
492 %typemap(out) YACS::ENGINE::Proc*
493 {
494   $result=convertNode($1,$owner);
495 }
496
497 %typemap(out) std::set<YACS::ENGINE::Node *>
498 {
499   int i;
500   std::set<YACS::ENGINE::Node *>::iterator iL;
501
502   $result = PyList_New($1.size());
503   PyObject * ob;
504   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
505     {
506       ob=convertNode(*iL);
507       PyList_SetItem($result,i,ob); 
508     }
509 }
510
511 %typemap(out) std::list<YACS::ENGINE::Node *>
512 {
513   int i;
514   std::list<YACS::ENGINE::Node *>::iterator iL;
515
516   $result = PyList_New($1.size());
517   PyObject * ob;
518   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
519     {
520       ob=convertNode(*iL);
521       PyList_SetItem($result,i,ob); 
522     }
523 }
524
525 %typemap(out) YACS::ENGINE::InputPort*,YACS::ENGINE::OutputPort*,YACS::ENGINE::InPort*,YACS::ENGINE::OutPort*,YACS::ENGINE::InPropertyPort*
526 {
527   $result=convertPort($1,$owner);
528 }
529
530 %typemap(out) std::set<YACS::ENGINE::InGate *>
531 {
532   int i;
533   std::set<YACS::ENGINE::InGate *>::iterator iL;
534   $result = PyList_New($1.size());
535   PyObject * ob;
536   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
537     {
538       ob=convertPort(*iL);
539       PyList_SetItem($result,i,ob); 
540     }
541 }
542
543 %typemap(out) std::set<YACS::ENGINE::OutGate *>
544 {
545   int i;
546   std::set<YACS::ENGINE::OutGate *>::iterator iL;
547   $result = PyList_New($1.size());
548   PyObject * ob;
549   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
550     {
551       ob=convertPort(*iL);
552       PyList_SetItem($result,i,ob); 
553     }
554 }
555
556 %typemap(out) std::set<YACS::ENGINE::InPort *>
557 {
558   std::set<YACS::ENGINE::InPort *>::iterator iL;
559   $result = PyList_New(0);
560   PyObject * ob;
561   int status;
562   for (iL=$1.begin(); iL!=$1.end(); iL++)
563     {
564       ob=convertPort(*iL);
565       status=PyList_Append($result,ob);
566       Py_DECREF(ob);
567       if (status < 0)
568         {
569           PyErr_SetString(PyExc_TypeError,"cannot build the inport list");
570           return NULL;
571         }
572     }
573 }
574
575 %typemap(out) std::set<YACS::ENGINE::OutPort *>
576 {
577   std::set<YACS::ENGINE::OutPort *>::iterator iL;
578   $result = PyList_New(0);
579   PyObject * ob;
580   int status;
581   for (iL=$1.begin(); iL!=$1.end(); iL++)
582     {
583       ob=convertPort(*iL);
584       status=PyList_Append($result,ob);
585       Py_DECREF(ob);
586       if (status < 0)
587         {
588           PyErr_SetString(PyExc_TypeError,"cannot build the outport list");
589           return NULL;
590         }
591     }
592 }
593
594 %typemap(out) std::list<YACS::ENGINE::OutPort *>
595 {
596   std::list<YACS::ENGINE::OutPort *>::const_iterator it;
597   $result = PyTuple_New($1.size());
598   int i = 0;
599   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
600     PyTuple_SetItem($result,i,convertPort(*it));
601   }
602 }
603 %typemap(out) std::list<YACS::ENGINE::InPort *>
604 {
605   std::list<YACS::ENGINE::InPort *>::const_iterator it;
606   $result = PyTuple_New($1.size());
607   int i = 0;
608   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
609     PyTuple_SetItem($result,i,convertPort(*it));
610   }
611 }
612 %typemap(out) std::list<YACS::ENGINE::OutputPort *>
613 {
614   std::list<YACS::ENGINE::OutputPort *>::const_iterator it;
615   $result = PyTuple_New($1.size());
616   int i = 0;
617   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
618     PyTuple_SetItem($result,i,convertPort(*it));
619   }
620 }
621 %typemap(out) std::list<YACS::ENGINE::InputPort *>
622 {
623   std::list<YACS::ENGINE::InputPort *>::const_iterator it;
624   $result = PyTuple_New($1.size());
625   int i = 0;
626   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
627     PyTuple_SetItem($result,i,convertPort(*it));
628   }
629 }
630 %typemap(out) std::list<YACS::ENGINE::InPropertyPort*>
631 {
632   std::list<YACS::ENGINE::InPropertyPort *>::const_iterator it;
633   $result = PyTuple_New($1.size());
634   int i = 0;
635   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
636     PyTuple_SetItem($result,i,convertPort(*it));
637   }
638 }
639
640 #endif
641
642 /*
643  * Exception section
644  */
645 // a general exception handler
646 %exception {
647    try 
648    {
649       $action
650    } 
651    catch(YACS::Exception& _e) 
652    {
653       PyErr_SetString(PyExc_ValueError,_e.what());
654       return NULL;
655    } 
656    catch(std::invalid_argument& _e) 
657    {
658       PyErr_SetString(PyExc_IOError ,_e.what());
659       return NULL;
660    } catch (std::domain_error& e) {
661       SWIG_exception(SWIG_ValueError, e.what() );
662    } catch (std::overflow_error& e) {
663       SWIG_exception(SWIG_OverflowError, e.what() );
664    } catch (std::out_of_range& e) {
665       PyErr_SetString(PyExc_KeyError,e.what());
666       return NULL;
667    } catch (std::length_error& e) {
668       SWIG_exception(SWIG_IndexError, e.what() );
669    } catch (std::runtime_error& e) {
670       SWIG_exception(SWIG_RuntimeError, e.what() );
671    }
672    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
673    catch (std::exception& e) {
674       SWIG_exception(SWIG_SystemError, e.what() );
675    }
676    catch(...) 
677    {
678      SWIG_exception(SWIG_UnknownError, "Unknown exception");
679    }
680 }
681
682 // a specific exception handler = generic + release lock
683 %define PYEXCEPTION(name)
684 %exception name {
685    try 
686    {
687       InterpreterUnlocker _l;
688       $action
689    } 
690    catch(YACS::Exception& _e) 
691    {
692       PyErr_SetString(PyExc_ValueError,_e.what());
693       return NULL;
694    }
695    catch(std::invalid_argument& _e) 
696    {
697       PyErr_SetString(PyExc_IOError ,_e.what());
698       return NULL;
699    } catch (std::domain_error& e) {
700       SWIG_exception(SWIG_ValueError, e.what() );
701    } catch (std::overflow_error& e) {
702       SWIG_exception(SWIG_OverflowError, e.what() );
703    } catch (std::out_of_range& e) {
704       PyErr_SetString(PyExc_KeyError,e.what());
705       return NULL;
706    } catch (std::length_error& e) {
707       SWIG_exception(SWIG_IndexError, e.what() );
708    } catch (std::runtime_error& e) {
709       SWIG_exception(SWIG_RuntimeError, e.what() );
710    }
711    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
712    catch (std::exception& e) {
713       SWIG_exception(SWIG_SystemError, e.what() );
714    }
715    catch(...) 
716    {
717      SWIG_exception(SWIG_UnknownError, "Unknown exception");
718    }
719 }
720 %enddef
721
722 %define EXCEPTION(name)
723 %exception name {
724    try 
725    {
726       $action
727    } 
728    catch(YACS::Exception& _e) 
729    {
730       PyErr_SetString(PyExc_ValueError,_e.what());
731       return NULL;
732    }
733    catch(std::invalid_argument& _e) 
734    {
735       PyErr_SetString(PyExc_IOError ,_e.what());
736       return NULL;
737    } catch (std::domain_error& e) {
738       SWIG_exception(SWIG_ValueError, e.what() );
739    } catch (std::overflow_error& e) {
740       SWIG_exception(SWIG_OverflowError, e.what() );
741    } catch (std::out_of_range& e) {
742       PyErr_SetString(PyExc_KeyError,e.what());
743       return NULL;
744    } catch (std::length_error& e) {
745       SWIG_exception(SWIG_IndexError, e.what() );
746    } catch (std::runtime_error& e) {
747       SWIG_exception(SWIG_RuntimeError, e.what() );
748    }
749    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
750    catch (std::exception& e) {
751       SWIG_exception(SWIG_SystemError, e.what() );
752    }
753    catch(...) 
754    {
755      SWIG_exception(SWIG_UnknownError, "Unknown exception");
756    }
757 }
758 %enddef
759 /*
760  * End of Exception section
761  */
762
763 /*
764  * Ownership section
765  */
766 //Release ownership : transfer it to C++
767 %apply SWIGTYPE *DISOWN { YACS::ENGINE::CatalogLoader* factory};
768 %apply SWIGTYPE *DISOWN { YACS::ENGINE::Node *DISOWNnode };
769 %apply SWIGTYPE *DISOWN { Node *DISOWNnode };
770 /*
771  * End of ownership section
772  */
773
774 /*
775  * Reference counting section
776  * reference counted objects are created with a count of 1 so we do not incrRef them on wrapping creation
777  * we only decrRef them on wrapping destruction.
778  * Do not forget to declare them new (%newobject) when they are not returned from a constructor
779  * unless they will not be decrRef on wrapping destruction
780  */
781 %feature("ref")   YACS::ENGINE::RefCounter  ""
782 %feature("unref") YACS::ENGINE::RefCounter  "$this->decrRef();"
783
784 // Unfortunately, class ComponentInstance inherits from RefCounter AND PropertyInterface. Thus the ref and
785 // unref features are ambiguous and with swig 2.0.7 at least, we must re-specify those features for class
786 // ComponentInstance unless the instances are destroyed when the Swig object is unref'ed.
787 %feature("ref")   YACS::ENGINE::ComponentInstance  ""
788 %feature("unref") YACS::ENGINE::ComponentInstance  "$this->decrRef();"
789 /*
790  * End of Reference counting section
791  */
792
793 /*
794 %wrapper %{
795   namespace swig {
796     template <> struct traits_from<YACS::ENGINE::InPort *> {
797       static PyObject *from(YACS::ENGINE::InPort* val){
798         return convertPort(val);
799       }
800     };
801     template <> struct traits_from<YACS::ENGINE::OutPort *> {
802       static PyObject *from(YACS::ENGINE::OutPort* val) {
803         return convertPort(val);
804       }
805     };
806     template <> struct traits_from<YACS::ENGINE::InputPort *> {
807       static PyObject *from(YACS::ENGINE::InPort* val){
808         return convertPort(val);
809       }
810     };
811     template <> struct traits_from<YACS::ENGINE::OutputPort *> {
812       static PyObject *from(YACS::ENGINE::OutPort* val) {
813         return convertPort(val);
814       }
815     };
816   }
817 %}
818 */
819
820 %define REFCOUNT_TEMPLATE(tname, T...)
821 /*
822  This macro is a special wrapping for map with value type which derives from RefCounter.
823  To overload standard SWIG wrapping we define a full specialization of std::map
824  with %extend for 4 basic methods : getitem, setitem, delitem and keys.
825  Then we complete the interface by deriving the shadow wrapper from
826  the python mixin class (UserDict.DictMixin / collections.MutableMapping with Python 3).
827  Do not forget to declare the new shadow class to SWIG with tname_swigregister(tname).
828  Objects returned by __getitem__ are declared new (%newobject) so that when destroyed they
829  call decrRef (see feature("unref") for RefCounter).
830 */
831 template<>
832 class std::map<std::string,T*>
833 {
834 public:
835 %extend
836 {
837   void __setitem__(const std::string& name, T* c)
838     {
839       std::map<std::string, T* >::iterator i = self->find(name);
840       if (i != self->end())
841         {
842           if(c==i->second)
843             return;
844           i->second->decrRef();
845         }
846       (*self)[name]=c;
847       c->incrRef();
848     }
849   T* __getitem__(std::string name)
850     {
851       std::map<std::string, T* >::iterator i = self->find(name);
852       if (i != self->end())
853         {
854           i->second->incrRef();
855           return i->second;
856         }
857       else
858         throw std::out_of_range("key not found");
859     }
860   void __delitem__(std::string name)
861     {
862       std::map<std::string, T* >::iterator i = self->find(name);
863       if (i != self->end()){
864         i->second->decrRef();
865         self->erase(i);
866       }
867       else
868         throw std::out_of_range("key not found");
869     }
870   PyObject* keys() {
871       int pysize = self->size();
872       PyObject* keyList = PyList_New(pysize);
873       std::map<std::string, T* >::const_iterator i = self->begin();
874       for (int j = 0; j < pysize; ++i, ++j) {
875         PyList_SET_ITEM(keyList, j, PyString_FromString(i->first.c_str()));
876       }
877       return keyList;
878     }
879 }
880 };
881
882 %newobject std::map<std::string,T* >::__getitem__;
883 %template()   std::pair<std::string, T* >;
884 %template(tname)    std::map<std::string, T* >;
885 %pythoncode{
886 from collections import MutableMapping    
887 class tname(tname,MutableMapping):pass
888 tname##_swigregister(tname)
889 }
890 %enddef
891
892