Commit 5f18de5f authored by gsamain's avatar gsamain

Allow c++ classes to have multiple constructors

parent f62f5ad2
...@@ -918,7 +918,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -918,7 +918,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if attr.type.is_cfunction and attr.type.is_static_method: if attr.type.is_cfunction and attr.type.is_static_method:
code.put("static ") code.put("static ")
elif attr.name == "<init>": elif attr.name == "<init>":
constructor = attr #constructor = attr
constructor = scope.lookup_here("<init>")
elif attr.name == "<del>": elif attr.name == "<del>":
destructor = attr destructor = attr
elif attr.type.is_cfunction: elif attr.type.is_cfunction:
...@@ -926,35 +927,43 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -926,35 +927,43 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
has_virtual_methods = True has_virtual_methods = True
code.putln("%s;" % attr.type.declaration_code(attr.cname)) code.putln("%s;" % attr.type.declaration_code(attr.cname))
is_implementing = 'init_module' in code.globalstate.parts is_implementing = 'init_module' in code.globalstate.parts
def generate_cpp_constructor_code(arg_decls, arg_names, is_implementing, py_attrs, constructor):
if is_implementing:
code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls)))
if py_attrs:
code.put_ensure_gil()
for attr in py_attrs:
code.put_init_var_to_py_none(attr, nanny=False);
if constructor:
code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names)))
if py_attrs:
code.put_release_ensured_gil()
code.putln("}")
else:
code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls)))
if constructor or py_attrs: if constructor or py_attrs:
if constructor: if constructor:
arg_decls = [] for constructor_alternative in constructor.all_alternatives():
arg_names = [] arg_decls = []
for arg in constructor.type.original_args[ arg_names = []
:len(constructor.type.args)-constructor.type.optional_arg_count]: for arg in constructor_alternative.type.original_args[
arg_decls.append(arg.declaration_code()) :len(constructor_alternative.type.args)-constructor_alternative.type.optional_arg_count]:
arg_names.append(arg.cname) arg_decls.append(arg.declaration_code())
if constructor.type.optional_arg_count: arg_names.append(arg.cname)
arg_decls.append(constructor.type.op_arg_struct.declaration_code(Naming.optional_args_cname)) if constructor_alternative.type.optional_arg_count:
arg_names.append(Naming.optional_args_cname) arg_decls.append(constructor_alternative.type.op_arg_struct.declaration_code(Naming.optional_args_cname))
if not arg_decls: arg_names.append(Naming.optional_args_cname)
arg_decls = ["void"] if not arg_decls:
default_constructor = True
arg_decls = ["void"]
generate_cpp_constructor_code(arg_decls, arg_names, is_implementing, py_attrs, constructor_alternative)
else: else:
arg_decls = ["void"] arg_decls = ["void"]
arg_names = [] arg_names = []
if is_implementing: generate_cpp_constructor_code(arg_decls, arg_names, is_implementing, py_attrs, constructor)
code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls)))
if py_attrs:
code.put_ensure_gil()
for attr in py_attrs:
code.put_init_var_to_py_none(attr, nanny=False);
if constructor:
code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names)))
if py_attrs:
code.put_release_ensured_gil()
code.putln("}")
else:
code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls)))
if destructor or py_attrs or has_virtual_methods: if destructor or py_attrs or has_virtual_methods:
if has_virtual_methods: if has_virtual_methods:
code.put("virtual ") code.put("virtual ")
......
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