Version 1.3.28 (unreleased). =========================== 12/30/2005: mmatus - Add option/format support to %rename and %namewarn. Now %namewarn can force renaming, for example: %namewarn("314: import is a keyword",rename="_%s") "import"; and rename can also support format forms: %rename("swig_%s") import; Now, since the format is processed via swig Printf, you can use encoder as follows: %rename("%(title)s") import; -> Import %rename("%(upper)s") import; -> IMPORT %rename("%(lower)s") Import; -> import %rename("%(ctitle)s") camel_case; -> CamelCase This will allow us to add more encoders, as the expected one for regular expressions. - Add the above 'ctitle' encoder, which does the camel case: camel_case -> CamelCase - Also, while we get the regexp support, add the 'command' encoder, you can use it as follows %rename("%(command:sed -e 's/\([a-z]\)/\U\\1/' <<< )s") import; then swig will popen the command "sed -e 's/\([a-z]\)/\U\\1/' <<< import" see below for anonymous renames for better examples. - The rename directive now also allows: - simple match: only apply the rename if a type match happen, for example %rename(%(title)s,match="enumitem") hello; enum Hello { hi, hello -> hi, Hello }; int hello() -> hello; - extended match: only apply the rename if the 'extended attribute' match occurred, for example: // same as simple match %rename(%(title)s,match$nodeType="enumitem") hello; enum Hello { hi, hello -> hi, Hello }; Note that the symbol '$' is used to define the attribute name in a 'recursive' way, for example: // match only hello in 'enum Hello' %rename(%(title)s,match$parentNode$type="enum Hello") hello; enum Hello { hi, hello -> hi, Hello // match }; enum Hi { hi, hello -> hi, hello // no match }; here, for Hello::hi, the "parentNode" is "Hello", and its "type" is "enum Hello". - Anonymous renames: you can use 'anonymous' rename directives, for example: // rename all the enum items in Hello %rename(%(title)s,match$parentNode$type="enum Hello") ""; enum Hello { hi, hello -> Hi, Hello // match both }; enum Hi { hi, hello -> hi, hello // no match }; // rename all the enum items %rename(%(title)s,match$nodeType="enumitem") ""; // rename all the items in given command (sloooow, but...) %rename(%(command:)s) ""; Anonymous renames with commands can be very powerful, since you can 'outsource' all the renaming mechanism (or part of it) to an external program: // Uppercase all (and only) the names that start with 'i' %rename("%(command:awk '/^i/{print toupper($1)}' <<<)s") ""; int imported() -> IMPORTED; int hello() -> hello Note that if the 'command' encoder returns an empty string, swig understand that no rename is necessary. Also note that %rename 'passes' the matched name. For example, in this case namespace ns1 { int foo(); } namespace ns2 { int bar(); } the external program only receives "foo" and "bar". If needed, however, you can request the 'fullname' %rename("%(command:awk 'awk '/ns1::/{l=split($1,a,"::"); print toupper(a[l])}'' <<<)s",fullname=1) ""; ns1::foo -> FOO ns2::bar -> bar - Mixing encoders and matching: of course, you can do mix commands and match fields, for example: %rename("%()",match="cdecl") ""; %rename("%()",match="enumitem") ""; %rename("%()",match="enumitem", match$parentNode$parentNode$nodeType="class") ""; Use "swig -dump_tree" to see the attributes names you can use to match an specific case. 12/30/2005: mmatus - Add initial support for gcj and Java -> mechanism. See examples in: Examples/python/java Examples/ruby/java Examples/tcl/java to see how to use gcj+swig to export java classes into python/ruby/tcl. The idea is to put all the common code for gcj inside Lib/gcj and localize especific issues as jstring, as can be found in Lib/python/jstring.i Lib/ruby/jstring.i Lib/tcl/jstring.i Using the UTL, this is very easy, and the perl version for jstring.i will be next. 12/29/2005: mmatus - Add the copyctor feature/directive to enable the automatic generation of copy constructors. Use as in: %copyctor A; struct A { }; then this will work a1 = A(); a2 = A(a1); Also, since is a feature, if you type just %copyctor; that will enable the automatic generation for all the classes. That is also equivalent to swig -features copyctor -c++ ... Notes: 1.- The feature only works in C++ mode. 2.- The automatic creation of the copy constructor will usually produce overloading. Hence, if the target language doesn't support overloading, a special name will be used (A_copy). 3.- For the same above, probably is not a good idea to use the flag when, for example, in python if you are using keywords. 4.- The copyctor automatic mechanism follows more or less the same rules than the default constructor mechanism, i.e., a copy constructor will not be added if the class is abstract or if there is a pertinent non-public copy ctor in the class or its hierarchy. Hence, it could be necessary for you to complete the class declaration with the proper non-public copy ctor to avoid a wrong constructor addition. - Fix features/rename for templates ctor/dtor and other things around while adding the copyctor mechanism. 12/27/2005: mmatus - Add the 'math' option to typemaps. Assume you have: %typemap(in) SWIGTYPE * (int res) {..} %typemap(freearg) SWIGTYPE * { if (res$argnum) ...} then if you do %typemap(in) A * {...} swig will 'overload the 'in' typemap, but the 'freearg' typemap will be also applied, even when is wrong. The old solutions is to write: %typemap(in) A * {...} %typemap(freeag) A * ""; overload 'freearg' with an empty definition. The problem is, however, there is no way to know you need to do that until you start getting broken C++ code, or worse, broken runtime code. The same applies to the infamous 'typecheck' typemap, which always confuses people, since the first thing you do is just to write the 'in' typemap. Well, the 'match' option solves the problem, and if you write instead %typemap(in) SWIGTYPE * (int res) {..} %typemap(freearg,match="in") SWIGTYPE * { if (res$argnum) ...} %typemap(typecheck,match="in",precedence...) SWIGTYPE * {...} that will tell swig to apply the 'freearg/typecheck' typemaps only if they 'match' the type of the 'in' typemap. The same can be done with other typemaps as: %typemap(directorout) SWIGTYPE * {...} %typemap(directorfree,match="directorout") SWIGTYPE * {...} 12/27/2005: mmatus - Add the 'naturalvar' option/mode/feature to treat member variables in a more natural way, ie, similar to the global variable behavior. If you use swig -naturalvar ... or %module(naturalvar="1") or %naturalvar std::string then, in the following case: std::string s; struct Bar { std::string s; }; you can do: b = Bar() b.s ="hello" cvar.s = "hello" if (b.s != cvar.s): raise RuntimeError This is valid for all the languages, and the implementation is based simply in forcing to use the typemaps const SWIGTYPE& (C++)/SWIGTYPE (C) for the get/set methods instead of the old SWIGTYPE *. Hence, for 'naturalvar' to work, each target language must implement 'typemap(in/out) const Type&' properly. The 'naturalvar' option makes (little dangerous) workarounds such as: %apply(const std::string &) { std::string *} obsoletes. Note1: If your interface has other kind of workarounds to deal with the old 'unnatural' way to deal with member variables (returning/expexting pointers), the 'narturalvar' option could break them. Note2: the option has no effect over unnamed types, such as unnamed nested unions. 12/27/2005: mmatus - Add more 'expressive' result states for the typemap libraries. In the old times, you just check something like: if (ConvertPtr(obj,&vptr,ty,flags) != -1) { // success } else { // error } Now the result state can carry more information, including: - Error state: as the old -1/0, but with error codes from swigerrors.swg. int res = ConvertPtr(obj,&vptr,ty,flags); if (SWIG_IsOK(res)) { // success code } else { SWIG_Error(res); // res carries the error code } - Cast rank: when returning a simple successful conversion, you just return SWIG_OK, but if you need to do a 'cast', you can add the casting rank, ie: if (PyFloat_Check(obj)) { value = PyFloat_AsDouble(obj); return SWIG_OK; } else if (PyInt_Check(obj)) { value = (double) PyInt_AsLong(obj); return SWIG_AddCast(SWIG_OK); } later, the casting rank is used to properly dispatch the overloaded function, for example. This of course requires your language to support and use the new dispatch cast/rank mechanism (Now mainly supported in perl and python, and easily expandable to ruby and tcl). - [UTL] Add support for the new 'expressive' result states. 12/27/2005: mmatus - Add support for the C++ implicit conversion mechanism, which required some modifications in parser.y (to recognize 'explicit') and overload.cxx (to replace $implicitconv as needed). Still, real support in each target language requires to modify each module language. Python provides an example, see bellow. - Add support for native C++ implicit conversions, ie, if you have %implicitconv A; struct A { int ii; A() {ii = 1;} A(int) {ii = 2;} A(double) {ii = 3;} explicit A(char *s) {ii = 4;} }; int get(const A& a) {return a.ii;} you can call: a = A() ai = A(1) ad = A(1.0) as = A("hello") # old forms get(a) -> 1 get(ai) -> 2 get(ad) -> 3 get(as) -> 4 #implicit conversions get(1) -> 2 get(1.0) -> 3 get("hello") -> Error, explicit constructor Also, as in C++, now implicit conversions are supported in variable assigments, and if you have: A ga; struct Bar { A a; }; you can do: cvar.ga = A(1) cvar.ga = 1 cvar.ga = 1.0 cvar.ga = A("hello") cvar.ga = "hello" -> error, explicit constructor b = Bar() b.a = A("hello") b.a = 1 b.a = 1.0 b.a = "hello" -> error, explicit constructor Note that the last case, assigning directly a member var, requires also the 'naturalvar' option. This support now makes the old '%implicit' macro, which was found in 'implicit.i' and it was fragile in many ways, obsolete, and you should use the new '%implicitconv' directive instead. Note that we follow the C++ conventions, ie, in the following the implicit conversion is allowed: int get(A a) {return a.ii;} int get(const A& a) {return a.ii;} but not in this cases: int get(A *a) {return a->ii;} int get(A& a) {return a.ii;} Also, it works for director methods that return a by value result, ie, the following will work: virtual A get_a() = 0; def get_a(self): return 1 but not in this cases: virtual const A& get_a() = 0; virtual A& get_a() = 0; virtual A* get_a() = 0; Notes: - the implicitconv mechanism is implemented by directly calling/dispatching the python constructor, triggering a call to the __init__method. Hence, if you expanded the __init__ method, like in: class A: def __init__(self,args): then 'my code' will also be executed. - Since the %implicitconv directive is based in SWIG features, if you type: %implicitconv; that will enable implicit conversion for all the classes in your module. But if you are worry about performance, maybe that will be too much, especially if you have overloaded methods, since to resolve the dispatching problem, python will efectively try to call all the implicit constructors as needed. - For the same reason, it is highly recommended that you use the new 'castmode' when mixing implicit conversion and overloading. - [python] The %implicit directive is declared obsolete, and you should use %implicitconv instead. If you include the implicit.i file, a warning will remind you this. Note: Since %implicit is fragile, just replacing it by %implicitconv could lead to different behavior. Hence, we don't automatically switch one by the other, and the user must migrate to the new %implicitconv directive manually. 12/26/2005: wsfulton [C#] Modify std::vector wrappers to use std::vector::value_type as this is closer to the real STL declarations for some methods, eg for push_back(). Fixes some compilation errors for some compilers eg when the templated type is a pointer. [Java] std::vector improvements - a few more methods are wrapped and specializations are no longer required. The specialize_std_vector macro is no longer needed (a warning is issued if an attempt is made to use it). 12/26/2005: wsfulton [Java, C#] Add in pointer reference typemaps. This also enables one to easily wrap std::vector where T is a pointer. 12/24/2005: efuzzyone [CFFI] The cffi module for SWIG: - Fully supports C, but provides limited supports for C++, in particular C++ support for templates and overloading needs to be worked upon. 12/23/2005: mmatus [python] Add the castmode that allows the python type casting to occurr. For example, if you have 'int foo(int)', now class Ai(): def __init__(self,x): self.x = x def __int__(self): return self.x foo(1) // Ok foo(1.0) // Ok foo(1.3) // Error a = Ai(4) foo(ai) // Ok The castmode, which can be enable either with the '-castmode' option or the %module("castmode") option, uses the new cast/rank dispatch mechanism. Hence, now if you have 'int foo(int); int foo(double);', the following works as expected: foo(1) -> foo(int) foo(1.0) -> foo(double) ai = Ai(4) foo(ai) -> foo(int) Note1: the 'castmode' could disrupt some specialized typemaps. In particular, the "implicit.i" library seems to have problem with the castmode. But besides that one, the entire test-suite compiles fine with and without the castmode. Note2: the cast mode can't be comnined with the fast dispatch mode, ie, the -fastdispatch option has no effect when the cast mode is selected. The penalties, however, are minimum since the cast dispatch code is already based in the same fast dispatch mechanism. See the file overload_dispatch_cast_runme.py file for new cases and examples. 12/22/2005: mmatus Add the cast and rank mechanism to dispatch overloading functions. The UTF supports it now, but for each language it must be decided how to implement and/or when to use it. [perl] Now perl uses the new cast and rank dispatch mechanism, which solves all the past problems known in perl, such as the old '+ 1' problem: int foo(int); $n = 1 $n = $n + 1 $r = foo(n) also works: foo(1); foo("1"); foo(1.0); foo("1.0"); but fails foo("l"); and when overloading foo(int) and foo(double); foo(1) -> foo(int) foo(1.0) -> foo(double) foo("1") -> foo(int) foo("1.0") -> foo(double) foo("l") -> error foo($n) -> foo(int) for good perl versions foo($n) -> foo(double) for old bad perl versions when overloading foo(int), foo(char*) and foo(double): foo(1) -> foo(int) foo(1.0) -> foo(double) foo("1") -> foo(char*) foo("1.0") -> foo(char*) foo("l") -> foo(char*) Note: In perl the old dispatch mechanism was broken, so, we don't provide and option to enable the old one since, again, was really really broken. See 'overload_simple_runme.pl' for more cases and tests. PS: all the old known issues are declared resolved, any new "problem" that could be discovered is declared, a priori, as "features" of the new dispatch mechanism (until we find another solution at least). *** POTENTIAL INCOMPATIBILITY *** As with the introduction of the UTF, some things could now start to work as expected, and people used to deal or workaround previous bugs related to the dispatch mechanism, could see now a difference in perl behavior. 12/21/2005: mmatus - The '-nodefault' flag (pragma and features) now generates a warning, and recommends to use the explicit -nodefaultctor and -nodefaultdtor options. The reason to split the 'nodefault' behavior is that, in general, ignoring the default destructor generates memory leaks in the target language. Hence, is to risky just to disable the both the default constructor and destructor at the same time. If you need to disable the default destructor, it is also recommended you use the directive form: %nodefaultdtor MyVerySpecialClass; for specific classes, and always avoid using the global -nodefault and -nodefaultdtor options. 12/21/2005: wsfulton [Java, C#] Fix incorrect code generation when the intermediary classname is changed in the module directive from its default. For example: %module(jniclassname="myimclassnewname") "mymodule" // Java %module(imclassname="myimclassnewname") "mymodule" // C# Add in new special variable $imclassname. See docs. 12/17/2005: mmatus [Python] - Add the -aliasobj0/-noaliasobj0 options to use with -fastunpack and/or -O and old typemaps that use 'obj0' directly. So, if you compile your code using -O and get errors about the undeclared 'obj0' variable, run again using swig -O -aliasobj0 -python .... For new typemaps, never use 'obj0' directly, if needed, use the '$self' name that will be properly expanded to 'obj0' (nofastunpack) or 'swig_obj[0]' (fastunpack). If you have no idea what I am talking about, better, that means you have no typemap with this problem. 12/14/2005: mmatus [Python] - Add the -fastunpack/-nofastunpack options to enable/disable the use of the internal UnpackTuple method, instead of calling the one from the python C API. The option -O now also implies -fastunpack. 12/11/2005: mmatus [Python] - Add the -proxydel/-noproxydel options to enable/disable the generation of proxy/shadow __del__ methods, even when now are redundant, since they are empty. However, old interfaces could relay in calling them. The default behavior is to generate the __del__ methods as in 1.3.27 or older swig versions. The option -O now also implies -noproxydel. 12/10/2005: mmatus [UTF] - Fix inneccessary calls to SWIG_TypeQuery for 'char *' and 'wchar_t *', problem found by Clay Culver while profiling the PyOgre project. [Python] - Add the -dirvtable/-nodirvtable to enable/disable a pseudo virtual table used for directors, avoiding to resolv the python method at each call. - Add the -safecstrings/-nosafecstrings options to enable/disable the use of safe conversions from PyString to char *. Python requires you never change the internal buffer directly, and henve 'safectrings' warranties that but returning a copy of the internal python string buffer. The default, as in previous releases, is to return a pointer to the buffer (nosafecstrings), so, is the user responsability to avoid its modification. - Add the -O option to enable all the optimization options at once, initially equivalent to -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual 12/08/2005: mmatus - Add the -fastdispatch option (fastdispatch feature). This enable the "fast dispatch" mechanism for overloaded methods provided by Salvador Fandi~no Garc'ia (#930586). The resulting code is smaller and faster since less type checking are performed. However, the error messages you get when the overloading is not resolved could be different from what the traditional method returns. With the old method you always get an error such as "No matching function for overloaded ..." with the new method you can also get errors such as "Type error in argument 1 of type ..." See bug report #930586 for more details. So, we let to the user the option to enable this optimization. You use this new mechanism as swig -fastdispatch or using the feature form %feature("fastdispatch") method; or %fastdispatch method; 12/06/2005: mmatus - Several memory and speed improvements, specially for templates. Now swig is up to 20 faster than before for large template interfaces, such as the std_containers.i and template_matrix.i files in the python test-suite. Memory footprint is also reduced in consideration of small pcs/architectures. - add options "cpperraswarn/nocpperraswarn" to force the swig preprocessor to treat the #error directive as a #warning. the default behavior is cpperraswarn, so, swig doesn't stop while encountering an #error directive. the pragmas #pragma SWIG cpperraswarn=1 #pragma SWIG cpperraswarn=0 are equivalent to the command line options, respectively. 12/06/2005: mmatus [Python] The generated code is now more portable, specially for Windows. Following http://www.python.org/doc/faq/windows.html Py_None is never accessed as a structure, plus other tricks mentioned there. 12/06/2005: mmatus [Python] Added initial support for threads based in the proposal by Joseph Winston. The user interface is as follows: 1.- the module thread support is enable via the "threads" module option, i.e. %module("threads"=1) 2.- Equivalent to that, is the new '-threads' swig option swig -threads -python ... 3.- You can partially disable thread support for a given method using: %feature("nothread") method; or %nothread method; also, you can disable sections of the thread support, for example %feature("nothreadblock") method; or %nothreadblock method; %feature("nothreadallow") method; or %nothreadallow method; the first disables the C++/python thread protection, and the second disables the python/C++ thread protection. 4.- The current thread support is based in the PyGIL extension present in python version 2.3 or later, but you can provide the thread code for older versions by defining the macros in pythreads.swg. If you get a working implementation for older versions, please send us a patch. For the curious about performance, here are some numbers for the profiletest.i test, which is used to check the speed of the wrapped code: nothread 9.6s (no thread code) nothreadblock 12.2s (only 'allow' code) nothreadallow 13.6s (only 'block' code) full thread 15.5s ('allow' + 'block' code) i.e., full thread code decreases the wrapping performance around 60%. If that is important to your application, you can tune each method using the different 'nothread', 'nothreadblock' or 'nothreadallow' features as needed. Note that for some methods deactivating the 'thread block' or 'thread allow' code is not an option, so, be careful. 11/26/2005: wsfulton SWIG library files use system angle brackets everywhere for %include, eg %include "std_common.i" becomes %include 11/26/2005: wsfulton [Java, C#] Typesafe enums and proper enums have an extra constructor so that enum item values that are initialised by another enum item value can be wrapped without having to use %javaconstvalue/ %csconstvalue for when using %javaconst(1)/%csconst(1). Suggestion by Bob Marinier/Douglas Pearson. For example: typedef enum { xyz, last = xyz } repeat; 11/21/2005: mmatus [ruby + python] Fixes for directors + pointers, ugly problem with not easy solution. Before we identified this case as problematic: virtual const MyClass& my_method(); but it turns out that all the cases where a pointer, array or reference is returned, are problematic, even for primitive types (as int, double, char*, etc). To try to fix the issue, a new typemap was added, 'directorfree', which is used to 'free' the resources allocated during the 'directorout' phase. At the same time, a primitive garbage collector engine was added to deal with orphans addresses, when needed. The situation now is much better, but still you can have memory exaustation if recursion is used. So, still you need to avoid returning pointers, arrays or references when using director methods. - Added stdint.i 11/14/2005: wsfulton More types added to windows.i, eg UINT8, WORD, BYTE etc. Including windows.i will also enable SWIG to parse the __declspec Microsoft extension, eg __declspec(dllimport). Also other Windows calling conventions such as __stdcall. 11/10/2005: wsfulton New library file for Windows - windows.i. This file will contain useful type information for users who include windows.h. Initial support is for the non ISO integral types: __int8, __int16, __int32, __int64 and unsigned versions. The unsigned versions previously could not be parsed by SWIG. SF #872013. 11/09/2005: wsfulton [Java, C#] Portability warning for files which will overwrite each other on case insensitive file systems such as FAT32/NTFS. This will occur, for example, when two class names are the same barring case. The warning is issued on all platforms and can be suppressed with the usual warning suppression techniques. SF bug #1084507. 11/09/2005: wsfulton ./configure --with-python --with-ruby --with-perl5 etc enable these languages, ie the --with-xxxx options, where no path is specified, work the same as if the option was not specified at all. Based on patches #1335042 #1329048 #1329047. 11/09/2005: dancy [Allegrocl] Add C++ support to the Allegrocl module. Further enhances the C support as well. Some of the features: - MUCH better generation of foreign types based on the C/C++ types for use in defining the FFI on the lisp side. We don't pass everything as a (* :void) any longer. - Uses typemaps for better control of type conversions and code generation in the generated lisp and c++ wrapper code. - CLOS wrapping of pointers returned from foreign space makes it easier to differentiate pointers in user code. The wrapping objects can be passed directly to FF calls. - Defun wrapping of FF calls, allowing for more lispy interface. Conversion, GCing, of lisp objects to foreign objects can be done in the wrapping defun via the use of typemaps. - overload dispatching implemented on the lisp side using generic functions. - Templates and synonymous types supported. 11/07/2005: mmatus [Python] Adding proper support for multi-inheritance in the python side, ie, if you have two C++ wrapped class, Foo and Bar, now: class MyPythonClass(Foo,Bar): .... will properly work, even with directors, and the deallocation of Foo.this and Bar.this will follow correctly. Before, since a class can only have one 'this' instance (not as in C++), only the last base class was properly deletted, or detected with directors. Now 'self.this' can be a list, which will contain the C++ instance pointers for all the base classes. Also, swig.this is responsible for deallocating the C++ instance(s), and the __del__ method is not emitted unless the user preppend/append some code to it. - Swig now can detect memory leaks, ie, if you still use the non-shadow module, and type something like import _example f = _example.new_Foo() and forgot to call _example.delete_Foo(f), then swig will tell you that there is a memory leak. Otherwise, if you always use the shadow module, probably you will never ever see this warning unless there is something wrong inside the swig wrapping code. *** POTENTIAL INCOMPATIBILITY *** If you overloaded the __del__ method, and call the base one without a try block, as in class MyClass(SwigClass): def __del__(self): SwigClass.__del__(self) python could complain that the method SwigClass.__del__ is undefined. Try to use instead: def __del__(self): try: SwigClass.__del__(self) except: pass or simply def __del__(self): 11/02/2005: mmatus [Python] Adding more fun to STL/STD containers, now you can do %template(pyset) std::set; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... The same applies to std::list, std::deque, std::multiset, etc. Then, at the python side you can do now: # C++ std::vector as native python sequence v = pyvector([1,"hello",(1,2)]) print v[1] >> 'hello' print v[2] >> (1,2) # C++ std::set as native python sequence s = pyset() s.insert((1,2)) s.insert(1) s.insert("hello") sum=() for i in s: sum +=(i,) print sum >>> (1, 'hello', (1, 2)) # C++ std::map as native python sequence m = pymap() m["foo"] = "hello" m[1] = (1,2) pm = {} for k in m: pm[k] = m[k] print pm >>> {1: (1, 2), 'foo': 'hello'} ie, the STD/STL containers work as real native python container, with arbitrary item types and so. But since normal C++ containers do not properly ref/unref their items, you should use the safer versions: %template(pyset) std::set; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... where swig::PyObject_ptr is a PyObject * envelope class provided to safely incref/decref the python object. So, now you can use all the STL/STD containers as native Python containers. Note 1: std::map, std::set and the other 'ordered' containers will properly use PyObject_Compare for sorting, when needed. Note 2: all the STL/STD containers have a limit size of SIZE_MAX, ie, you can have manage containers larger than INT_MAX, the python limit. 11/02/2005: mmatus [Python] - add 'iterator()' method for all sequences and additionally 'key_iterator()' for maps. 'iterator()' will always return the native C++ iterator. Additionally, in maps, 'key_iterator()' will return a python iterator using only the map keys. In general the sequence method __iter__ will call 'iterator()', returning the native C++ iterator, but in maps it will call 'key_iterator()', maintaining backward compatibility. Hence, for std::maps, you can play then with the native C++ iterator, which value is a (key, value) pair, by calling map.iterator(), as with map.begin(), map.end(), etc. The difference is that map.iterator() returns a safe 'close' iterator, while map.begin() and map.end() are 'open' iterators. A 'close' iterator knows the begin and the end of the sequence, and it never can seg. fault. A 'open' iterator, as in C++, can seg. fault at the C++ side. # a close iterator is safe in the following example. # the next() method will throw a StopIteration # exception as needed i = seq.iterator() try: while True: sum += i.next() except: pass # an open iterator always need to be checked, # or it will crash at the C++ side current = seq.begin() end = seq.end() while (current != end): sum += current.next() [Python] - Finally, when we call f = Foo() the construction is 'one-way'. Before construction was done something like Foo() (python) -> _new_Foo() (C++) new_Foo() (C++) -> FooPtr() (python) FooPtr() (python) -> Foo() (python) and returning a pointer was done like NewPointerObj() (C++) -> FooPtr() (python) FooPtr(python) -> Foo() (python) ie, we when going back and forward between the C++ and python side. Now since there is no FooPtr the construction process is Foo() (python) -> _new_Foo() (C++) _new_Foo() (C++) -> NewPointerObj() (C++) (no shadow class) and returning a pointer is done NewPointerObj() (C++) (with shadow class) -> NewInstaceObj() (C++) where NewInstanceObj creates a new instance without calling __init__ and it doesn't go 'back' to python, is 'pure' C API. - With this change, and the other ones in the PySwigObject type, which now carries the thisown and swig_type_info pointer, the generated code should be as fast as boost::Python and/or the other python wrappers based in pure Python/C API calls. As a reference, the profiletest_runme.py example, which does a simple call function many times, such as this code: import profiletest a = profiletest.A() b = profiletest.B() for i in range(0,1000000) a = b.fn(a) where fn is defined as 'A* B::fn(A *a) {return a;}', produces the following times nomodern modern swig-1.3.26 19.70s 5.98s swig-CVS 0.99s 0.98s Clearly, there is a large improvement for the python 'nomodern' mode. Still, the 'modern' mode is around 6 times faster than before. For the same test, but using the non-shadow version of the module, we get _profiletest (non-shadow) swig-1.3.26 0.80s swig-CVS 0.60s Hence, now for practical porpuses, the proxy overhead is insignificant. Note that the performance numbers we are showing is for a simple module (two types) and a simple function (one argument). For real situations, with modules with many more types and/or functions with many more parameters, you will see even better results. 10/31/2005: mmatus [Python] - Finally, no more ClassPtr shadow classes. You will see only a clean Class shadow class in the .py file. - No more 'real' thisown attribute either, the PySwigObject now carries the ownership info. You can also do something like print self.this.own() >>> True self.this.disown() self.this.own(0) print self.this.own() >>> False self.this.acquire() self.this.own(1) print self.this.own() >>> True Still the old way, print self.thisown >>> True self.thisown = 0 print self.thisown >>> False self.thisown = 1 print self.thisown >>> True is supported, and python dispatch the proper method calls as needed. - Support for iterators in STL/STD containers, for example, if you have %template std::set; you can use the C++ iterators as: s = set_string() s.append("c") s.append("a") s.append("b") b = s.begin() e = s.end() sum = "" while (b != e): sum += b.next() print sum >>> "abc" advance the iterator as in C++ current = s.begin() current += 1 print current.value() >>> "b" now using the reverse operators b = s.rbegin() e = s.rend() sum = "" while (b != e): sum += b.next() print sum >>> "cba" or the 'previous' method b = s.begin() e = s.end() sum = "" while (b != e): sum += e.previous() print sum >>> "cba" or just as in a python fashion for i in s: sum += i Note 1: Iterators in C++ are very powerful, but dangerous too. And in python you can shoot your foot as well as in C++, so, be careful. Note 2: the iterators are 'light', ie, they do not convert sequence elements until you request so, via next(), value() or previous(). If you just increment/decrement one no conversion is performed, for example: b = s.begin() b += 1 b.incr() b.incr(2) b.decr(2) b.decr() b -= 1 only the iterator is modified, and not value wrapper is generated. Other typical C++ operations are also available, such as: print s.end() - s.begin() >>> 3 f = s.begin() + 1 print f.value() >>> "b" l = s.end() - 1 print l.value() >>> "c" etc. Of course, the 'find', 'insert', 'erase', and so on methods also supports iterators now, ie: i = s.begin() i += 1 s.erase(i) for i in s: sum += i print sum >>> "ac" *** POTENTIAL INCOMPATIBILITY *** There is no more 'thisown' attribute. If you use it, python will translate the following code as follows: if (self.thisown): ==> if (self.this.own()): self.thisown = 1 ==> self.this.own(1) self.thisown = 0 ==> self.this.own(0) Still, maybe in some strange case the translation is not 100% secure,so if you have a problem, please report it and/or use the new 'self.this.own()' accessor. *** POTENTIAL INCOMPATIBILITY *** There is no more ClassPtr classes in the python code. Hence, if in the past you needed to resort in some kind of trick to use them, or overcome their presence, it is no longer required, but the extra code you added could now break things arounds. If needed, you can use the option -classptr, i.e., swig -classptr -python ... to generate the old ClassPtr classes. 10/30/2005: mkoeppe [Guile] Make declared and defined linkage of SWIG_init consistent. Reported by Steven G. Johnson (SF patch 1315498). 10/26/2005: mmatus - Added the attribute.i file to the global library director. Now it can be used from other languages that do not use the unified typemap library as well. So, if you have something like: %include attribute.i %attribute(A, int, a, get_a, set_a); struct A { int get_a() const; void set_a(int aa); }; %attribute_ref(B, int, c); struct B { int& c(); }; then in the target language the 'A.a' and 'B.c' attributes will be visible, ie, you can access them as plain variables: f = A() f.a = 3 g = B() g.c = 3 h = f.a + g.c and the proper get/set methods will be dispatched. See attribute.i for more info. - More cleanups around and adding more test-cases. The DISOWN typemap now is tested and working in all the languages that use the unified typemap library, ie, tcl, ruby, perl and python. 10/25/2005: mmatus - Perl, complete the DISOWN typemap. - added the attribute.i file to the unified typemap library (before was only usable from python). - uniform the names for the setter and getter methods in perl,tcl,ruby and python, so, the attribute.i library can work across them. - see the li_attribute.i test-case or the library file Lib/typemaps/attribute.swg for more info about how to use it. 10/24/2005: mmatus - Perl uses now the unified typemap library. - Changes in ruby to use the $track option in typemaps. - Changes in the unified typemap library to follow the convention that all macros that are not used in the C/C++ side starts with %, such as %delete %new_array etc. - Documenting fragments, see fragments.swg. - Cleaner way to use the unified typemap library, include just . Check some of the supported languages: perl, tcl, ruby, python. Always start with the head file, such as python/python.swg tcl/tcl8.swg ruby/ruby.swg perl5/perl5.swg and the principal file that invokes the unified library, such as python/pytypemaps.swg tcl/tcltypemaps.swg ruby/rubytypemaps.swg perl/perltypemaps.swg The file that provide the specialization for each language are the one that provides the basic types: python/pyprimtypes.swg ruby/rubyprimtypes.swg tcl/tclprimtypes.swg perl5/perlprimtypes.swg and the string manipulation: python/pystrings.swg ruby/rubystrings.swg tcl/tclstrings.swg perl5/perlstrings.swg The rest of the files, such as carray.i, are mostly one line files that include the proper typemap library version. *** POTENTIAL INCOMPATIBILITY in Perl *** Some missing/wrong typemaps could start working properly, and change the old expected behavior in Perl. 10/23/2005: wuzzeb Chicken: + pointers to member functions finally work properly + add test of member function pointers to cpp_basic.i 10/20/2005: dancy [allegrocl] Added C++ support. Large update, many changes. See newly added Allegro Common Lisp section in lisp.html 10/20/2005: mmatus Ruby, Tcl, Python: - Uniform way to fail (label fail:), now finally SWIG_exception works across the three languages and all the typemaps. - Add proper cleanup code to ruby - More valgrind fixes - Simplify the inline use, it seems a small interface of 20,000 lines (plus many many templates0 can break gcc -O3 easily. - Finalize the typemaps library. All the old *.i files (carray.i, cpointer.i, exception.i) had been implemented in the new typemaps library. 10/19/2005: wuzzeb Update the Runtime Typemap documentation in Typemaps.html 10/18/2005: wuzzeb Chicken: - Correctly handle %ignored classes - Correctly convert long, long long, unsigned long, etc to chicken primitives. (Thanks to Felix Winkelmann) - Using argout parameters when the return value was a wrapped pointer caused a memory corruption. The chicken garbage collector moved a pointer out from under us. This is now fixed by running all the proxy creation functions as continuations after the wrapper function returns. As part of this, we no longer need the chickenfastproxy flag on output typemaps. - using -proxy and -nocollection together works now Before, it was not exporting the destructor in the proxy wrapper. 10/18/2005: mmatus Unifying the typemaps for python, ruby, tcl and in the process, fix several problems in three languages to work in the "canonical" way now stablished in the typemap library SWIG/Lib/typempas The current status of the unification is that everything compiles and runs inside the test-suite and examples directories. And for the first type we have three languages than pass the primitive_types.i case. Also, we have uniform way to treat the errors, for example if you do something like >>> from primitive_types import * >>> print val_uchar(10) 10 >>> print val_uchar(1000) Traceback (most recent call last): File "", line 1, in ? OverflowError: in argument 1 of type 'unsigned char' you get the same exception in all the three languages. And well, many more good things will come from this unification, as proper support of the STL/STD classes for all the languages, and hopefully, we can keep adding other languages. The hardest part, writting a common typemap library that suites the three different languages, is done, and adding another language it is easy now. Still the global unification is not complete, the STL/STD part is next, and probably adding one or two more languages. If you are curious, look at the python, ruby and/or tcl directories to see what is needed to support the new common typemaps library. Still, the final way to integrate a new language could change as we move to integrate the STD/STL. *** POTENTIAL INCOMPATIBILITY in Ruby/Tcl *** Some missing/wrong typemaps could start working properly, and change the old expected behavior, specially in ruby and tcl.