diff --git a/CHANGES.current b/CHANGES.current index 0a707a918..7c57b7040 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,17 @@ Version 2.0.0 (in progress) ============================ +2010-05-05: wsfulton + [R] Memory leak fix handling const std::string & inputs, reported by Will Nolan. + +2010-05-01: wsfulton + Typemap matching enhancement for non-default typemaps. Previously all + qualifiers were stripped in one step, now they are stripped one at a time + starting with the left most qualifier. For example, int const*const + is first stripped to int *const then int *. + + *** POTENTIAL INCOMPATIBILITY *** + 2010-04-25: bhy [Python] Fix #2985655 - broken constructor renaming. @@ -37,7 +48,7 @@ Version 2.0.0 (in progress) Numerous subtle typemap matching rule fixes when using the default type. The typemap matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc), then look for the next best match by reducing the chosen default type. The type deduction - now follows C++ template partial specialization matching rules. + now follows C++ class template partial specialization matching rules. Below are the set of changes made showing the default type deduction along with the old reduced type and the new version of the reduced type: diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index a99fd1885..242b86429 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -351,6 +351,7 @@
To tell SWIG that 'RCObj' and all its derived classes are reference -counted objects, you use the "ref" and "unref" features, or -%ref and %unref directives (since 1.3.28). For example: +counted objects, you use the "ref" and "unref" features. +For example:
@@ -2143,25 +2143,6 @@ counted objects, you use the "ref" and "unref" features, or -or, using the directive form: - - --%module example -... - -%ref RCObj "$this->ref();" -%unref RCObj "$this->unref();" - -%include "rcobj.h" -%include "A.h" -... --
where the code passed to the "ref" and "unref" features will be executed as needed whenever a new object is passed to python, or when diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 71c2c43ec..76cc770b2 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -33,6 +33,7 @@
-If TYPE includes qualifiers (const, volatile, etc.), they are stripped to form a new stripped type +If TYPE includes qualifiers (const, volatile, etc.), each qualifier is stripped one at a time to form a new stripped type and the matching rules above are repeated on the stripped type. +The left-most qualifier is stripped first, resulting in the right-most (or top-level) qualifier being stripped last. +For example int const*const is first stripped to int *const then int *.
@@ -1056,8 +1059,8 @@ To find a typemap for the argument const char *s, SWIG will search for
const char *s Exact type and name match const char * Exact type match -char *s Type and name match (stripped qualifiers) -char * Type match (stripped qualifiers) +char *s Type and name match (qualifier stripped) +char * Type match (qualifier stripped)@@ -1097,6 +1100,11 @@ void F(int x[1000]); // int [ANY] rule (typemap 5) +
+Compatibility note: SWIG-2.0.0 introduced stripping the qualifiers one step at a time. Prior versions +stripped all qualifiers in one step. +
+@@ -1441,7 +1448,165 @@ but all subsequent arguments must match exactly.
-+For those intimately familiar with C++ templates, a comparison of the typemap matching rules and template type deduction is interesting. +The two areas considered are firstly the default typemaps and their similarities to partial template specialization and secondly, non-default typemaps and their similarities to full template specialization. +
+ ++For default (SWIGTYPE) typemaps the rules are inspired by C++ class template +partial specialization. For example, given partial specialization for T const& : +
+ +
+template <typename T> struct X { void a(); };
+template <typename T> struct X< T const& > { void b(); };
+
++The full (unspecialized) template is matched with most types, such as: +
+ ++X< int & > x1; x1.a(); ++
+and the following all match the T const& partial specialization: +
+ ++X< int *const& > x2; x2.b(); +X< int const*const& > x3; x3.b(); +X< int const& > x4; x4.b(); ++
+Now, given just these two default typemaps, where T is analogous to SWIGTYPE: +
+ +
+%typemap(...) SWIGTYPE { ... }
+%typemap(...) SWIGTYPE const& { ... }
+
++The generic default typemap SWIGTYPE is used with most types, such as +
+ ++int & ++
+and the following all match the SWIGTYPE const& typemap, just like the partial template matching: +
+ ++int *const& +int const*const& +int const& ++
+Note that the template and typemap matching rules are not identical for all default typemaps though, for example, with arrays. +
+ ++For non-default typemaps, one might expect SWIG to follow the fully specialized template rules. +This is nearly the case, but not quite. +Consider a very similar example to the earlier partially specialized template but this time there is a fully specialized template: +
+ +
+template <typename T> struct Y { void a(); };
+template <> struct Y< int const & > { void b(); };
+
++Only the one type matches the specialized template exactly: +
+ ++Y< int & > y1; y1.a(); +Y< int *const& > y2; y2.a(); +Y< int const *const& > y3; y3.a(); +Y< int const& > y4; y4.b(); // fully specialized match ++
+Given typemaps with the same types used for the template declared above, where T is again analogous to SWIGTYPE: +
+ +
+%typemap(...) SWIGTYPE { ... }
+%typemap(...) int const& { ... }
+
++The comparison between non-default typemaps and fully specialized single parameter templates turns out to be the same, as just the one type will match the non-default typemap: +
+ ++int & +int *const& +int const*const& +int const& // matches non-default typemap int const& ++
+However, if a non-const type is used instead: +
+ +
+%typemap(...) SWIGTYPE { ... }
+%typemap(...) int & { ... }
+
++then there is a clear difference to template matching as both the const and non-const types match the typemap: +
+ ++int & // matches non-default typemap int & +int *const& +int const*const& +int const& // matches non-default typemap int & ++
+There are other subtle differences such as typedef handling, but at least it should be clear that the typemap matching rules +are similar to those for specialized template handling. +
+ + +
diff --git a/Examples/test-suite/char_strings.i b/Examples/test-suite/char_strings.i
index 26f3f22a5..cc59815b2 100644
--- a/Examples/test-suite/char_strings.i
+++ b/Examples/test-suite/char_strings.i
@@ -21,7 +21,7 @@ below.
static char *global_str = NULL;
const int UINT_DIGITS = 10; // max unsigned int is 4294967295
-bool check(const char *str, unsigned int number) {
+bool check(const char *const str, unsigned int number) {
static char expected[256];
sprintf(expected, "%s%d", OTHERLAND_MSG, number);
bool matches = (strcmp(str, expected) == 0);
@@ -105,6 +105,18 @@ bool SetConstCharArrayStaticString(const char str[], unsigned int number) {
return check(static_str, number);
}
+bool SetCharConstStaticString(char *const str, unsigned int number) {
+ static char static_str[] = CPLUSPLUS_MSG;
+ strcpy(static_str, str);
+ return check(static_str, number);
+}
+
+bool SetConstCharConstStaticString(const char *const str, unsigned int number) {
+ static char static_str[] = CPLUSPLUS_MSG;
+ strcpy(static_str, str);
+ return check(static_str, number);
+}
+
// get set function
char *CharPingPong(char *str) {
return str;
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 308ff9f1e..831b1b78f 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -387,12 +387,14 @@ CPP_TEST_CASES += \
typedef_scope \
typedef_sizet \
typedef_struct \
+ typemap_delete \
typemap_global_scope \
typemap_namespace \
typemap_ns_using \
typemap_numinputs \
typemap_template \
typemap_out_optimal \
+ typemap_qualifier_strip \
typemap_variables \
typemap_various \
typename \
diff --git a/Examples/test-suite/csharp/char_strings_runme.cs b/Examples/test-suite/csharp/char_strings_runme.cs
index 59bcc64df..414d32b7a 100644
--- a/Examples/test-suite/csharp/char_strings_runme.cs
+++ b/Examples/test-suite/csharp/char_strings_runme.cs
@@ -76,6 +76,16 @@ public class char_strings_runme {
throw new Exception("Test char set 6 failed, iteration " + i);
}
+ for (i=0; i