From: Robert Bradshaw Date: Fri, 15 Jan 2010 07:24:58 +0000 (-0800) Subject: C++ templating fixes. X-Git-Tag: 0.13.beta0~353^2~15 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5b2f63ca1530c16e46d4aca8ad5cfa8677066fab;p=cython.git C++ templating fixes. --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 6d13154a..46bd6d74 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -477,6 +477,19 @@ class CArrayDeclaratorNode(CDeclaratorNode): child_attrs = ["base", "dimension"] def analyse(self, base_type, env, nonempty = 0): + if base_type.is_cpp_class: + from ExprNodes import TupleNode + if isinstance(self.dimension, TupleNode): + args = self.dimension.args + else: + args = self.dimension, + values = [v.analyse_as_type(env) for v in args] + if None in values: + ix = values.index(None) + error(args[ix].pos, "Template parameter not a type.") + return error_type + base_type = base_type.specialize_here(self.pos, values) + return self.base.analyse(base_type, env, nonempty = nonempty) if self.dimension: self.dimension.analyse_const_expression(env) if not self.dimension.type.is_int: diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index add37a96..dafba8e3 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -1832,6 +1832,7 @@ class CppClassType(CType): self.operators = [] self.templates = templates self.template_type = template_type + self.specializations = {} def specialize_here(self, pos, template_values = None): if self.templates is None: @@ -1844,10 +1845,14 @@ class CppClassType(CType): return self.specialize(dict(zip(self.templates, template_values))) def specialize(self, values): - # TODO(danilo): Cache for efficiency. + key = tuple(values.items()) + if key in self.specializations: + return self.specializations[key] template_values = [t.specialize(values) for t in self.templates] - return CppClassType(self.name, self.scope.specialize(values), self.cname, self.base_classes, - template_values, template_type=self) + specialized = self.specializations[key] = \ + CppClassType(self.name, None, self.cname, self.base_classes, template_values, template_type=self) + specialized.scope = self.scope.specialize(values) + return specialized def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if self.templates: