summaryrefslogtreecommitdiff
path: root/Doc
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2022-11-18 18:49:48 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-11-18 19:35:47 +0000
commit4729cf2b1f44e57f46d13758009b10cec5af47b6 (patch)
tree67e0c94bf8f89539c4008c11624b22779c1240c5 /Doc
parent777fd2c280fbeb0dea79d900f115369bc2295f65 (diff)
downloadswig-4729cf2b1f44e57f46d13758009b10cec5af47b6.tar.gz
Duplicate class template instantiations via %template changes
Named duplicate class template instantiations now issue a warning and are ignored. Duplicate empty class template instantiations are quietly ignored. The test cases are fixed for this new behaviour. This commit is a pre-requisite for the near future so that the Python builtin wrappers can correctly use the SwigType_namestr function without generating duplicate symbol names.
Diffstat (limited to 'Doc')
-rw-r--r--Doc/Manual/Contents.html1
-rw-r--r--Doc/Manual/SWIGPlus.html139
-rw-r--r--Doc/Manual/Warnings.html1
3 files changed, 110 insertions, 31 deletions
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index fd74ab299..cecd54958 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -260,6 +260,7 @@
<li><a href="SWIGPlus.html#SWIGPlus_template_functions">Function templates</a>
<li><a href="SWIGPlus.html#SWIGPlus_template_classes">Default template arguments</a>
<li><a href="SWIGPlus.html#SWIGPlus_template_class_inheritance">Template base classes</a>
+<li><a href="SWIGPlus.html#SWIGPlus_template_empty">Empty template instantiation</a>
<li><a href="SWIGPlus.html#SWIGPlus_template_specialization">Template specialization</a>
<li><a href="SWIGPlus.html#SWIGPlus_template_member">Member templates</a>
<li><a href="SWIGPlus.html#SWIGPlus_template_scoping">Scoping and templates</a>
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index b4b9acb17..cc33d6152 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -57,6 +57,7 @@
<li><a href="#SWIGPlus_template_functions">Function templates</a>
<li><a href="#SWIGPlus_template_classes">Default template arguments</a>
<li><a href="#SWIGPlus_template_class_inheritance">Template base classes</a>
+<li><a href="#SWIGPlus_template_empty">Empty template instantiation</a>
<li><a href="#SWIGPlus_template_specialization">Template specialization</a>
<li><a href="#SWIGPlus_template_member">Member templates</a>
<li><a href="#SWIGPlus_template_scoping">Scoping and templates</a>
@@ -3261,10 +3262,28 @@ void foo(List&lt;Integer&gt; *x);
In this case, <tt>List&lt;Integer&gt;</tt> is exactly the same type as
<tt>List&lt;int&gt;</tt>. Any use of <tt>List&lt;Integer&gt;</tt> is mapped back to the
instantiation of <tt>List&lt;int&gt;</tt> created earlier. Therefore, it is
-not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
-redundant and will simply result in code bloat).
+not correct to instantiate a new class for the type <tt>Integer</tt>.
+An attempt to do so such as:
</p>
+<div class="code">
+<pre>
+%template(intList) List&lt;int&gt;;
+%template(IntegerList) List&lt;Integer&gt;; // Ignored
+</pre>
+</div>
+
+<p>
+will result in the duplicate instantiation being ignored with a warning:
+</p>
+
+<div class="shell">
+<pre>
+example.i:48: Warning 404: Duplicate template instantiation of 'List&lt; Integer &gt;' with name 'IntegerList' ignored,
+example.i:47: Warning 404: previous instantiation of 'List&lt; int &gt;' with name 'intList'.
+</pre>
+</div>
+
<p>
The template provided to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
</p>
@@ -3333,36 +3352,49 @@ original template definition. Template default arguments are supported. For ex
<div class="code">
<pre>
-template vector&lt;typename T, int max=100&gt; class vector {
+template &lt;typename T, int max=100&gt; class vector {
...
};
-%template(intvec) vector&lt;int&gt;; // OK
+%template(intvec) vector&lt;int&gt;; // OK
%template(vec1000) vector&lt;int, 1000&gt;; // OK
</pre>
</div>
<p>
The <tt>%template</tt> directive should not be used to wrap the same
-template instantiation more than once in the same scope. This will
-generate an error. For example:
+template instantiation more than once. This also applies to default parameters
+where a template parameter specified in the instantiation is the same as the default parameter.
+For example:
</p>
<div class="code">
<pre>
-%template(intList) List&lt;int&gt;;
-%template(Listint) List&lt;int&gt;; // Error. Template already wrapped.
+%template(vec) vector&lt;double&gt;; // OK
+%template(vec100) vector&lt;double, 100&gt;; // Ignored
</pre>
</div>
<p>
-This error is caused because the template expansion results in two
-identical classes with the same name. This generates a symbol table
-conflict. Besides, it probably more efficient to only wrap a specific
-instantiation only once in order to reduce the potential for code
-bloat.
+will warn:
</p>
+<div class="shell">
+<pre>
+example.i:59: Warning 404: Duplicate template instantiation of 'vector&lt; double,100 &gt;' with name 'vec100' ignored,
+example.i:58: Warning 404: previous instantiation of 'vector&lt; double &gt;' with name 'vec'.
+</pre>
+</div>
+
+<p>
+If this was not ignored, the template expansion would result in two identical classes.
+An identical instantiation is only wrapped once in order to reduce code bloat.
+</p>
+
+<p>
+<b>Compatibility Note</b>: Versions prior to SWIG-4.2.0 would sometimes not detect and prevent duplicate
+instantiations, such as when the wrapped name was different.
+</p>
<H3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base classes</a></H3>
@@ -3430,20 +3462,6 @@ Don't worry--if you get the order wrong, SWIG should generate a warning message.
</p>
<p>
-Occasionally, you may need to tell SWIG about base classes that are defined by templates,
-but which aren't supposed to be wrapped. Since SWIG is not able to automatically
-instantiate templates for this purpose, you must do it manually. To do this, simply
-use the empty template instantiation, that is, <tt>%template</tt> with no name. For example:
-</p>
-
-<div class="code">
-<pre>
-// Instantiate traits&lt;double, double&gt;, but don't wrap it.
-%template() traits&lt;double, double&gt;;
-</pre>
-</div>
-
-<p>
If you have to instantiate a lot of different classes for many different types,
you might consider writing a SWIG macro. For example:
</p>
@@ -3468,7 +3486,66 @@ TEMPLATE_WRAP(PairStringInt, std::pair&lt;string, int&gt;)
Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
</p>
-<H3><a name="SWIGPlus_template_specialization">6.18.5 Template specialization</a></H3>
+<H3><a name="SWIGPlus_template_empty">6.18.5 Empty template instantiation</a></H3>
+
+
+<p>
+Occasionally, you may need to tell SWIG about classes that are defined by templates,
+but which aren't supposed to be wrapped. Since SWIG is not able to automatically
+instantiate templates for this purpose, you must do it manually. To do this, simply
+use <tt>%template()</tt>, that is the empty template instantiation that omits providing a name. For example:
+</p>
+
+<div class="code">
+<pre>
+template&lt;typename T&gt; struct Traits {
+ typedef T type;
+};
+%}
+
+%template() Traits&lt;int&gt;; // instantiate Traits&lt;int&gt;, but don't wrap it
+
+void traitor(Traits&lt;int&gt;::type val);
+</pre>
+</div>
+
+<p>
+Without a template instantiation, SWIG does not know that the first parameter to the <tt>traitor</tt>
+function is type int and passing an integer to this function from any target language won't work.
+The empty template instantiation adds the appropriate type information into SWIG's type system, without
+forcing one to wrap the <tt>Traits</tt> class.
+</p>
+
+<p>
+Duplicate template instantiation are not allowed, as described in the
+<a href="#SWIGPlus_template_classes">Default template arguments</a> section above.
+There is one exception where a named template instantiation can be followed by an empty template instantiation.
+Duplicate empty template instantiations are silently ignored, unlike duplicate named template instantiations.
+</p>
+
+<p>
+Unlike template class instantiations, template function instantiations must have a name.
+Consider the following:
+</p>
+
+<div class="code">
+<pre>
+template&lt;class T&gt; T tfunc(T x) { };
+%template() tfunc&lt;double&gt;;
+</pre>
+</div>
+
+<p>
+The empty template instantiation will be ignored with:
+</p>
+
+<div class="shell">
+<pre>
+example.i:9: Warning 519: %template() contains no name. Template method ignored: tfunc&lt; double &gt;(double)
+</pre>
+</div>
+
+<H3><a name="SWIGPlus_template_specialization">6.18.6 Template specialization</a></H3>
<p>
@@ -3558,7 +3635,7 @@ SWIG implements template argument deduction so that the following partial specia
</pre>
</div>
-<H3><a name="SWIGPlus_template_member">6.18.6 Member templates</a></H3>
+<H3><a name="SWIGPlus_template_member">6.18.7 Member templates</a></H3>
<p>
@@ -3770,7 +3847,7 @@ constructor, that will dispatch the proper call depending on the argument
type.
</p>
-<H3><a name="SWIGPlus_template_scoping">6.18.7 Scoping and templates</a></H3>
+<H3><a name="SWIGPlus_template_scoping">6.18.8 Scoping and templates</a></H3>
<p>
@@ -3871,7 +3948,7 @@ template class C&lt;int&gt;;
</p>
-<H3><a name="SWIGPlus_template_more">6.18.8 More on templates</a></H3>
+<H3><a name="SWIGPlus_template_more">6.18.9 More on templates</a></H3>
<p>
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index b20b69cef..9d5361dae 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -493,6 +493,7 @@ example.i(4) : Syntax error in input(1).
<li>401. Nothing known about class 'name'. Ignored.
<li>402. Base class 'name' is incomplete.
<li>403. Class 'name' might be abstract.
+<li>404. Duplicate template instantiation of '<em>type</em>' with name '<em>name</em>' ignored, previous instantiation of '<em>type</em>' with name '<em>name</em>'.
<li>450. Reserved
<li>451. Setting const char * variable may leak memory.
<li>452. Reserved