mirror of https://github.com/swig/swig
Fix overloading of shared_ptr method overloading
Add 'equivalent' attribute to typecheck typemap. Closes #1098.
This commit is contained in:
parent
f5e1856650
commit
ed4b84f4d3
|
@ -7,6 +7,36 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
2017-09-23: wsfulton
|
||||
Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
|
||||
|
||||
void m(std::shared_ptr<T> p);
|
||||
void m(T &p);
|
||||
void m(T *p);
|
||||
|
||||
Only the first method is wrapped and the others are ignored/shadowed.
|
||||
The implementation is done via a new attribute in the 'typecheck' typemap called
|
||||
'equivalent'. If specified, it must contain the equivalent pointer type for overloading
|
||||
and can only be used for the special SWIG_TYPECHECK_POINTER precedence level.
|
||||
The shared_ptr 'typecheck' typemaps have been modified accordingly.
|
||||
Here is a simplified version:
|
||||
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="T *")
|
||||
T,
|
||||
T CONST &,
|
||||
T CONST *,
|
||||
T *CONST&,
|
||||
std::shared_ptr< T >,
|
||||
std::shared_ptr< T > &,
|
||||
std::shared_ptr< T > *,
|
||||
std::shared_ptr< T > *&
|
||||
{ ... }
|
||||
|
||||
Overloading with any of these types will result in SWIG ignoring all but the first
|
||||
overloaded method by default. Without the 'equivalent' attribute, wrapping the overloaded
|
||||
methods resulted in types being shadowed (scripting languages) or code that did not
|
||||
compile (statically typed languages).
|
||||
|
||||
2017-09-19: futatuki
|
||||
[Python] #1003 Add --with-2to3=/path/to/2to3 option to configure.
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@
|
|||
<ul>
|
||||
<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||
</ul>
|
||||
|
@ -500,6 +501,9 @@
|
|||
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn48">More about %apply and %clear</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn47">Passing data between typemaps</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn52">C++ "this" pointer</a>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<ul>
|
||||
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||
<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||
<li><a href="#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
|
||||
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||
</ul>
|
||||
|
@ -1921,7 +1922,30 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Library_shared_ptr_templates">9.4.4.3 shared_ptr and templates</a></H4>
|
||||
<H4><a name="Library_shared_ptr_overloading">9.4.4.3 shared_ptr and method overloading</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
A C++ compiler can disambiguate a method overloaded by a shared_ptr and one using the raw underlying type.
|
||||
For example, either one of these methods can be called in C++:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
int age(std::shared_ptr<GrandParent> num);
|
||||
int age(GrandParent& num);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
When wrapped by SWIG, disambiguation is not possible using the overloaded names as there is just one equivalent type (<tt>GrandParent</tt>) in the target language.
|
||||
SWIG will choose to wrap just the first method by default.
|
||||
<a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in overloading</a> discusses ways to control which method(s) gets wrapped using <tt>%ignore</tt> or <tt>%rename</tt>.
|
||||
For the interested reader, SWIG detects that they are equivalent types via the <a href=Typemaps.html#Typemaps_typecheck_pointer>typecheck typemaps</a> in the shared_ptr library.
|
||||
</p>
|
||||
|
||||
<H4><a name="Library_shared_ptr_templates">9.4.4.4 shared_ptr and templates</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
|
||||
|
@ -1962,7 +1986,7 @@ The SWIG code below shows the required ordering:
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Library_shared_ptr_directors">9.4.4.4 shared_ptr and directors</a></H4>
|
||||
<H4><a name="Library_shared_ptr_directors">9.4.4.5 shared_ptr and directors</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
@ -89,6 +89,9 @@
|
|||
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn48">More about %apply and %clear</a>
|
||||
<li><a href="#Typemaps_nn47">Passing data between typemaps</a>
|
||||
<li><a href="#Typemaps_nn52">C++ "this" pointer</a>
|
||||
|
@ -4754,7 +4757,8 @@ then the type is given a precedence higher than any other known precedence level
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type checking rule - no precedence level in typecheck typemap for 'int').
|
||||
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type
|
||||
checking rule - no precedence level in typecheck typemap for 'int').
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
@ -4779,10 +4783,112 @@ simply check the type of the first array element and use that to dispatch to the
|
|||
Subsequent "in" typemaps would then perform more extensive type-checking.
|
||||
</li>
|
||||
|
||||
<li>Make sure you read the section on overloading in the "<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>" chapter.
|
||||
<li>Make sure you read the section on <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">overloading</a> in the SWIG and C++ chapter.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="Typemaps_typecheck_pointer">11.13.1 SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
When it comes to overloading of a particular type passed by value, pointer or reference (const and non-const),
|
||||
a C++ compiler can disambiguate which overloaded function to call.
|
||||
However, SWIG effectively treats these as pointers in the target language and thus as equivalent types.
|
||||
For example, consider:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class X { ... };
|
||||
void m(X const &c); // equivalent: void m(X *c);
|
||||
void m(X &r); // equivalent: void m(X *r);
|
||||
void m(X *p); // equivalent: void m(X *p);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
These cannot be disambiguated in the target languages and so SWIG will choose the first method and ignore the subsequent two methods.
|
||||
The scripting languages do this by using the overload dispatch mechanism described earlier and warnings indicate this:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:6: Warning 509: Overloaded method m(X &) effectively ignored,
|
||||
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
||||
example.i:7: Warning 509: Overloaded method m(X *) effectively ignored,
|
||||
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The statically typed languages like Java and C# automatically ignore all but the first equivalent overloaded methods with warnings:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:6: Warning 516: Overloaded method m(X &) ignored,
|
||||
example.i:5: Warning 516: using m(X const &) instead.
|
||||
example.i:7: Warning 516: Overloaded method m(X *) ignored,
|
||||
example.i:5: Warning 516: using m(X const &) instead.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
You can select the overloaded method you would like to wrap by ignoring the other two with <tt>%ignore</tt> or rename two of them with <tt>%rename</tt>
|
||||
and this will of course remove the warnings too.
|
||||
The problem of ambiguity is also discussed in the C++ chapter on <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">overloading</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
So how does this work with respect to typemaps?
|
||||
The typemaps SWIG provides to handle overloading for these three methods are from the SWIGTYPE family.
|
||||
As discussed earlier, in <a href="Typemaps.html#Typemaps_nn19">Default typemap matching rules</a>,
|
||||
the <tt>SWIGTYPE &</tt> typemaps are used for references and <tt>SWIGTYPE *</tt> typemaps are used for pointers.
|
||||
SWIG uses the special <tt>SWIG_TYPECHECK_POINTER</tt> (0) precedence level to handle these types in the "typecheck" typemap:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE & "..."
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE * "..."
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
When the SWIGTYPE "typecheck" typemaps use the <tt>SWIG_TYPECHECK_POINTER</tt> precedence level,
|
||||
SWIG converts the type to a pointer equivalent type and then uses the equivalent type to detect if it can be disambiguated in an overloaded method in the target language.
|
||||
In our example above, the equivalent types for <tt>X const &</tt>, <tt>X &</tt> and <tt>X *</tt> are all <tt>X *</tt>.
|
||||
As they are the same, they cannot be disambiguated and so just the first overloaded method is chosen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The automatic conversion to equivalent types and subsequent type comparison is triggered via the use of the special <tt>SWIG_TYPECHECK_POINTER</tt> precedence level
|
||||
and works for types passed by value, pointer and reference.
|
||||
Alas, there are more ways to overload a method that also need handling.
|
||||
C++ smart pointers are such a type which can be disambiguated by a C++ compiler but not automatically by SWIG.
|
||||
SWIG does not automatically know that a smart pointer has an equivalent type, but it can be told manually.
|
||||
Just specify the 'equivalent' attribute in the "typecheck" typemap with a pointer to the underlying type.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="X *") MySmartPtr<X> " ... "
|
||||
|
||||
void m(X &r); // equivalent: void m(X *r);
|
||||
void m(MySmartPtr<X> s); // equivalent: void m(X *s);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now SWIG will detect the two types are equivalent and generate valid code by wrapping just the first overloaded method.
|
||||
You can of course choose which method to wrap by ignoring one of them with <tt>%ignore</tt>.
|
||||
Otherwise both can be wrapped by removing the overloading name ambiguity by renaming one of them with <tt>%rename</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The 'equivalent' attribute is used in the implementation for the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library.
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn48">11.14 More about %apply and %clear</a></H2>
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ CPP_TEST_CASES = \
|
|||
CPP11_TEST_CASES = \
|
||||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_upcast \
|
||||
cpp11_strongly_typed_enumerations_simple \
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ CPP_TEST_CASES = \
|
|||
CPP11_TEST_CASES = \
|
||||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_upcast \
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
|
|
@ -46,6 +46,7 @@ CPP_TEST_CASES = \
|
|||
CPP11_TEST_CASES = \
|
||||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_upcast \
|
||||
cpp11_strongly_typed_enumerations_simple \
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import cpp11_shared_ptr_overload.*;
|
||||
|
||||
public class cpp11_shared_ptr_overload_runme {
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_shared_ptr_overload");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[])
|
||||
{
|
||||
String ret = null;
|
||||
|
||||
// ref
|
||||
ret = cpp11_shared_ptr_overload.UseA(new MyType("123"));
|
||||
if (!ret.equals("123 ref")) throw new RuntimeException("UseA fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseB(0, new MyType("123"));
|
||||
if (!ret.equals("123 ref")) throw new RuntimeException("UseB fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseC(0, new MyType("123"), new MyType("456"));
|
||||
if (!ret.equals("123 ref")) throw new RuntimeException("UseC fail:" + ret);
|
||||
|
||||
// sharedptr
|
||||
ret = cpp11_shared_ptr_overload.UseX(new MyType("123"));
|
||||
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseX fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseY(0, new MyType("123"));
|
||||
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseY fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseZ(0, new MyType("123"), new MyType("456"));
|
||||
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseZ fail:" + ret);
|
||||
|
||||
// Combo1-4
|
||||
ret = cpp11_shared_ptr_overload.Combo1(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo1")) throw new RuntimeException("Combo1 fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo2(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo2")) throw new RuntimeException("Combo2 fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo3(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo3")) throw new RuntimeException("Combo3 fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo4(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo4")) throw new RuntimeException("Combo4 fail:" + ret);
|
||||
|
||||
// Combo5-7
|
||||
ret = cpp11_shared_ptr_overload.Combo5(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo5")) throw new RuntimeException("Combo5 fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo6(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo6")) throw new RuntimeException("Combo6 fail:" + ret);
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo7(new MyType("XXX"));
|
||||
if (!ret.equals("XXXCombo7")) throw new RuntimeException("Combo7 fail:" + ret);
|
||||
}
|
||||
}
|
|
@ -83,6 +83,7 @@ CPP11_TEST_CASES = \
|
|||
cpp11_hash_tables \
|
||||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_upcast \
|
||||
|
||||
C_TEST_CASES += \
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import cpp11_shared_ptr_overload
|
||||
from cpp11_shared_ptr_overload import MyType
|
||||
|
||||
# ref
|
||||
ret = cpp11_shared_ptr_overload.UseA(MyType("123"))
|
||||
if ret != "123 ref": raise RuntimeError("UseA fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseB(0, MyType("123"))
|
||||
if ret != "123 ref": raise RuntimeError("UseB fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseC(0, MyType("123"), MyType("456"))
|
||||
if ret != "123 ref": raise RuntimeError("UseC fail:" + ret)
|
||||
|
||||
# sharedptr
|
||||
ret = cpp11_shared_ptr_overload.UseX(MyType("123"))
|
||||
if ret != "123 sharedptr": raise RuntimeError("UseX fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseY(0, MyType("123"))
|
||||
if ret != "123 sharedptr": raise RuntimeError("UseY fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.UseZ(0, MyType("123"), MyType("456"))
|
||||
if ret != "123 sharedptr": raise RuntimeError("UseZ fail:" + ret)
|
||||
|
||||
# Combo1-4
|
||||
ret = cpp11_shared_ptr_overload.Combo1(MyType("XXX"))
|
||||
if ret != "XXXCombo1": raise RuntimeError("Combo1 fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo2(MyType("XXX"))
|
||||
if ret != "XXXCombo2": raise RuntimeError("Combo2 fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo3(MyType("XXX"))
|
||||
if ret != "XXXCombo3": raise RuntimeError("Combo3 fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo4(MyType("XXX"))
|
||||
if ret != "XXXCombo4": raise RuntimeError("Combo4 fail:" + ret)
|
||||
|
||||
# Combo5-7
|
||||
ret = cpp11_shared_ptr_overload.Combo5(MyType("XXX"))
|
||||
if ret != "XXXCombo5": raise RuntimeError("Combo5 fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo6(MyType("XXX"))
|
||||
if ret != "XXXCombo6": raise RuntimeError("Combo6 fail:" + ret)
|
||||
|
||||
ret = cpp11_shared_ptr_overload.Combo7(MyType("XXX"))
|
||||
if ret != "XXXCombo7": raise RuntimeError("Combo7 fail:" + ret)
|
|
@ -36,6 +36,7 @@ CPP11_TEST_CASES = \
|
|||
cpp11_hash_tables \
|
||||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_upcast \
|
||||
cpp11_std_unordered_map \
|
||||
cpp11_std_unordered_multimap \
|
||||
|
|
|
@ -505,6 +505,17 @@
|
|||
%typemap(imtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast "global::System.Runtime.InteropServices.HandleRef"
|
||||
%typemap(imtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast "global::System.Runtime.InteropServices.HandleRef"
|
||||
|
||||
// Typecheck typemaps
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *")
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
TYPE *CONST&,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
|
||||
""
|
||||
|
||||
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
|
||||
%enddef
|
||||
|
|
|
@ -233,6 +233,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Typecheck typemaps
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *")
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
TYPE *CONST&,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
|
||||
""
|
||||
|
||||
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
|
||||
%enddef
|
||||
|
||||
|
|
|
@ -197,5 +197,17 @@ public static void* swigGetCPtr(typeof(this) obj) {
|
|||
}
|
||||
}
|
||||
|
||||
// Typecheck typemaps
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *")
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
TYPE *CONST&,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
|
||||
""
|
||||
|
||||
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
|
||||
%enddef
|
||||
|
|
|
@ -467,6 +467,17 @@
|
|||
%typemap(jtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast "long"
|
||||
%typemap(jtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast "long"
|
||||
|
||||
// Typecheck typemaps
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *")
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
TYPE *CONST&,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
|
||||
""
|
||||
|
||||
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
|
||||
%enddef
|
||||
|
|
|
@ -225,6 +225,18 @@
|
|||
}
|
||||
%}
|
||||
|
||||
// Typecheck typemaps
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *")
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
TYPE *CONST&,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
|
||||
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
|
||||
""
|
||||
|
||||
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
|
||||
%enddef
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@
|
|||
// Typecheck typemaps
|
||||
// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
|
||||
// function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1)
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1)
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
|
|
|
@ -294,7 +294,7 @@
|
|||
// Typecheck typemaps
|
||||
// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
|
||||
// function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1)
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1)
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
|
|
|
@ -281,7 +281,7 @@
|
|||
// Typecheck typemaps
|
||||
// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
|
||||
// function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1)
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1)
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
|
|
|
@ -369,7 +369,7 @@
|
|||
// Typecheck typemaps
|
||||
// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
|
||||
// function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1)
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1)
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
%include <rubystdcommon_forward.swg>
|
||||
|
||||
|
||||
%fragment("StdSharedPtrTraits","header",fragment="StdTraitsForwardDeclaration")
|
||||
%fragment("StdSharedPtrTraits","header",fragment="StdTraitsForwardDeclaration",fragment="<memory>")
|
||||
{
|
||||
namespace swig {
|
||||
/*
|
||||
|
|
|
@ -290,7 +290,7 @@
|
|||
// Typecheck typemaps
|
||||
// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
|
||||
// function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1)
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1)
|
||||
TYPE CONST,
|
||||
TYPE CONST &,
|
||||
TYPE CONST *,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* emit_return_variable()
|
||||
|
@ -112,9 +113,8 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
/* This is compatibility code to deal with the deprecated "ignore" typemap */
|
||||
Parm *p = l;
|
||||
Parm *np;
|
||||
String *tm;
|
||||
while (p) {
|
||||
tm = Getattr(p, "tmap:in");
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
Replaceall(tm, "$target", Getattr(p, "lname"));
|
||||
Printv(f->code, tm, "\n", NIL);
|
||||
|
@ -134,7 +134,6 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
/* Perform a sanity check on "in" and "freearg" typemaps. These
|
||||
must exactly match to avoid chaos. If a mismatch occurs, we
|
||||
nuke the freearg typemap */
|
||||
|
||||
{
|
||||
Parm *p = l;
|
||||
Parm *npin, *npfreearg;
|
||||
|
@ -196,6 +195,36 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent
|
||||
* target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer
|
||||
* are seen as equivalent types in the target language.
|
||||
*/
|
||||
{
|
||||
Parm *p = l;
|
||||
while (p) {
|
||||
String *tm = Getattr(p, "tmap:typecheck");
|
||||
if (tm) {
|
||||
String *equivalent = Getattr(p, "tmap:typecheck:equivalent");
|
||||
if (equivalent) {
|
||||
String *precedence = Getattr(p, "tmap:typecheck:precedence");
|
||||
if (precedence && Strcmp(precedence, "0") != 0)
|
||||
Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0));
|
||||
SwigType *cpt = Swig_cparse_type(equivalent);
|
||||
if (cpt) {
|
||||
Setattr(p, "equivtype", cpt);
|
||||
Delete(cpt);
|
||||
} else {
|
||||
Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0));
|
||||
}
|
||||
}
|
||||
p = Getattr(p, "tmap:typecheck:next");
|
||||
} else {
|
||||
p = nextSibling(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
@ -185,7 +185,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
nodes[j] = t;
|
||||
break;
|
||||
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
|
||||
t1 = Getattr(p1, "ltype");
|
||||
t1 = Getattr(p1, "equivtype");
|
||||
t1 = t1 ? t1 : Getattr(p1, "ltype");
|
||||
if (!t1) {
|
||||
t1 = SwigType_ltype(Getattr(p1, "type"));
|
||||
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
|
||||
|
@ -193,7 +194,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
}
|
||||
Setattr(p1, "ltype", t1);
|
||||
}
|
||||
t2 = Getattr(p2, "ltype");
|
||||
t2 = Getattr(p2, "equivtype");
|
||||
t2 = t2 ? t2 : Getattr(p2, "ltype");
|
||||
if (!t2) {
|
||||
t2 = SwigType_ltype(Getattr(p2, "type"));
|
||||
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
|
||||
|
|
Loading…
Reference in New Issue