diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2022-11-18 18:49:48 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2022-11-18 19:35:47 +0000 |
commit | 4729cf2b1f44e57f46d13758009b10cec5af47b6 (patch) | |
tree | 67e0c94bf8f89539c4008c11624b22779c1240c5 /Doc | |
parent | 777fd2c280fbeb0dea79d900f115369bc2295f65 (diff) | |
download | swig-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.html | 1 | ||||
-rw-r--r-- | Doc/Manual/SWIGPlus.html | 139 | ||||
-rw-r--r-- | Doc/Manual/Warnings.html | 1 |
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<Integer> *x); In this case, <tt>List<Integer></tt> is exactly the same type as <tt>List<int></tt>. Any use of <tt>List<Integer></tt> is mapped back to the instantiation of <tt>List<int></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<int>; +%template(IntegerList) List<Integer>; // 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< Integer >' with name 'IntegerList' ignored, +example.i:47: Warning 404: previous instantiation of 'List< int >' 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<typename T, int max=100> class vector { +template <typename T, int max=100> class vector { ... }; -%template(intvec) vector<int>; // OK +%template(intvec) vector<int>; // OK %template(vec1000) vector<int, 1000>; // 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<int>; -%template(Listint) List<int>; // Error. Template already wrapped. +%template(vec) vector<double>; // OK +%template(vec100) vector<double, 100>; // 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< double,100 >' with name 'vec100' ignored, +example.i:58: Warning 404: previous instantiation of 'vector< double >' 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<double, double>, but don't wrap it. -%template() traits<double, double>; -</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<string, int>) 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<typename T> struct Traits { + typedef T type; +}; +%} + +%template() Traits<int>; // instantiate Traits<int>, but don't wrap it + +void traitor(Traits<int>::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<class T> T tfunc(T x) { }; +%template() tfunc<double>; +</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< double >(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<int>; </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 |