1 """Various helpers for instantiation."""
4 from copy
import deepcopy
5 from typing
import List, Sequence, Union
9 ClassMembers = Union[parser.Constructor, parser.Method, parser.StaticMethod,
10 parser.GlobalFunction, parser.Operator, parser.Variable,
12 InstantiatedMembers = Union[
'InstantiatedConstructor',
'InstantiatedMethod',
13 'InstantiatedStaticMethod',
14 'InstantiatedGlobalFunction']
18 str_arg_typename: str):
20 Check if the template given by `str_arg_typename` is a scoped template e.g. T::Value,
21 and if so, return what template from `template_typenames` and
22 the corresponding index matches the scoped template correctly.
24 for idx, template
in enumerate(template_typenames):
25 if "::" in str_arg_typename
and \
26 template
in str_arg_typename.split(
"::"):
33 template_typenames: Sequence[str],
34 instantiations: Sequence[parser.Typename],
35 cpp_typename: parser.Typename,
36 instantiated_class:
'InstantiatedClass' =
None) -> parser.Type:
38 Instantiate template typename for `ctype`.
41 ctype: The original argument type.
42 template_typenames: List of strings representing the templates.
43 instantiations: List of the instantiations of the templates in `template_typenames`.
44 cpp_typename: Full-namespace cpp class name of this instantiation
45 to replace for arguments of type named `This`.
46 instiated_class: The instantiated class which, if provided,
47 will be used for instantiating `This`.
50 If `ctype`'s name is in the `template_typenames`, return the
51 corresponding type to replace in `instantiations`.
52 If ctype name is `This`, return the new typename `cpp_typename`.
53 Otherwise, return the original ctype.
56 ctype = deepcopy(ctype)
59 if ctype.typename.instantiations:
60 for idx, instantiation
in enumerate(ctype.typename.instantiations):
61 if instantiation.name
in template_typenames:
62 template_idx = template_typenames.index(instantiation.name)
63 ctype.typename.instantiations[idx].name =\
64 instantiations[template_idx]
67 str_arg_typename =
str(ctype.typename)
79 instantiation = deepcopy(instantiations[scoped_idx])
81 instantiation.name = str_arg_typename.replace(scoped_template,
84 typename=instantiation,
85 is_const=ctype.is_const,
86 is_shared_ptr=ctype.is_shared_ptr,
89 is_basic=ctype.is_basic,
92 elif str_arg_typename
in template_typenames:
93 idx = template_typenames.index(str_arg_typename)
95 typename=instantiations[idx],
96 is_const=ctype.is_const,
97 is_shared_ptr=ctype.is_shared_ptr,
100 is_basic=ctype.is_basic,
104 elif str_arg_typename ==
'This':
107 if instantiated_class:
108 name = instantiated_class.original.name
109 namespaces_name = instantiated_class.namespaces()
110 namespaces_name.append(name)
111 cpp_typename = parser.Typename(
113 instantiations=instantiated_class.instantiations)
116 typename=cpp_typename,
117 is_const=ctype.is_const,
118 is_shared_ptr=ctype.is_shared_ptr,
121 is_basic=ctype.is_basic,
125 elif 'This' in str_arg_typename:
127 if 'This' in ctype.typename.namespaces:
130 namespace_idx = ctype.typename.namespaces.index(
'This')
131 ctype.typename.namespaces[namespace_idx] = cpp_typename.name
134 for idx, instantiation
in enumerate(ctype.typename.instantiations):
135 if 'This' in instantiation.namespaces:
136 ctype.typename.instantiations[idx].namespaces = \
137 cpp_typename.namespaces + [cpp_typename.name]
145 args_list: Sequence[parser.Argument],
146 template_typenames: Sequence[parser.template.Typename],
147 instantiations: Sequence, cpp_typename: parser.Typename):
149 Instantiate template typenames in an argument list.
150 Type with name `This` will be replaced by @p `cpp_typename`.
152 @param[in] args_list A list of `parser.Argument` to instantiate.
153 @param[in] template_typenames List of template typenames to instantiate,
154 e.g. ['T', 'U', 'V'].
155 @param[in] instantiations List of specific types to instantiate, each
156 associated with each template typename. Each type is a parser.Typename,
157 including its name and full namespaces.
158 @param[in] cpp_typename Full-namespace cpp class name of this instantiation
159 to replace for arguments of type named `This`.
160 @return A new list of parser.Argument which types are replaced with their
163 instantiated_args = []
164 for arg
in args_list:
166 instantiations, cpp_typename)
167 instantiated_args.append(
168 parser.Argument(name=arg.name, ctype=new_type,
169 default=arg.default))
170 return instantiated_args
174 return_type: parser.ReturnType,
175 template_typenames: Sequence[parser.template.Typename],
176 instantiations: Sequence[parser.Typename],
177 cpp_typename: parser.Typename,
178 instantiated_class:
'InstantiatedClass' =
None):
179 """Instantiate the return type."""
184 instantiated_class=instantiated_class)
185 if return_type.type2:
190 instantiated_class=instantiated_class)
193 return parser.ReturnType(new_type1, new_type2)
197 instantiations: Sequence[parser.Typename]):
199 Concatenate instantiated types with `original_name` to form a new
202 NOTE: To avoid conflicts, we should include the instantiation's
203 namespaces, but that is too verbose.
205 instantiated_names = []
206 for inst
in instantiations:
208 name = inst.instantiated_name()
210 instantiated_names.append(name.replace(name[0], name[0].capitalize()))
212 return "{}{}".
format(original_name,
"".join(instantiated_names))
217 Helper class for instantiation templates.
218 Requires that `instantiation_type` defines a class method called
219 `construct` to generate the appropriate object type.
221 Signature for `construct` should be
225 class_instantiations,
226 method_instantiations,
231 def __init__(self, instantiation_type: InstantiatedMembers):
234 def instantiate(self, instantiated_methods: List[InstantiatedMembers],
235 method: ClassMembers, typenames: Sequence[str],
236 class_instantiations: Sequence[parser.Typename],
237 method_instantiations: Sequence[parser.Typename],
238 parent:
'InstantiatedClass'):
240 Instantiate both the class and method level templates.
242 instantiations = class_instantiations + method_instantiations
245 typenames, instantiations,
246 parent.cpp_typename())
248 instantiated_methods.append(
251 class_instantiations,
252 method_instantiations,
256 return instantiated_methods
259 typenames: Sequence[str],
260 parent:
'InstantiatedClass'):
262 Helper to instantiate methods at both the class and method level.
265 methods_list: The list of methods in the class to instantiated.
266 typenames: List of class level template parameters, e.g. ['T'].
267 parent: The instantiated class to which `methods_list` belongs.
269 instantiated_methods = []
271 for method
in methods_list:
273 method_typenames = deepcopy(typenames)
275 if isinstance(method.template, parser.template.Template):
276 method_typenames.extend(method.template.typenames)
279 for instantiations
in itertools.product(
280 *method.template.instantiations):
283 instantiated_methods,
285 typenames=method_typenames,
286 class_instantiations=parent.instantiations,
287 method_instantiations=
list(instantiations),
293 instantiated_methods,
295 typenames=method_typenames,
296 class_instantiations=parent.instantiations,
297 method_instantiations=[],
300 return instantiated_methods