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):
if constructor:
arg_decls = []
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_names.append(arg.cname)
if constructor.type.optional_arg_count:
......
......@@ -2311,6 +2311,16 @@ class CppClassScope(Scope):
cname = "%s__init__%s" % (Naming.func_prefix, class_name)
name = '<init>'
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:
cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name)
name = '<del>'
......
......@@ -6,6 +6,7 @@ cdef double pi
from math import pi
from libc.math cimport sin, cos
from libcpp cimport bool
from libcpp.memory cimport unique_ptr
from libcpp.vector cimport vector
from cython.operator cimport dereference as deref
......@@ -222,3 +223,17 @@ def test_CppClassWithObjectMemberCopyAssign(name):
print "Alive in vector", v[0].o
v.clear()
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