1 /* ------------------------------------------------------------------------- 2 * Special user directives 3 * ------------------------------------------------------------------------- */ 4 5 /* ------------------------------------------------------------------------- */ 6 7 /* shadow code */ 8 #define %shadow %insert("shadow") 9 #define %pythoncode %insert("python") 10 #define %pythonbegin %insert("pythonbegin") 11 12 13 /* ------------------------------------------------------------------------- */ 14 /* 15 Use the "nondynamic" feature to make a wrapped class behave as a "nondynamic" 16 one, ie, a python class that doesn't dynamically add new attributes. 17 18 For example, for the class 19 20 %pythonnondynamic A; 21 struct A 22 { 23 int a; 24 int b; 25 }; 26 27 you will get: 28 29 aa = A() 30 aa.a = 1 # Ok 31 aa.b = 1 # Ok 32 aa.c = 3 # error 33 34 Since nondynamic is a feature, if you use it like 35 36 %pythonnondynamic; 37 38 it will make all the wrapped classes nondynamic ones. 39 40 The implementation is based on this recipe: 41 42 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252158 43 44 and works for modern (-modern) and plain python. We do not use __slots__, 45 so, it works with old python versions. 46 47 */ 48 49 #define %pythonnondynamic %feature("python:nondynamic", "1") 50 #define %nopythonnondynamic %feature("python:nondynamic", "0") 51 #define %clearpythonnondynamic %feature("python:nondynamic", "") 52 #define %pythondynamic %nopythonnondynamic 53 54 55 /* ------------------------------------------------------------------------- */ 56 /* 57 58 Use %pythonmaybecall to flag a method like __add__ or __radd__. These 59 don't produce an error when called, they just return NotImplemented. 60 61 These methods "may be called" if needed. 62 63 */ 64 65 #define %pythonmaybecall %feature("python:maybecall", "1") 66 #define %nopythonmaybecall %feature("python:maybecall", "0") 67 #define %clearpythonmaybecall %feature("python:maybecall", "") 68 69 /* ------------------------------------------------------------------------- */ 70 /* 71 The %pythoncallback feature produce a more natural callback wrapper 72 than the %callback mechanism, ie, it uses the original name for 73 the callback and callable objects. 74 75 Just use it as 76 77 %pythoncallback(1) foo; 78 int foo(int a); 79 80 %pythoncallback(1) A::foo; 81 struct A { 82 static int foo(int a); 83 }; 84 85 int bar(int, int (*pf)(int)); 86 87 then, you can use it as: 88 89 a = foo(1) 90 b = bar(2, foo) 91 92 c = A.foo(3) 93 d = bar(4, A.foo) 94 95 96 If you use it with a member method 97 %pythoncallback(1) A::foom; 98 struct A { 99 int foom(int a); 100 }; 101 102 then you can use it as 103 104 r = a.foom(3) # eval the method 105 mptr = A.foom_cb_ptr # returns the callback pointer 106 107 where the '_cb_ptr' suffix is added for the callback pointer. 108 109 */ 110 111 #define %pythoncallback %feature("python:callback") 112 #define %nopythoncallback %feature("python:callback","0") 113 #define %clearpythoncallback %feature("python:callback","") 114 115 /* ------------------------------------------------------------------------- */ 116 /* 117 Support for the old %callback directive name 118 */ 119 #ifdef %callback 120 #undef %callback 121 #endif 122 123 #ifdef %nocallback 124 #undef %nocallback 125 #endif 126 127 #ifdef %clearcallback 128 #undef %clearcallback 129 #endif 130 131 #define %callback(x) %feature("python:callback",`x`) 132 #define %nocallback %nopythoncallback 133 #define %clearcallback %clearpythoncallback 134 135 /* ------------------------------------------------------------------------- */ 136 /* 137 Thread support - Advance control 138 139 */ 140 141 #define %nothread %feature("nothread") 142 #define %thread %feature("nothread","0") 143 #define %clearnothread %feature("nothread","") 144 145 #define %nothreadblock %feature("nothreadblock") 146 #define %threadblock %feature("nothreadblock","0") 147 #define %clearnothreadblock %feature("nothreadblock","") 148 149 #define %nothreadallow %feature("nothreadallow") 150 #define %threadallow %feature("nothreadallow","0") 151 #define %clearnothreadallow %feature("nothreadallow","") 152 153 154 /* ------------------------------------------------------------------------- */ 155 /* 156 Implicit Conversion using the C++ constructor mechanism 157 */ 158 159 #define %implicitconv %feature("implicitconv") 160 #define %noimplicitconv %feature("implicitconv", "0") 161 #define %clearimplicitconv %feature("implicitconv", "") 162 163 164 /* ------------------------------------------------------------------------- */ 165 /* 166 Enable keywords paramaters 167 */ 168 169 #define %kwargs %feature("kwargs") 170 #define %nokwargs %feature("kwargs", "0") 171 #define %clearkwargs %feature("kwargs", "") 172 173 /* ------------------------------------------------------------------------- */ 174 /* 175 Add python code to the proxy/shadow code 176 177 %pythonprepend - Add code before the C++ function is called 178 %pythonappend - Add code after the C++ function is called 179 */ 180 181 #define %pythonprepend %feature("pythonprepend") 182 #define %clearpythonprepend %feature("pythonprepend","") 183 184 #define %pythonappend %feature("pythonappend") 185 #define %clearpythonappend %feature("pythonappend","") 186 187 188 189 /* ------------------------------------------------------------------------- */ 190 /* 191 %extend_smart_pointer extend the smart pointer support. 192 193 For example, if you have a smart pointer as: 194 195 template <class Type> class RCPtr { 196 public: 197 ... 198 RCPtr(Type *p); 199 Type * operator->() const; 200 ... 201 }; 202 203 you use the %extend_smart_pointer directive as: 204 205 %extend_smart_pointer(RCPtr<A>); 206 %template(RCPtr_A) RCPtr<A>; 207 208 then, if you have something like: 209 210 RCPtr<A> make_ptr(); 211 int foo(A *); 212 213 you can do the following: 214 215 a = make_ptr(); 216 b = foo(a); 217 218 ie, swig will accept a RCPtr<A> object where a 'A *' is 219 expected. 220 221 Also, when using vectors 222 223 %extend_smart_pointer(RCPtr<A>); 224 %template(RCPtr_A) RCPtr<A>; 225 %template(vector_A) std::vector<RCPtr<A> >; 226 227 you can type 228 229 a = A(); 230 v = vector_A(2) 231 v[0] = a 232 233 ie, an 'A *' object is accepted, via implicit conversion, 234 where a RCPtr<A> object is expected. Additionally 235 236 x = v[0] 237 238 returns (and sets 'x' as) a copy of v[0], making reference 239 counting possible and consistent. 240 */ 241 242 %define %extend_smart_pointer(Type...) 243 %implicitconv Type; 244 %apply const SWIGTYPE& SMARTPOINTER { const Type& }; 245 %apply SWIGTYPE SMARTPOINTER { Type }; 246 %enddef 247