template_instantiator/classes.py
Go to the documentation of this file.
1 """Instantiate a class and its members."""
2 
3 import gtwrap.interface_parser as parser
4 from gtwrap.template_instantiator.constructor import InstantiatedConstructor
5 from gtwrap.template_instantiator.helpers import (InstantiationHelper,
6  instantiate_args_list,
7  instantiate_name,
8  instantiate_return_type,
9  instantiate_type)
10 from gtwrap.template_instantiator.method import (InstantiatedMethod,
11  InstantiatedStaticMethod)
12 
13 
14 class InstantiatedClass(parser.Class):
15  """
16  Instantiate the class defined in the interface file.
17  """
18 
19  def __init__(self, original: parser.Class, instantiations=(), new_name=''):
20  """
21  Template <T, U>
22  Instantiations: [T1, U1]
23  """
24  self.original = original
25  self.instantiations = instantiations
26 
27  self.template = None
28  self.is_virtual = original.is_virtual
29  self.parent = original.parent
30 
31  # If the class is templated, check if the number of provided instantiations
32  # match the number of templates, else it's only a partial instantiation which is bad.
33  if original.template:
34  assert len(original.template.typenames) == len(
35  instantiations), "Typenames and instantiations mismatch!"
36 
37  # Get the instantiated name of the class. E.g. FuncDouble
39  original.name, instantiations) if not new_name else new_name
40 
41  # Check for typenames if templated.
42  # By passing in typenames, we can gracefully handle both templated and non-templated classes
43  # This will allow the `This` keyword to be used in both templated and non-templated classes.
44  typenames = self.original.template.typenames if self.original.template else []
45 
46  # Instantiate the parent class, constructors, static methods, properties, respectively.
47  self.parent_class = self.instantiate_parent_class(typenames)
48  self.ctors = self.instantiate_ctors(typenames)
50  self.properties = self.instantiate_properties(typenames)
51 
52  # Instantiate all operator overloads
53  self.operators = self.instantiate_operators(typenames)
54 
55  # Set enums
56  self.enums = original.enums
57 
58  # Instantiate all instance methods
59  self.methods = self.instantiate_methods(typenames)
60 
61  super().__init__(
62  self.template,
63  self.is_virtual,
64  self.name,
65  [self.parent_class],
66  self.ctors,
67  self.methods,
68  self.static_methods,
69  self.properties,
70  self.operators,
71  self.enums,
72  parent=self.parent,
73  )
74 
75  def __repr__(self):
76  return "{virtual}Class {cpp_class} : {parent_class}\n"\
77  "{ctors}\n{static_methods}\n{methods}\n{operators}".format(
78  virtual="virtual " if self.is_virtual else '',
79  cpp_class=self.to_cpp(),
80  parent_class=self.parent,
81  ctors="\n".join([repr(ctor) for ctor in self.ctors]),
82  static_methods="\n".join([repr(m)
83  for m in self.static_methods]),
84  methods="\n".join([repr(m) for m in self.methods]),
85  operators="\n".join([repr(op) for op in self.operators])
86  )
87 
88  def instantiate_parent_class(self, typenames):
89  """
90  Instantiate the inherited parent names.
91 
92  Args:
93  typenames: List of template types to instantiate.
94 
95  Return: List of constructors instantiated with provided template args.
96  """
97 
98  if isinstance(self.original.parent_class, parser.type.TemplatedType):
99  return instantiate_type(
100  self.original.parent_class, typenames, self.instantiations,
101  parser.Typename(self.namespaces())).typename
102  else:
103  return self.original.parent_class
104 
105  def instantiate_ctors(self, typenames):
106  """
107  Instantiate the class constructors.
108 
109  Args:
110  typenames: List of template types to instantiate.
111 
112  Return: List of constructors instantiated with provided template args.
113  """
114 
115  helper = InstantiationHelper(
116  instantiation_type=InstantiatedConstructor)
117 
118  instantiated_ctors = helper.multilevel_instantiation(
119  self.original.ctors, typenames, self)
120 
121  return instantiated_ctors
122 
123  def instantiate_static_methods(self, typenames):
124  """
125  Instantiate static methods in the class.
126 
127  Args:
128  typenames: List of template types to instantiate.
129 
130  Return: List of static methods instantiated with provided template args.
131  """
132  helper = InstantiationHelper(
133  instantiation_type=InstantiatedStaticMethod)
134 
135  instantiated_static_methods = helper.multilevel_instantiation(
136  self.original.static_methods, typenames, self)
137 
138  return instantiated_static_methods
139 
140  def instantiate_methods(self, typenames):
141  """
142  Instantiate regular methods in the class.
143 
144  Args:
145  typenames: List of template types to instantiate.
146 
147  Return: List of methods instantiated with provided template args.
148  """
149  instantiated_methods = []
150 
151  helper = InstantiationHelper(instantiation_type=InstantiatedMethod)
152 
153  instantiated_methods = helper.multilevel_instantiation(
154  self.original.methods, typenames, self)
155 
156  return instantiated_methods
157 
158  def instantiate_operators(self, typenames):
159  """
160  Instantiate the class-level template in the operator overload.
161 
162  Args:
163  typenames: List of template types to instantiate.
164 
165  Return: List of methods instantiated with provided template args on the class.
166  """
167  instantiated_operators = []
168  for operator in self.original.operators:
169  instantiated_args = instantiate_args_list(
170  operator.args.list(),
171  typenames,
172  self.instantiations,
173  self.cpp_typename(),
174  )
175  instantiated_operators.append(
176  parser.Operator(
177  name=operator.name,
178  operator=operator.operator,
179  return_type=instantiate_return_type(
180  operator.return_type,
181  typenames,
182  self.instantiations,
183  self.cpp_typename(),
184  ),
185  args=parser.ArgumentList(instantiated_args),
186  is_const=operator.is_const,
187  parent=self,
188  ))
189  return instantiated_operators
190 
191  def instantiate_properties(self, typenames):
192  """
193  Instantiate the class properties.
194 
195  Args:
196  typenames: List of template types to instantiate.
197 
198  Return: List of properties instantiated with provided template args.
199  """
200  instantiated_ = instantiate_args_list(
201  self.original.properties,
202  typenames,
203  self.instantiations,
204  self.cpp_typename(),
205  )
206  # Convert to type Variable
207  instantiated_properties = [
208  parser.Variable(ctype=[arg.ctype],
209  name=arg.name,
210  default=arg.default) for arg in instantiated_
211  ]
212  return instantiated_properties
213 
214  def cpp_typename(self):
215  """
216  Return a parser.Typename including namespaces and cpp name of this
217  class.
218  """
219  if self.original.template:
220  name = "{}<{}>".format(
221  self.original.name,
222  ", ".join([inst.to_cpp() for inst in self.instantiations]))
223  else:
224  name = self.original.name
225  namespaces_name = self.namespaces()
226  namespaces_name.append(name)
227  return parser.Typename(namespaces_name)
228 
229  def to_cpp(self):
230  """Generate the C++ code for wrapping."""
231  return self.cpp_typename().to_cpp()
bool isinstance(handle obj)
Definition: pytypes.h:700
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
str repr(handle h)
Definition: pytypes.h:2265
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2244


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:01