mirror of https://github.com/swig/swig
rvalue reference outputs
Document rvalue reference outputs behaviour Test rvalue reference outputs
This commit is contained in:
parent
c5495fea79
commit
2212af3f4f
|
@ -16,6 +16,8 @@
|
|||
<ul>
|
||||
<li><a href="#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
|
||||
<ul>
|
||||
<li><a href="#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
|
||||
<li><a href="#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
|
||||
<li><a href="#CPlusPlus11_move_only">Movable and move-only types</a>
|
||||
</ul>
|
||||
<li><a href="#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
|
||||
|
@ -109,7 +111,7 @@ public:
|
|||
|
||||
<p>
|
||||
Rvalue references are designed for C++ temporaries and are not particularly useful when used from non-C++ target languages.
|
||||
You could just ignore them via <tt>%ignore</tt> before parsing the class.
|
||||
One option is to just ignore them via <tt>%ignore</tt>.
|
||||
For example, ignore the move constructor:
|
||||
</p>
|
||||
|
||||
|
@ -117,8 +119,17 @@ For example, ignore the move constructor:
|
|||
%ignore MyClass::MyClass(MyClass &&);
|
||||
</pre></div>
|
||||
|
||||
<H4><a name="CPlusPlus11_rvalue_reference_inputs">7.2.1.1 Rvalue reference inputs</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
However, if you do wrap a function/contructor with an rvalue reference and pass a proxy class to it, SWIG will assume that after the call, the rvalue reference parameter will have been 'moved'.
|
||||
Rvalue reference parameters are useful as input parameters in C++ for implementing move semantics, such as,
|
||||
in the move constructor and move assignment operator.
|
||||
This type of usage can be useful from target languages too to avoid copying large objects.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you do wrap a function/contructor with an rvalue reference parameter and pass a proxy class to it, SWIG will assume that after the call, the rvalue reference parameter object will have been 'moved'.
|
||||
The proxy class passed as the rvalue reference, will own the underlying C++ object up until it is used as an rvalue reference parameter.
|
||||
Afterwards, the proxy class will have the underlying C++ pointer set to the nullptr so that the proxy class instance cannot be used again and the underlying (moved from) C++ object will be deleted after the function/constructor call has returned.
|
||||
</p>
|
||||
|
@ -136,15 +147,15 @@ MyClass mc2 = new MyClass(mc); // move constructor fails
|
|||
|
||||
<p>
|
||||
The second call to the move constructor will fail as the <tt>mc</tt> proxy instance has been moved.
|
||||
Each target language handles the moved proxy class slightly differently, but typically you'll get an exception such as in Java:
|
||||
Each target language handles the moved proxy class slightly differently when attempting to move it again, but typically you'll get an exception such as in Java:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
Exception in thread "main" java.lang.RuntimeException: Cannot release ownership as memory is not owned
|
||||
at MyClass.swigRelease(MyClass.java:27)
|
||||
at MyClass.<init>(MyClass.java:55)
|
||||
at runme.main(runme.java:18)
|
||||
at MyClass.swigRelease(MyClass.java:27)
|
||||
at MyClass.<init>(MyClass.java:55)
|
||||
at runme.main(runme.java:18)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
@ -160,15 +171,15 @@ example.i:18: Warning 503: Can't wrap 'operator =' unless renamed to a valid ide
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Using a <tt>%rename</tt> will remove the warning, however, a <tt>%rename</tt> makes the move constructor available from the target language:
|
||||
Using a <tt>%rename</tt> will remove the warning and also makes the move assignment operator available from the target language:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
%rename(MoveAssign) MyClass::operator=(MyClass &&);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
You can then use the move assignment operator, but like the move constructor example above, you cannot use
|
||||
a proxy class once it has been moved:
|
||||
You can then use it, but like the move constructor example above, you cannot use
|
||||
a proxy class once it has already been moved:
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
|
@ -178,12 +189,58 @@ MyClass mc3 = mc.MoveAssign(mc); // Use of mc again will fail
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
<b>Compatibility note:</b>
|
||||
SWIG-4.1.0 changed the way that rvalue references were handled and implemented typemaps assuming that the
|
||||
proxy class would transfer ownership of the underlying C++ object when a function/constructor with an rvalue reference parameter was called.
|
||||
It is of course perfectly possible in C++ for a function/constructor to not move an object passed to it in an rvalue reference parameter. The assumption that SWIG makes would then not hold and customisation of the appropriate input typemaps would be required.
|
||||
For scripting languages, this would be for the 'in' typemap and for the non-scripting languages additional typemaps such as the 'javain' typemap, which is used to set the memory ownership of the underlying C++ object for Java, would also need copying and modifying appropriately.
|
||||
</p>
|
||||
|
||||
<H4><a name="CPlusPlus11_move_only">7.2.1.1 Movable and move-only types</a></H4>
|
||||
<p>
|
||||
<b>Compatibility note:</b>
|
||||
SWIG-4.1.0 changed the way that rvalue reference parameters were handled and implemented typemaps assuming that the
|
||||
proxy class owns the underlying C++ object and transfers ownership of the object when a function/constructor with an rvalue reference parameter is called.
|
||||
</p>
|
||||
|
||||
<H4><a name="CPlusPlus11_rvalue_reference_outputs">7.2.1.2 Rvalue reference outputs</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
While rvalue reference parameter inputs are not uncommon in C++ and can be usefully utilised from target languages, this cannot be said for rvalue reference outputs.
|
||||
Firstly, it is quite unusual in C++ to have functions that return an rvalue reference.
|
||||
Secondly, these cases are nigh on impossible to use from a target language.
|
||||
The main problem is these references are for C++ compiler temporaries used on the stack and the target languages use objects on the heap
|
||||
and the concept of compiler temporary objects doesn't make sense from another language.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using <tt>MyClass</tt> from earlier and this C++ code:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
void use(MyClass &&mc);
|
||||
MyClass && get1();
|
||||
MyClass & get2();
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
SWIG wraps the <tt>get1</tt> and <tt>get2</tt> functions more or less identically.
|
||||
The returned references are converted into pointers that are not owned by the target language.
|
||||
It means that the following perfectly valid C++ has no equivalent in any of the target languages:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
use(get1());
|
||||
use(std::move(get2()));
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
An attempt to call the equivalent <tt>use(get1())</tt> from one of the target languages will result in the ownership failure mentioned in the previous section as the object being passed to the <tt>use</tt> function is not owned by the proxy class.
|
||||
In order to own the object, it would need to be cloned for the object to move from the stack to the heap, for which an appropriate clone function would be required, but may not even be available.
|
||||
Note that a move constructor or copy constructor may slice the object when inheritance is involved.
|
||||
Alternatively, customising the input rvalue reference typemap, as mentioned in the previous section, could remove the ownership requirement.
|
||||
Another alternative would be to modify the output rvalue reference typemap to always clone the rvalue reference object.
|
||||
Fortunately you're highly unlikely to have to solve any of these issues!
|
||||
</p>
|
||||
|
||||
<H4><a name="CPlusPlus11_move_only">7.2.1.3 Movable and move-only types</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
@ -298,6 +298,8 @@
|
|||
<ul>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
|
||||
<ul>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types</a>
|
||||
</ul>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
|
||||
|
|
|
@ -609,7 +609,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_rvalue_reference \
|
||||
cpp11_rvalue_reference2 \
|
||||
cpp11_rvalue_reference3 \
|
||||
cpp11_rvalue_reference_move_input \
|
||||
cpp11_rvalue_reference_move \
|
||||
cpp11_sizeof_object \
|
||||
cpp11_static_assert \
|
||||
cpp11_std_array \
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
%module cpp11_rvalue_reference_move
|
||||
|
||||
// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
|
||||
|
||||
%include "cpp11_move_only_helper.i"
|
||||
|
||||
%catches(std::string) MovableCopyable::check_numbers_match;
|
||||
|
||||
%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
|
||||
%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
|
||||
%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
|
||||
|
||||
%inline %{
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool trace = false;
|
||||
|
||||
class MovableCopyable {
|
||||
int num;
|
||||
public:
|
||||
MovableCopyable(int i = 0) : num(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
|
||||
|
||||
MovableCopyable(const MovableCopyable &other) : num(other.num) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
|
||||
MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; num = other.num; return *this; }
|
||||
|
||||
MovableCopyable(MovableCopyable &&other) noexcept : num(std::move(other.num)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
|
||||
MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; num = std::move(other.num); return *this; }
|
||||
~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
|
||||
|
||||
int getNum() { return num; }
|
||||
|
||||
static void movein(MovableCopyable &&mcin) {
|
||||
MovableCopyable mc = std::move(mcin);
|
||||
}
|
||||
|
||||
static MovableCopyable && moveout(int i) {
|
||||
static MovableCopyable instance;
|
||||
instance = MovableCopyable(i);
|
||||
return std::move(instance);
|
||||
}
|
||||
|
||||
static bool is_nullptr(MovableCopyable *p) {
|
||||
return p == nullptr;
|
||||
}
|
||||
|
||||
static void check_numbers_match(MovableCopyable *p, int expected_num) {
|
||||
if (p->num != expected_num)
|
||||
throw std::string("Numbers don't match");
|
||||
}
|
||||
};
|
||||
%}
|
|
@ -1,37 +0,0 @@
|
|||
%module cpp11_rvalue_reference_move_input
|
||||
|
||||
// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
|
||||
|
||||
%include "cpp11_move_only_helper.i"
|
||||
|
||||
%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
|
||||
%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
|
||||
%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
|
||||
|
||||
%inline %{
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool trace = false;
|
||||
|
||||
class MovableCopyable {
|
||||
public:
|
||||
MovableCopyable(int i = 0) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
|
||||
|
||||
MovableCopyable(const MovableCopyable &other) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
|
||||
MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
|
||||
|
||||
MovableCopyable(MovableCopyable &&other) noexcept { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
|
||||
MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
|
||||
~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
|
||||
|
||||
static void movein(MovableCopyable &&mcin) {
|
||||
MovableCopyable mc = std::move(mcin);
|
||||
}
|
||||
|
||||
static bool is_nullptr(MovableCopyable *p) {
|
||||
return p == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
%}
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using cpp11_rvalue_reference_move_inputNamespace;
|
||||
using cpp11_rvalue_reference_moveNamespace;
|
||||
|
||||
public class cpp11_rvalue_reference_move_input_runme {
|
||||
public class cpp11_rvalue_reference_move_runme {
|
||||
public static void Main() {
|
||||
{
|
||||
// Function containing rvalue reference parameter
|
||||
|
@ -62,5 +62,25 @@ public class cpp11_rvalue_reference_move_input_runme {
|
|||
throw new ApplicationException("Should have thrown null error");
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// output
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mc = MovableCopyable.moveout(1234);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
bool exception_thrown = false;
|
||||
try {
|
||||
MovableCopyable.movein(mc);
|
||||
} catch (ApplicationException e) {
|
||||
if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
|
||||
throw new ApplicationException("incorrect exception message");
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
module cpp11_rvalue_reference_move_input_runme;
|
||||
module cpp11_rvalue_reference_move_runme;
|
||||
|
||||
import cpp11_rvalue_reference_move_input.Counter;
|
||||
import cpp11_rvalue_reference_move_input.MovableCopyable;
|
||||
import cpp11_rvalue_reference_move.Counter;
|
||||
import cpp11_rvalue_reference_move.MovableCopyable;
|
||||
|
||||
void main() {
|
||||
{
|
||||
|
@ -63,4 +63,24 @@ void main() {
|
|||
throw new Exception("Should have thrown null error");
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// output
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mc = MovableCopyable.moveout(1234);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
bool exception_thrown = false;
|
||||
try {
|
||||
MovableCopyable.movein(mc);
|
||||
} catch (Exception e) {
|
||||
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
|
||||
throw new Exception("incorrect exception message: " ~ e.msg);
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
module cpp11_rvalue_reference_move_input_runme;
|
||||
module cpp11_rvalue_reference_move_runme;
|
||||
|
||||
import cpp11_rvalue_reference_move_input.Counter;
|
||||
import cpp11_rvalue_reference_move_input.MovableCopyable;
|
||||
import cpp11_rvalue_reference_move.Counter;
|
||||
import cpp11_rvalue_reference_move.MovableCopyable;
|
||||
import std.algorithm;
|
||||
|
||||
void main() {
|
||||
|
@ -64,4 +64,24 @@ void main() {
|
|||
throw new Exception("Should have thrown null error");
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// output
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mc = MovableCopyable.moveout(1234);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
bool exception_thrown = false;
|
||||
try {
|
||||
MovableCopyable.movein(mc);
|
||||
} catch (Exception e) {
|
||||
if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
|
||||
throw new Exception("incorrect exception message: " ~ e.msg);
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
(dynamic-call "scm_init_cpp11_rvalue_reference_move_input_module" (dynamic-link "./libcpp11_rvalue_reference_move_input"))
|
||||
(load "testsuite.scm")
|
||||
(load "../schemerunme/cpp11_rvalue_reference_move_input.scm")
|
|
@ -0,0 +1,3 @@
|
|||
(dynamic-call "scm_init_cpp11_rvalue_reference_move_module" (dynamic-link "./libcpp11_rvalue_reference_move"))
|
||||
(load "testsuite.scm")
|
||||
(load "../schemerunme/cpp11_rvalue_reference_move.scm")
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
import cpp11_rvalue_reference_move_input.*;
|
||||
import cpp11_rvalue_reference_move.*;
|
||||
|
||||
public class cpp11_rvalue_reference_move_input_runme {
|
||||
public class cpp11_rvalue_reference_move_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_rvalue_reference_move_input");
|
||||
System.loadLibrary("cpp11_rvalue_reference_move");
|
||||
} 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);
|
||||
|
@ -73,5 +73,25 @@ public class cpp11_rvalue_reference_move_input_runme {
|
|||
throw new RuntimeException("Should have thrown null error");
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// output
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mc = MovableCopyable.moveout(1234);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
boolean exception_thrown = false;
|
||||
try {
|
||||
MovableCopyable.movein(mc);
|
||||
} catch (RuntimeException e) {
|
||||
if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
|
||||
throw new RuntimeException("incorrect exception message");
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
var cpp11_rvalue_reference_move_input = require("cpp11_rvalue_reference_move_input");
|
||||
|
||||
{
|
||||
// Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts();
|
||||
mo = new cpp11_rvalue_reference_move_input.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo;
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// Move constructor test
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts();
|
||||
mo = new cpp11_rvalue_reference_move_input.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
mo_moved = new cpp11_rvalue_reference_move_input.MovableCopyable(mo);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo;
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
// delete mo_moved;
|
||||
// cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
// Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo_moved);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 2, 0, 3);
|
||||
}
|
||||
|
||||
{
|
||||
// Move assignment operator test
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts();
|
||||
mo111 = new cpp11_rvalue_reference_move_input.MovableCopyable(111);
|
||||
mo222 = new cpp11_rvalue_reference_move_input.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 0, 0);
|
||||
mo111.MoveAssign(mo222);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
if (!cpp11_rvalue_reference_move_input.MovableCopyable.is_nullptr(mo222))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo222;
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
// delete mo111;
|
||||
// cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 2);
|
||||
// Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo111);
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 1, 1, 3);
|
||||
}
|
||||
|
||||
{
|
||||
// null check
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts();
|
||||
exception_thrown = false;
|
||||
try {
|
||||
cpp11_rvalue_reference_move_input.MovableCopyable.movein(null);
|
||||
} catch (e) {
|
||||
if (!e.message.includes("invalid null reference"))
|
||||
throw new Error("incorrect exception message " + e.message);
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new Error("Should have thrown null error");
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
var cpp11_rvalue_reference_move = require("cpp11_rvalue_reference_move");
|
||||
|
||||
{
|
||||
// Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts();
|
||||
mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(mo);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo;
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// Move constructor test
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts();
|
||||
mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
mo_moved = new cpp11_rvalue_reference_move.MovableCopyable(mo);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo;
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
// delete mo_moved;
|
||||
// cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
// Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(mo_moved);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 2, 0, 3);
|
||||
}
|
||||
|
||||
{
|
||||
// Move assignment operator test
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts();
|
||||
mo111 = new cpp11_rvalue_reference_move.MovableCopyable(111);
|
||||
mo222 = new cpp11_rvalue_reference_move.MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0);
|
||||
mo111.MoveAssign(mo222);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo222))
|
||||
throw new Error("is_nullptr failed");
|
||||
delete mo222;
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
// delete mo111;
|
||||
// cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2);
|
||||
// Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(mo111);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 1, 1, 3);
|
||||
}
|
||||
|
||||
{
|
||||
// null check
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts();
|
||||
exception_thrown = false;
|
||||
try {
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(null);
|
||||
} catch (e) {
|
||||
if (!e.message.includes("invalid null reference"))
|
||||
throw new Error("incorrect exception message " + e.message);
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new Error("Should have thrown null error");
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// output
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts();
|
||||
var mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234);
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
exception_thrown = false;
|
||||
try {
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(mc);
|
||||
} catch (e) {
|
||||
if (!e.message.includes("cannot release ownership as memory is not owned"))
|
||||
throw new Error("incorrect exception message " + e.message);
|
||||
exception_thrown = true;
|
||||
}
|
||||
if (!exception_thrown)
|
||||
throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
require("import") -- the import fn
|
||||
import("cpp11_rvalue_reference_move_input") -- import code
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
-- Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts()
|
||||
mo = cpp11_rvalue_reference_move_input.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
cpp11_rvalue_reference_move_input.MovableCopyable.movein(mo)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo = nil
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
-- Move constructor test
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts()
|
||||
mo = cpp11_rvalue_reference_move_input.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
mo_moved = cpp11_rvalue_reference_move_input.MovableCopyable(mo)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo = nil
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
mo_moved = nil
|
||||
collectgarbage() -- gc nudge needed here
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
-- Move assignment operator test
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts()
|
||||
mo111 = cpp11_rvalue_reference_move_input.MovableCopyable(111)
|
||||
mo222 = cpp11_rvalue_reference_move_input.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 0, 0)
|
||||
mo111:MoveAssign(mo222)
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
if not (cpp11_rvalue_reference_move_input.MovableCopyable_is_nullptr(mo222)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo222 = nil
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
mo111 = nil
|
||||
collectgarbage() -- gc nudge needed here
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(2, 0, 0, 0, 1, 2)
|
||||
|
||||
-- null check
|
||||
cpp11_rvalue_reference_move_input.Counter.reset_counts()
|
||||
s, msg = pcall(function() cpp11_rvalue_reference_move_input.MovableCopyable.movein(nil) end)
|
||||
assert(s == false and msg:find("Error in MovableCopyable::movein (arg 1), expected 'MovableCopyable &&' got 'nil'", 1, true))
|
||||
cpp11_rvalue_reference_move_input.Counter.check_counts(0, 0, 0, 0, 0, 0)
|
|
@ -0,0 +1,66 @@
|
|||
require("import") -- the import fn
|
||||
import("cpp11_rvalue_reference_move") -- import code
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
-- Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts()
|
||||
mo = cpp11_rvalue_reference_move.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
cpp11_rvalue_reference_move.MovableCopyable.movein(mo)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo = nil
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
-- Move constructor test
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts()
|
||||
mo = cpp11_rvalue_reference_move.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
mo_moved = cpp11_rvalue_reference_move.MovableCopyable(mo)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo = nil
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
mo_moved = nil
|
||||
collectgarbage() -- gc nudge needed here
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
-- Move assignment operator test
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts()
|
||||
mo111 = cpp11_rvalue_reference_move.MovableCopyable(111)
|
||||
mo222 = cpp11_rvalue_reference_move.MovableCopyable(222)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0)
|
||||
mo111:MoveAssign(mo222)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo222)) then
|
||||
error("is_nullptr failed")
|
||||
end
|
||||
mo222 = nil
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
mo111 = nil
|
||||
collectgarbage() -- gc nudge needed here
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2)
|
||||
|
||||
-- null check
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts()
|
||||
s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(nil) end)
|
||||
assert(s == false and msg:find("Error in MovableCopyable::movein (arg 1), expected 'MovableCopyable &&' got 'nil'", 1, true))
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0)
|
||||
|
||||
-- output
|
||||
cpp11_rvalue_reference_move.Counter.reset_counts()
|
||||
mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234)
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234)
|
||||
|
||||
s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(mc) end)
|
||||
assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
|
||||
cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
|
|
@ -1,7 +1,7 @@
|
|||
(load-extension "cpp11_rvalue_reference_move_input.so")
|
||||
(load-extension "cpp11_rvalue_reference_move.so")
|
||||
(require (lib "defmacro.ss"))
|
||||
|
||||
; Copied from ../schemerunme/cpp11_rvalue_reference_move_input.scm and modified for exceptions
|
||||
; Copied from ../schemerunme/cpp11_rvalue_reference_move.scm and modified for exceptions
|
||||
|
||||
; Function containing rvalue reference parameter
|
||||
(Counter-reset-counts)
|
||||
|
@ -51,4 +51,18 @@
|
|||
(error (format "incorrect exception message: ~a" exception_thrown)))
|
||||
(Counter-check-counts 0 0 0 0 0 0)
|
||||
|
||||
; output
|
||||
(Counter-reset-counts)
|
||||
(define mc (MovableCopyable-moveout 1234))
|
||||
(Counter-check-counts 2 0 0 0 1 1)
|
||||
(MovableCopyable-check-numbers-match mc 1234)
|
||||
|
||||
(define exception_thrown "no exception thrown for kin")
|
||||
(with-handlers ([exn:fail? (lambda (exn)
|
||||
(set! exception_thrown (exn-message exn)))])
|
||||
(MovableCopyable-movein mc))
|
||||
(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
|
||||
(error (format "incorrect exception message: ~a" exception_thrown)))
|
||||
(Counter-check-counts 2 0 0 0 1 1)
|
||||
|
||||
(exit 0)
|
|
@ -3,7 +3,7 @@ if exist("crash_dumps_octave_core", "builtin")
|
|||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
cpp11_rvalue_reference_move_input
|
||||
cpp11_rvalue_reference_move
|
||||
|
||||
# Function containing rvalue reference parameter
|
||||
Counter.reset_counts();
|
||||
|
@ -62,3 +62,24 @@ if (!exception_thrown)
|
|||
error("Should have thrown null error");
|
||||
endif
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0);
|
||||
|
||||
|
||||
# output
|
||||
Counter.reset_counts();
|
||||
mc = MovableCopyable.moveout(1234);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable.check_numbers_match(mc, 1234);
|
||||
|
||||
exception_thrown = false;
|
||||
try
|
||||
MovableCopyable.movein(mc);
|
||||
catch e
|
||||
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
|
||||
error("incorrect exception message: %s", e.message)
|
||||
endif
|
||||
exception_thrown = true;
|
||||
end_try_catch
|
||||
if (!exception_thrown)
|
||||
error("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
endif
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
|
@ -1,56 +0,0 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 6;
|
||||
BEGIN { use_ok('cpp11_rvalue_reference_move_input') }
|
||||
require_ok('cpp11_rvalue_reference_move_input');
|
||||
|
||||
{
|
||||
# Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move_input::Counter::reset_counts();
|
||||
my $mo = new cpp11_rvalue_reference_move_input::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 0, 0, 0);
|
||||
cpp11_rvalue_reference_move_input::MovableCopyable::movein($mo);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
|
||||
undef $mo;
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# Move constructor test
|
||||
cpp11_rvalue_reference_move_input::Counter::reset_counts();
|
||||
my $mo = new cpp11_rvalue_reference_move_input::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 0, 0, 0);
|
||||
my $mo_moved = new cpp11_rvalue_reference_move_input::MovableCopyable($mo);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 1);
|
||||
is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
|
||||
undef $mo;
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 1);
|
||||
undef $mo_moved;
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# Move assignment operator test
|
||||
cpp11_rvalue_reference_move_input::Counter::reset_counts();
|
||||
my $mo111 = new cpp11_rvalue_reference_move_input::MovableCopyable(111);
|
||||
my $mo222 = new cpp11_rvalue_reference_move_input::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 0, 0);
|
||||
$mo111->MoveAssign($mo222);
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
is(cpp11_rvalue_reference_move_input::MovableCopyable::is_nullptr($mo222), 1, "is_nullptr check");
|
||||
undef $mo222;
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
undef $mo111;
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(2, 0, 0, 0, 1, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# null check
|
||||
cpp11_rvalue_reference_move_input::Counter::reset_counts();
|
||||
eval {
|
||||
cpp11_rvalue_reference_move_input::MovableCopyable::movein(undef);
|
||||
};
|
||||
like($@, qr/\binvalid null reference/, "Should have thrown null error");
|
||||
cpp11_rvalue_reference_move_input::Counter::check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 7;
|
||||
BEGIN { use_ok('cpp11_rvalue_reference_move') }
|
||||
require_ok('cpp11_rvalue_reference_move');
|
||||
|
||||
{
|
||||
# Function containing rvalue reference parameter
|
||||
cpp11_rvalue_reference_move::Counter::reset_counts();
|
||||
my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
|
||||
cpp11_rvalue_reference_move::MovableCopyable::movein($mo);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
|
||||
undef $mo;
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# Move constructor test
|
||||
cpp11_rvalue_reference_move::Counter::reset_counts();
|
||||
my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
|
||||
my $mo_moved = new cpp11_rvalue_reference_move::MovableCopyable($mo);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
|
||||
is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
|
||||
undef $mo;
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
|
||||
undef $mo_moved;
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# Move assignment operator test
|
||||
cpp11_rvalue_reference_move::Counter::reset_counts();
|
||||
my $mo111 = new cpp11_rvalue_reference_move::MovableCopyable(111);
|
||||
my $mo222 = new cpp11_rvalue_reference_move::MovableCopyable(222);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 0, 0);
|
||||
$mo111->MoveAssign($mo222);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo222), 1, "is_nullptr check");
|
||||
undef $mo222;
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
undef $mo111;
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 2);
|
||||
}
|
||||
|
||||
{
|
||||
# null check
|
||||
cpp11_rvalue_reference_move::Counter::reset_counts();
|
||||
eval {
|
||||
cpp11_rvalue_reference_move::MovableCopyable::movein(undef);
|
||||
};
|
||||
like($@, qr/\binvalid null reference/, "Should have thrown null error");
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
{
|
||||
# output
|
||||
cpp11_rvalue_reference_move::Counter::reset_counts();
|
||||
my $mc = cpp11_rvalue_reference_move::MovableCopyable::moveout(1234);
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
cpp11_rvalue_reference_move::MovableCopyable::check_numbers_match($mc, 1234);
|
||||
|
||||
eval {
|
||||
cpp11_rvalue_reference_move::MovableCopyable::movein($mc);
|
||||
};
|
||||
like($@, qr/\bcannot release ownership as memory is not owned\b/, "Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
}
|
|
@ -61,4 +61,20 @@ try {
|
|||
check::equal($exception_thrown, true, "Should have thrown null error");
|
||||
Counter::check_counts(0, 0, 0, 0, 0, 0);
|
||||
|
||||
# output
|
||||
Counter::reset_counts();
|
||||
$mc = MovableCopyable::moveout(1234);
|
||||
Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
MovableCopyable::check_numbers_match($mc, 1234);
|
||||
|
||||
$exception_thrown = false;
|
||||
try {
|
||||
MovableCopyable::movein($mc);
|
||||
} catch (TypeError $e) {
|
||||
check::str_contains($e->getMessage(), "Cannot release ownership as memory is not owned", "incorrect exception message: {$e->getMessage()}");
|
||||
$exception_thrown = true;
|
||||
}
|
||||
check::equal($exception_thrown, true, "Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||
Counter::check_counts(2, 0, 0, 0, 1, 1);
|
||||
|
||||
check::done();
|
|
@ -1,4 +1,4 @@
|
|||
from cpp11_rvalue_reference_move_input import *
|
||||
from cpp11_rvalue_reference_move import *
|
||||
|
||||
# Function containing rvalue reference parameter
|
||||
Counter.reset_counts()
|
||||
|
@ -50,3 +50,20 @@ except ValueError as e:
|
|||
if not exception_thrown:
|
||||
raise RuntimeError("Should have thrown null error")
|
||||
Counter.check_counts(0, 0, 0, 0, 0, 0)
|
||||
|
||||
# output
|
||||
Counter.reset_counts()
|
||||
mc = MovableCopyable.moveout(1234)
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
MovableCopyable.check_numbers_match(mc, 1234)
|
||||
|
||||
exception_thrown = False
|
||||
try:
|
||||
MovableCopyable.movein(mc)
|
||||
except RuntimeError as e:
|
||||
if "cannot release ownership as memory is not owned" not in str(e):
|
||||
raise RuntimeError("incorrect exception message:" + str(e))
|
||||
exception_thrown = True
|
||||
if not exception_thrown:
|
||||
raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1)
|
|
@ -4,25 +4,24 @@ a = cpp11_rvalue_reference.A()
|
|||
|
||||
a.setAcopy(5)
|
||||
if a.getAcopy() != 5:
|
||||
raise RunTimeError("int A::getAcopy() value is ",
|
||||
raise RuntimeError("int A::getAcopy() value is ",
|
||||
a.getAcopy(), " should be 5")
|
||||
|
||||
ptr = a.getAptr()
|
||||
|
||||
a.setAptr(ptr)
|
||||
if a.getAcopy() != 5:
|
||||
raise RunTimeError("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
|
||||
raise RuntimeError("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
|
||||
), " should be 5")
|
||||
|
||||
a.setAref(ptr)
|
||||
if a.getAcopy() != 5:
|
||||
raise RunTimeError("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
|
||||
raise RuntimeError("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
|
||||
), " should be 5")
|
||||
|
||||
rvalueref = a.getAmove()
|
||||
|
||||
# WIP: out rvalue references not yet modified for taking ownership
|
||||
# a.setAmove(rvalueref)
|
||||
# if a.getAcopy() != 5:
|
||||
# raise RunTimeError("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
|
||||
# ), " should be 5")
|
||||
a.setAref(rvalueref)
|
||||
if a.getAcopy() != 5:
|
||||
raise RuntimeError("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
|
||||
), " should be 5")
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'swig_assert'
|
||||
|
||||
require 'cpp11_rvalue_reference_move_input'
|
||||
|
||||
# Function containing rvalue reference parameter
|
||||
Cpp11_rvalue_reference_move_input::Counter.reset_counts()
|
||||
mo = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo = nil
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
# Move constructor test
|
||||
Cpp11_rvalue_reference_move_input::Counter.reset_counts()
|
||||
mo = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
mo_moved = Cpp11_rvalue_reference_move_input::MovableCopyable.new(mo)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo = nil
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
# mo_moved = nil
|
||||
# Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo_moved)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(1, 0, 0, 2, 0, 3)
|
||||
|
||||
# Move assignment operator test
|
||||
Cpp11_rvalue_reference_move_input::Counter.reset_counts()
|
||||
mo111 = Cpp11_rvalue_reference_move_input::MovableCopyable.new(111)
|
||||
mo222 = Cpp11_rvalue_reference_move_input::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 0, 0)
|
||||
mo111.MoveAssign(mo222)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.is_nullptr(mo222)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo222 = nil
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
# mo111 = nil
|
||||
# Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 0, 1, 2)
|
||||
# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.movein(mo111)
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(2, 0, 0, 1, 1, 3)
|
||||
|
||||
# null check
|
||||
Cpp11_rvalue_reference_move_input::Counter.reset_counts()
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move_input::MovableCopyable.movein(nil)
|
||||
rescue ArgumentError => e
|
||||
if (!e.to_s.include? "invalid null reference")
|
||||
raise RuntimeError, "incorrect exception message: #{e.to_s}"
|
||||
end
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "Should have thrown null error"
|
||||
end
|
||||
Cpp11_rvalue_reference_move_input::Counter.check_counts(0, 0, 0, 0, 0, 0)
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'swig_assert'
|
||||
|
||||
require 'cpp11_rvalue_reference_move'
|
||||
|
||||
# Function containing rvalue reference parameter
|
||||
Cpp11_rvalue_reference_move::Counter.reset_counts()
|
||||
mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.movein(mo)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo = nil
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
|
||||
# Move constructor test
|
||||
Cpp11_rvalue_reference_move::Counter.reset_counts()
|
||||
mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
|
||||
mo_moved = Cpp11_rvalue_reference_move::MovableCopyable.new(mo)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo = nil
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
|
||||
# mo_moved = nil
|
||||
# Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
|
||||
# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.movein(mo_moved)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 2, 0, 3)
|
||||
|
||||
# Move assignment operator test
|
||||
Cpp11_rvalue_reference_move::Counter.reset_counts()
|
||||
mo111 = Cpp11_rvalue_reference_move::MovableCopyable.new(111)
|
||||
mo222 = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 0, 0)
|
||||
mo111.MoveAssign(mo222)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo222)
|
||||
rescue ObjectPreviouslyDeleted
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "is_nullptr failed to throw"
|
||||
end
|
||||
mo222 = nil
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
# mo111 = nil
|
||||
# Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 2)
|
||||
# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.movein(mo111)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 1, 1, 3)
|
||||
|
||||
# null check
|
||||
Cpp11_rvalue_reference_move::Counter.reset_counts()
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.movein(nil)
|
||||
rescue ArgumentError => e
|
||||
if (!e.to_s.include? "invalid null reference")
|
||||
raise RuntimeError, "incorrect exception message: #{e.to_s}"
|
||||
end
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "Should have thrown null error"
|
||||
end
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(0, 0, 0, 0, 0, 0)
|
||||
|
||||
# output
|
||||
Cpp11_rvalue_reference_move::Counter.reset_counts()
|
||||
mc = Cpp11_rvalue_reference_move::MovableCopyable.moveout(1234)
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.check_numbers_match(mc, 1234)
|
||||
|
||||
exception_thrown = false
|
||||
begin
|
||||
Cpp11_rvalue_reference_move::MovableCopyable.movein(mc)
|
||||
rescue RuntimeError => e
|
||||
if (!e.to_s.include? "cannot release ownership as memory is not owned")
|
||||
raise RuntimeError, "incorrect exception message: #{e.to_s}"
|
||||
end
|
||||
exception_thrown = true
|
||||
end
|
||||
if (!exception_thrown)
|
||||
raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
|
||||
end
|
||||
Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
|
|
@ -43,4 +43,15 @@
|
|||
; TODO: check the exception message
|
||||
(Counter-check-counts 0 0 0 0 0 0)
|
||||
|
||||
; output
|
||||
(Counter-reset-counts)
|
||||
(define mc (MovableCopyable-moveout 1234))
|
||||
(Counter-check-counts 2 0 0 0 1 1)
|
||||
(MovableCopyable-check-numbers-match mc 1234)
|
||||
|
||||
(expect-throw 'misc-error
|
||||
(MovableCopyable-movein mc))
|
||||
; TODO: check the exception message
|
||||
(Counter-check-counts 2 0 0 0 1 1)
|
||||
|
||||
(exit 0)
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
if [ catch { load ./cpp11_rvalue_reference_move_input[info sharedlibextension] cpp11_rvalue_reference_move_input} err_msg ] {
|
||||
if [ catch { load ./cpp11_rvalue_reference_move[info sharedlibextension] cpp11_rvalue_reference_move} err_msg ] {
|
||||
puts stderr "Could not load shared object:\n$err_msg"
|
||||
}
|
||||
|
||||
|
@ -60,3 +60,23 @@ if {!$exception_thrown} {
|
|||
error "Should have thrown null error"
|
||||
}
|
||||
Counter_check_counts 0 0 0 0 0 0
|
||||
|
||||
# output
|
||||
Counter_reset_counts
|
||||
set mc [MovableCopyable_moveout 1234]
|
||||
Counter_check_counts 2 0 0 0 1 1
|
||||
MovableCopyable_check_numbers_match $mc 1234
|
||||
|
||||
set exception_thrown 0
|
||||
if [ catch {
|
||||
MovableCopyable_movein $mc
|
||||
} e ] {
|
||||
if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
|
||||
error "incorrect exception message: $e"
|
||||
}
|
||||
set exception_thrown 1
|
||||
}
|
||||
if {!$exception_thrown} {
|
||||
error "Should have thrown 'Cannot release ownership as memory is not owned' error"
|
||||
}
|
||||
Counter_check_counts 2 0 0 0 1 1
|
Loading…
Reference in New Issue