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