Commit d01f6d4a authored by Robert Bradshaw's avatar Robert Bradshaw

Avoid copying C++ classes when passing constructor arguments.

parent b6500f58
...@@ -905,7 +905,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -905,7 +905,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if constructor: if constructor:
arg_decls = [] arg_decls = []
arg_names = [] arg_names = []
for arg in constructor.type.args[:len(constructor.type.args)-constructor.type.optional_arg_count]: for arg in constructor.type.original_args[:len(constructor.type.args)-constructor.type.optional_arg_count]:
arg_decls.append(arg.declaration_code()) arg_decls.append(arg.declaration_code())
arg_names.append(arg.cname) arg_names.append(arg.cname)
if constructor.type.optional_arg_count: if constructor.type.optional_arg_count:
......
...@@ -2311,6 +2311,16 @@ class CppClassScope(Scope): ...@@ -2311,6 +2311,16 @@ class CppClassScope(Scope):
cname = "%s__init__%s" % (Naming.func_prefix, class_name) cname = "%s__init__%s" % (Naming.func_prefix, class_name)
name = '<init>' name = '<init>'
type.return_type = PyrexTypes.CVoidType() type.return_type = PyrexTypes.CVoidType()
# This is called by the actual constructor, but need to support
# arguments that cannot by called by value.
type.original_args = type.args
def maybe_ref(arg):
if arg.type.is_cpp_class and not arg.type.is_reference:
return PyrexTypes.CFuncTypeArg(
arg.name, PyrexTypes.c_ref_type(arg.type), arg.pos)
else:
return arg
type.args = [maybe_ref(arg) for arg in type.args]
elif name == '__dealloc__' and cname is None: elif name == '__dealloc__' and cname is None:
cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name) cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name)
name = '<del>' name = '<del>'
......
...@@ -6,6 +6,7 @@ cdef double pi ...@@ -6,6 +6,7 @@ cdef double pi
from math import pi from math import pi
from libc.math cimport sin, cos from libc.math cimport sin, cos
from libcpp cimport bool from libcpp cimport bool
from libcpp.memory cimport unique_ptr
from libcpp.vector cimport vector from libcpp.vector cimport vector
from cython.operator cimport dereference as deref from cython.operator cimport dereference as deref
...@@ -222,3 +223,17 @@ def test_CppClassWithObjectMemberCopyAssign(name): ...@@ -222,3 +223,17 @@ def test_CppClassWithObjectMemberCopyAssign(name):
print "Alive in vector", v[0].o print "Alive in vector", v[0].o
v.clear() v.clear()
print "Nothing alive." print "Nothing alive."
cdef cppclass UncopyableConstructorArgument:
unique_ptr[vector[int]] member
__init__(unique_ptr[vector[int]] arg):
this.member.reset(arg.release())
def test_uncopyable_constructor_argument():
"""
>>> test_uncopyable_constructor_argument()
"""
cdef UncopyableConstructorArgument *c = new UncopyableConstructorArgument(
unique_ptr[vector[int]](new vector[int]()))
del c
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment