Avoid an issue with virtual functions

Reimplementing virtual functions with
"const &" arguments wasn't behaving as
expected because these arguments were
copied.

Now, "const &" for arguments (in virtual
function reimplementation) is not implemented
as a copy.

In addition, now it's possible to declare
results as references always (also if const &).

See gsiTest.cc:1078 for example:

  //  gsi::arg_make_reference makes the function's return value
  //  always being taken as a reference
  gsi::method<C_P, const CopyDetector &, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_cref_as_ref", &C_P::pass_cd_cref)
This commit is contained in:
Matthias Koefferlein
2019-01-31 01:07:15 +01:00
parent 4068478887
commit 30e26c4f96
10 changed files with 539 additions and 76 deletions
+74
View File
@@ -73,6 +73,14 @@ class C_IMP2(pya.C):
class C_IMP3(pya.C):
anything = None
class C_IMP4(pya.C):
def __init__(self):
self.x = None
self.xx = None
def vfunc(self, cd):
self.x = cd.x()
self.xx = cd.xx()
class Z_IMP1(pya.Z):
def f(self, x):
return x.cls_name()
@@ -1072,6 +1080,11 @@ class BasicTest(unittest.TestCase):
arr.append(i)
self.assertEqual( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
c4 = C_IMP4()
c4.call_vfunc(pya.CopyDetector(17))
self.assertEqual(c4.x, 17)
self.assertEqual(c4.xx, 17)
def test_20(self):
b = pya.B()
@@ -1538,6 +1551,67 @@ class BasicTest(unittest.TestCase):
b = None
self.assertEqual(pya.B.has_inst(), False)
def test_29(self):
# copy/ref semantics on return
c = pya.C()
cd = pya.CopyDetector(42)
cd2 = c.pass_cd_direct(cd)
self.assertEqual(cd2.x(), 42)
# two copies: one for return statement and then one for the new object
self.assertEqual(cd2.xx(), 44)
cd2 = c.pass_cd_cref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 43)
cd2 = c.pass_cd_cref_as_copy(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 43)
cd2 = c.pass_cd_cref_as_ref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_cptr(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_cptr_as_copy(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 43)
cd2 = c.pass_cd_cptr_as_ref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_ptr(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_ptr_as_copy(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 43)
cd2 = c.pass_cd_ptr_as_ref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_ref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
cd2 = c.pass_cd_ref_as_copy(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 43)
cd2 = c.pass_cd_ref_as_ref(cd)
self.assertEqual(cd2.x(), 42)
self.assertEqual(cd2.xx(), 42)
def test_30(self):
# some basic tests for the *Value boxing classes
+84
View File
@@ -936,6 +936,22 @@ class Basic_TestClass < TestBase
class C_IMP3 < RBA::C
end
class C_IMP4 < RBA::C
def initialize
@x = @xx = nil
end
def x
@x
end
def xx
@xx
end
def vfunc(cd)
@x = cd.x
@xx = cd.xx
end
end
def test_19
c0 = RBA::C.new
@@ -978,6 +994,11 @@ class Basic_TestClass < TestBase
C_IMP2.each { |i| arr.push i }
assert_equal( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
c4 = C_IMP4.new
c4.call_vfunc(RBA::CopyDetector::new(17))
assert_equal(c4.x, 17)
assert_equal(c4.xx, 17)
end
def test_20
@@ -1414,6 +1435,69 @@ class Basic_TestClass < TestBase
end
def test_29
# copy/ref semantics on return
c = RBA::C::new
cd = RBA::CopyDetector::new(42)
cd2 = c.pass_cd_direct(cd)
assert_equal(cd2.x, 42)
# two copies: one for return statement and then one for the new object
assert_equal(cd2.xx, 44)
cd2 = c.pass_cd_cref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 43)
cd2 = c.pass_cd_cref_as_copy(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 43)
cd2 = c.pass_cd_cref_as_ref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_cptr(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_cptr_as_copy(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 43)
cd2 = c.pass_cd_cptr_as_ref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_ptr(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_ptr_as_copy(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 43)
cd2 = c.pass_cd_ptr_as_ref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_ref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
cd2 = c.pass_cd_ref_as_copy(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 43)
cd2 = c.pass_cd_ref_as_ref(cd)
assert_equal(cd2.x, 42)
assert_equal(cd2.xx, 42)
end
def test_30
# some basic tests for the *Value boxing classes