Add missing use of move constructor

instead of copy constructor when passing movable types. This was
previously implemented only for parameters passed to a global function
or static member function and is now extended to member methods.

Enhancement to e777b054d5.
This commit is contained in:
William S Fulton 2024-01-23 20:54:52 +00:00
parent ee75385566
commit dcc1471dd3
21 changed files with 382 additions and 39 deletions

View File

@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-01-23: wsfulton
Add missing use of move constructor instead of copy constructor when
passing movable types. This was previously implemented only for parameters
passed to a global function or static member function and is now extended
to member methods.
2024-03-01: olly
[Java] #2819 Suppress Java removal warnings for uses of
System.runFinalization(). SWIG will need to stop relying on

View File

@ -305,7 +305,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
</pre></div>
<p>
<tt>SwigValueWrapper</tt> is covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>.
<tt>SwigValueWrapper</tt> is covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a> and is automatically generated in this case as <tt>MoveOnly</tt> is not assignable.
Note that the generated code could be optimised further using the <a href="Typemaps.html#Typemaps_optimal">"optimal" attribute</a>
in the "out" typemap, so if the above typemap is customised as follows (note that this is C# specific):
</p>

View File

@ -1518,13 +1518,13 @@ Vector *wrap_cross_product(Vector *a, Vector *b) {
</div>
<p>
In order for the wrapper code to compile, <tt>Vector</tt> must define a default constructor, copy assignment operator (and/or a move assignment operator for C++11 and later).
In order for the wrapper code to compile, <tt>Vector</tt> must define a default constructor and a copy assignment operator (and/or a move assignment operator for C++11 and later).
The <a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types</a> section should be read regarding C++11 move semantics and return by value.
</p>
<p>
If <tt>Vector</tt> is defined as a class in the interface, but it does not
support a default constructor, SWIG changes the wrapper code by encapsulating
support a default constructor and an assignment operator, SWIG changes the wrapper code by encapsulating
the arguments inside a special C++ template wrapper class, through a process
called the "Fulton Transform". This produces a wrapper that looks like this:
</p>
@ -1545,7 +1545,7 @@ Vector cross_product(Vector *a, Vector *b) {
<p>
This transformation is a little sneaky, but it provides support for
pass-by-value even when a class does not provide a default constructor
pass-by-value even when a class is not default constructible nor assignable
and it makes it possible to properly support a number of SWIG's
customization options. The definition of <tt>SwigValueWrapper</tt>
can be found by reading the SWIG wrapper code. This class is really nothing more than a thin

View File

@ -7,7 +7,7 @@
#endif
%ignore MoveOnly::operator=;
//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types
//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types (actually when there is no copy assignment operator)
%inline %{
#include <iostream>
@ -59,3 +59,16 @@ struct MovableCopyable {
static void take(MovableCopyable mc) { if (trace) cout << "take(MovableCopyable)" << " " << &mc << endl; }
};
%}
%inline %{
struct InstanceMethodsTester {
#if defined(WRAP_TAKE_METHOD)
void instance_take_move_only(MoveOnly mo) { if (trace) cout << "instance_take_move_only(MoveOnly)" << " " << &mo << endl; }
#endif
void instance_take_movable_copyable(MovableCopyable mc) { if (trace) cout << "instance_take_movable_copyable(MovableCopyable)" << " " << &mc << endl; }
};
#if defined(WRAP_TAKE_METHOD)
void global_take_move_only(MoveOnly mo) { if (trace) cout << "global_take_move_only(MoveOnly)" << " " << &mo << endl; }
#endif
void global_take_movable_copyable(MovableCopyable mc) { if (trace) cout << "global_take_movable_copyable(MovableCopyable)" << " " << &mc << endl; }
%}

View File

@ -4,7 +4,6 @@ using cpp11_move_onlyNamespace;
public class cpp11_move_only_runme {
public static void Main() {
// Output
Counter.reset_counts();
using (MoveOnly mo = MoveOnly.create()) {
@ -12,23 +11,43 @@ public class cpp11_move_only_runme {
Counter.check_counts(1, 0, 0, 2, 0, 3);
Counter.reset_counts();
using (MovableCopyable mo = MovableCopyable.create()) {
using (MovableCopyable mc = MovableCopyable.create()) {
}
Counter.check_counts(2, 1, 0, 0, 1, 3);
// Move semantics not used
Counter.reset_counts();
using (MovableCopyable mo = MovableCopyable.createConst()) {
using (MovableCopyable mc = MovableCopyable.createConst()) {
}
Counter.check_counts(2, 1, 1, 0, 0, 3);
// Input
// Input static method
Counter.reset_counts();
using (MovableCopyable mo = new MovableCopyable(222)) {
using (MovableCopyable mc = new MovableCopyable(222)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
MovableCopyable.take(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
}
Counter.check_counts(2, 0, 1, 1, 0, 3);
// Input global function
Counter.reset_counts();
using (MovableCopyable mc = new MovableCopyable(333)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
cpp11_move_only.global_take_movable_copyable(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
}
Counter.check_counts(2, 0, 1, 1, 0, 3);
// Input instance method
Counter.reset_counts();
using (InstanceMethodsTester imt = new InstanceMethodsTester()) {
using (MovableCopyable mc = new MovableCopyable(444)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
}
Counter.check_counts(2, 0, 1, 1, 0, 3);
}
}
}

View File

@ -33,5 +33,22 @@ public class cpp11_move_typemaps_runme {
if (!exception_thrown)
throw new ApplicationException("double usage of take should have been an error");
}
Counter.reset_counts();
using (InstanceMethodsTester imt = new InstanceMethodsTester()) {
using (MoveOnly mo = new MoveOnly(333)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_move_only(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
using (MovableCopyable mc = new MovableCopyable(444)) {
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
}
}

View File

@ -3,6 +3,7 @@ module cpp11_move_typemaps_runme;
import cpp11_move_typemaps.Counter;
import cpp11_move_typemaps.MoveOnly;
import cpp11_move_typemaps.MovableCopyable;
import cpp11_move_typemaps.InstanceMethodsTester;
import std.conv;
import std.algorithm;
@ -39,4 +40,24 @@ void main() {
if (!exception_thrown)
throw new Exception("double usage of take should have been an error");
}
{
Counter.reset_counts();
InstanceMethodsTester imt = new InstanceMethodsTester();
{
scope MoveOnly mo = new MoveOnly(333);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_move_only(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
{
scope MovableCopyable mc = new MovableCopyable(444);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
}

View File

@ -24,27 +24,50 @@ public class cpp11_move_only_runme {
{
Counter.reset_counts();
MovableCopyable mo = MovableCopyable.create();
mo.delete();
MovableCopyable mc = MovableCopyable.create();
mc.delete();
Counter.check_counts(2, 1, 0, 0, 1, 3);
}
// Move semantics not used
{
Counter.reset_counts();
MovableCopyable mo = MovableCopyable.createConst();
mo.delete();
MovableCopyable mc = MovableCopyable.createConst();
mc.delete();
Counter.check_counts(2, 1, 1, 0, 0, 3);
}
// Input
// Input static method
{
Counter.reset_counts();
MovableCopyable mo = new MovableCopyable(222);
MovableCopyable mc = new MovableCopyable(222);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
MovableCopyable.take(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
mo.delete();
mc.delete();
Counter.check_counts(2, 0, 1, 1, 0, 3);
}
// Input global function
{
Counter.reset_counts();
MovableCopyable mc = new MovableCopyable(333);
Counter.check_counts(1, 0, 0, 0, 0, 0);
cpp11_move_only.global_take_movable_copyable(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
mc.delete();
Counter.check_counts(2, 0, 1, 1, 0, 3);
}
// Input instance method
{
Counter.reset_counts();
InstanceMethodsTester imt = new InstanceMethodsTester();
MovableCopyable mc = new MovableCopyable(444);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(2, 0, 1, 1, 0, 2);
mc.delete();
Counter.check_counts(2, 0, 1, 1, 0, 3);
}
}

View File

@ -47,5 +47,27 @@ public class cpp11_move_typemaps_runme {
if (!exception_thrown)
throw new RuntimeException("double usage of take should have been an error");
}
{
Counter.reset_counts();
InstanceMethodsTester imt = new InstanceMethodsTester();
{
MoveOnly mo = new MoveOnly(333);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_move_only(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
mo.delete();
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
{
MovableCopyable mc = new MovableCopyable(444);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(1, 0, 0, 1, 0, 2);
mc.delete();
}
Counter.check_counts(1, 0, 0, 1, 0, 2);
}
}
}

View File

@ -6,17 +6,32 @@ var mo = cpp11_move_only.MoveOnly.create();
cpp11_move_only.Counter.check_counts(1, 0, 0, 2, 0, 2);
cpp11_move_only.Counter.reset_counts();
var mo = cpp11_move_only.MovableCopyable.create();
var mc = cpp11_move_only.MovableCopyable.create();
cpp11_move_only.Counter.check_counts(2, 1, 0, 0, 1, 2);
// Move semantics not used
cpp11_move_only.Counter.reset_counts();
var mo = cpp11_move_only.MovableCopyable.createConst();
var mc = cpp11_move_only.MovableCopyable.createConst();
cpp11_move_only.Counter.check_counts(2, 1, 1, 0, 0, 2);
// Input
// Input static method
cpp11_move_only.Counter.reset_counts();
var mo = new cpp11_move_only.MovableCopyable(222);
var mc = new cpp11_move_only.MovableCopyable(222);
cpp11_move_only.Counter.check_counts(1, 0, 0, 0, 0, 0);
cpp11_move_only.MovableCopyable.take(mo);
cpp11_move_only.MovableCopyable.take(mc);
cpp11_move_only.Counter.check_counts(2, 0, 1, 1, 0, 2);
// Input global function
cpp11_move_only.Counter.reset_counts();
var mc = new cpp11_move_only.MovableCopyable(333);
cpp11_move_only.Counter.check_counts(1, 0, 0, 0, 0, 0);
cpp11_move_only.global_take_movable_copyable(mc);
cpp11_move_only.Counter.check_counts(2, 0, 1, 1, 0, 2);
// Input instance method
cpp11_move_only.Counter.reset_counts();
var imt = new cpp11_move_only.InstanceMethodsTester();
var mc = new cpp11_move_only.MovableCopyable(444);
cpp11_move_only.Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
cpp11_move_only.Counter.check_counts(2, 0, 1, 1, 0, 2);

View File

@ -28,3 +28,24 @@ try {
}
if (!exception_thrown)
throw new Error("double usage of take should have been an error");
cpp11_move_typemaps.Counter.reset_counts();
imt = new cpp11_move_typemaps.InstanceMethodsTester();
mo = new cpp11_move_typemaps.MoveOnly(333);
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_move_only(mo);
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
delete mo;
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
cpp11_move_typemaps.Counter.reset_counts();
mc = new cpp11_move_typemaps.MovableCopyable(444);
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
delete mc;
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);

View File

@ -26,3 +26,23 @@ mo = cpp11_move_typemaps.MoveOnly(222)
cpp11_move_typemaps.MoveOnly.take(mo)
s, msg = pcall(function() cpp11_move_typemaps.MoveOnly.take(mo) end)
assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
cpp11_move_typemaps.Counter.reset_counts()
imt = cpp11_move_typemaps.InstanceMethodsTester()
mo = cpp11_move_typemaps.MoveOnly(333)
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
imt:instance_take_move_only(mo)
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
mo = nil
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
cpp11_move_typemaps.Counter.reset_counts()
mc = cpp11_move_typemaps.MovableCopyable(444)
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
imt:instance_take_movable_copyable(mc)
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
mc = nil
cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)

View File

@ -32,4 +32,24 @@
(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
(error "Wrong or no exception thrown: " exception_thrown))
(Counter-reset-counts)
(define imt (new-InstanceMethodsTester))
(define mo (new-MoveOnly 333))
(Counter-check-counts 1 0 0 0 0 0)
(InstanceMethodsTester-instance-take-move-only imt mo)
(Counter-check-counts 1 0 0 1 0 2)
(delete-MoveOnly mo)
(Counter-check-counts 1 0 0 1 0 2)
(Counter-reset-counts)
(define mc (new-MovableCopyable 444))
(Counter-check-counts 1 0 0 0 0 0)
(InstanceMethodsTester-instance-take-movable-copyable imt mc)
(Counter-check-counts 1 0 0 1 0 2)
(delete-MovableCopyable mc)
(Counter-check-counts 1 0 0 1 0 2)
(exit 0)

View File

@ -7,19 +7,19 @@ cpp11_move_typemaps
Counter.reset_counts();
mo = MoveOnly(111);
Counter_check_counts(1, 0, 0, 0, 0, 0);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MoveOnly.take(mo);
Counter_check_counts(1, 0, 0, 1, 0, 2);
Counter.check_counts(1, 0, 0, 1, 0, 2);
clear mo;
Counter_check_counts(1, 0, 0, 1, 0, 2);
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
mo = MovableCopyable(111);
Counter_check_counts(1, 0, 0, 0, 0, 0);
Counter.check_counts(1, 0, 0, 0, 0, 0);
MovableCopyable.take(mo);
Counter_check_counts(1, 0, 0, 1, 0, 2);
Counter.check_counts(1, 0, 0, 1, 0, 2);
clear mo;
Counter_check_counts(1, 0, 0, 1, 0, 2);
Counter.check_counts(1, 0, 0, 1, 0, 2);
mo = MoveOnly(222);
MoveOnly.take(mo);
@ -35,3 +35,23 @@ end_try_catch
if (!exception_thrown)
error("double usage of take should have been an error");
endif
Counter.reset_counts();
imt = InstanceMethodsTester();
mo = MoveOnly(333);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_move_only(mo);
Counter.check_counts(1, 0, 0, 1, 0, 2);
clear mo;
Counter.check_counts(1, 0, 0, 1, 0, 2);
Counter.reset_counts();
mc = MovableCopyable(444);
Counter.check_counts(1, 0, 0, 0, 0, 0);
imt.instance_take_movable_copyable(mc);
Counter.check_counts(1, 0, 0, 1, 0, 2);
clear mc;
Counter.check_counts(1, 0, 0, 1, 0, 2);

View File

@ -32,3 +32,25 @@ cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
};
like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
}
{
cpp11_move_typemaps::Counter::reset_counts();
my $imt = new cpp11_move_typemaps::InstanceMethodsTester();
{
my $mo = new cpp11_move_typemaps::MoveOnly(333);
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
$imt->instance_take_move_only($mo);
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
undef $mo;
}
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
cpp11_move_typemaps::Counter::reset_counts();
{
my $mc = new cpp11_move_typemaps::MovableCopyable(444);
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
$imt->instance_take_movable_copyable($mc);
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
undef $mc;
}
cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
}

View File

@ -29,4 +29,24 @@ try {
}
check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
Counter::reset_counts();
$imt = new InstanceMethodsTester();
$mo = new MoveOnly(333);
Counter::check_counts(1, 0, 0, 0, 0, 0);
$imt->instance_take_move_only($mo);
Counter::check_counts(1, 0, 0, 1, 0, 2);
$mo = NULL;
Counter::check_counts(1, 0, 0, 1, 0, 2);
Counter::reset_counts();
$mc = new MovableCopyable(444);
Counter::check_counts(1, 0, 0, 0, 0, 0);
$imt->instance_take_movable_copyable($mc);
Counter::check_counts(1, 0, 0, 1, 0, 2);
$mc = NULL;
Counter::check_counts(1, 0, 0, 1, 0, 2);
check::done();

View File

@ -7,21 +7,40 @@ del mo
Counter.check_counts(1, 0, 0, 2, 0, 3)
Counter.reset_counts()
mo = MovableCopyable.create()
del mo
mc = MovableCopyable.create()
del mc
Counter.check_counts(2, 1, 0, 0, 1, 3)
# Move semantics not used
Counter.reset_counts()
mo = MovableCopyable.createConst()
del mo
mc = MovableCopyable.createConst()
del mc
Counter.check_counts(2, 1, 1, 0, 0, 3)
# Input
# Input static method
Counter.reset_counts()
mo = MovableCopyable(222)
mc = MovableCopyable(222)
Counter.check_counts(1, 0, 0, 0, 0, 0)
MovableCopyable.take(mo)
MovableCopyable.take(mc)
Counter.check_counts(2, 0, 1, 1, 0, 2)
del mo
del mc
Counter.check_counts(2, 0, 1, 1, 0, 3)
# Input global function
Counter.reset_counts()
mc = MovableCopyable(333)
Counter.check_counts(1, 0, 0, 0, 0, 0)
global_take_movable_copyable(mc)
Counter.check_counts(2, 0, 1, 1, 0, 2)
del mc
Counter.check_counts(2, 0, 1, 1, 0, 3)
# Input instance method
Counter.reset_counts()
imt = InstanceMethodsTester()
mc = MovableCopyable(444)
Counter.check_counts(1, 0, 0, 0, 0, 0)
imt.instance_take_movable_copyable(mc)
Counter.check_counts(2, 0, 1, 1, 0, 2)
del mc
Counter.check_counts(2, 0, 1, 1, 0, 3)

View File

@ -27,3 +27,23 @@ except RuntimeError as e:
exception_thrown = True
if not exception_thrown:
raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
Counter.reset_counts()
imt = InstanceMethodsTester()
mo = MoveOnly(333)
Counter.check_counts(1, 0, 0, 0, 0, 0)
imt.instance_take_move_only(mo)
Counter.check_counts(1, 0, 0, 1, 0, 2)
del mo
Counter.check_counts(1, 0, 0, 1, 0, 2)
Counter.reset_counts()
mc = MovableCopyable(444)
Counter.check_counts(1, 0, 0, 0, 0, 0)
imt.instance_take_movable_copyable(mc)
Counter.check_counts(1, 0, 0, 1, 0, 2)
del mc
Counter.check_counts(1, 0, 0, 1, 0, 2)

View File

@ -34,3 +34,23 @@ end
if (!exception_thrown)
raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
end
Cpp11_move_typemaps::Counter.reset_counts()
imt = Cpp11_move_typemaps::InstanceMethodsTester.new()
mo = Cpp11_move_typemaps::MoveOnly.new(333)
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
imt.instance_take_move_only(mo)
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
mo = nil
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
Cpp11_move_typemaps::Counter.reset_counts()
mc = Cpp11_move_typemaps::MovableCopyable.new(444)
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
imt.instance_take_movable_copyable(mc)
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
mc = nil
Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)

View File

@ -33,3 +33,25 @@ if [ catch {
if {!$exception_thrown} {
error "Should have thrown 'Cannot release ownership as memory is not owned' error"
}
Counter_reset_counts
Counter_check_counts 0 0 0 0 0 0
InstanceMethodsTester imt
Counter_check_counts 0 0 0 0 0 0
MoveOnly mo333 333
Counter_check_counts 1 0 0 0 0 0
imt instance_take_move_only mo333
Counter_check_counts 1 0 0 1 0 2
mo333 -delete
Counter_check_counts 1 0 0 1 0 2
Counter_reset_counts
MovableCopyable mc 444
Counter_check_counts 1 0 0 0 0 0
imt instance_take_movable_copyable mc
Counter_check_counts 1 0 0 1 0 2
mc -delete
Counter_check_counts 1 0 0 1 0 2

View File

@ -532,7 +532,10 @@ static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms,
String *rcaststr = SwigType_rcaststr(pt, pname);
if (comma)
Append(func, ",");
Append(func, rcaststr);
if (cparse_cplusplus && SwigType_type(pt) == T_USER)
Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
else
Printv(func, rcaststr, NIL);
Delete(rcaststr);
Delete(pname);
comma = 1;