type.py
Go to the documentation of this file.
1 """
2 GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
4 All Rights Reserved
5 
6 See LICENSE for the license information
7 
8 Define the parser rules and classes for various C++ types.
9 
10 Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
11 """
12 
13 # pylint: disable=unnecessary-lambda, expression-not-assigned
14 
15 from typing import List, Sequence, Union
16 
17 from pyparsing import ParseResults # type: ignore
18 from pyparsing import Forward, Optional, Or, delimitedList
19 
20 from .tokens import (BASIC_TYPES, CONST, IDENT, LOPBRACK, RAW_POINTER, REF,
21  ROPBRACK, SHARED_POINTER)
22 
23 
24 class Typename:
25  """
26  Class which holds a type's name, full namespace, and template arguments.
27 
28  E.g.
29  ```
30  gtsam::PinholeCamera<gtsam::Cal3S2>
31  ```
32 
33  will give the name as `PinholeCamera`, namespace as `gtsam`,
34  and template instantiations as `[gtsam::Cal3S2]`.
35 
36  Args:
37  namespaces_and_name: A list representing the namespaces of the type
38  with the type being the last element.
39  instantiations: Template parameters to the type.
40  """
41 
42  namespaces_name_rule = delimitedList(IDENT, "::")
43  instantiation_name_rule = delimitedList(IDENT, "::")
44  rule = (
45  namespaces_name_rule("namespaces_and_name") #
46  ).setParseAction(lambda t: Typename(t))
47 
48  def __init__(self,
49  t: ParseResults,
50  instantiations: Sequence[ParseResults] = ()):
51  self.name = t[-1] # the name is the last element in this list
52  self.namespaces = t[:-1]
53 
54  # If the first namespace is empty string, just get rid of it.
55  if self.namespaces and self.namespaces[0] == '':
56  self.namespaces.pop(0)
57 
58  if instantiations:
59  if isinstance(instantiations, Sequence):
60  self.instantiations = instantiations # type: ignore
61  else:
62  self.instantiations = instantiations.asList()
63  else:
64  self.instantiations = []
65 
66  if self.name in ["Matrix", "Vector"] and not self.namespaces:
67  self.namespaces = ["gtsam"]
68 
69  @staticmethod
70  def from_parse_result(parse_result: Union[str, list]):
71  """Unpack the parsed result to get the Typename instance."""
72  return parse_result[0]
73 
74  def __repr__(self) -> str:
75  return self.to_cpp()
76 
77  def instantiated_name(self) -> str:
78  """Get the instantiated name of the type."""
79  res = self.name
80  for instantiation in self.instantiations:
81  res += instantiation.instantiated_name()
82  return res
83 
84  def qualified_name(self):
85  """Return the fully qualified name, e.g. `gtsam::internal::PoseKey`."""
86  return "::".join(self.namespaces + [self.name])
87 
88  def to_cpp(self) -> str:
89  """Generate the C++ code for wrapping."""
90  if self.instantiations:
91  cpp_name = self.name + "<{}>".format(", ".join(
92  [inst.to_cpp() for inst in self.instantiations]))
93  else:
94  cpp_name = self.name
95  return '{}{}{}'.format(
96  "::".join(self.namespaces),
97  "::" if self.namespaces else "",
98  cpp_name,
99  )
100 
101  def __eq__(self, other) -> bool:
102  if isinstance(other, Typename):
103  return str(self) == str(other)
104  else:
105  return False
106 
107  def __ne__(self, other) -> bool:
108  res = self.__eq__(other)
109  return not res
110 
111 
112 class BasicType:
113  """
114  Basic types are the fundamental built-in types in C++ such as double, int, char, etc.
115 
116  When using templates, the basic type will take on the same form as the template.
117 
118  E.g.
119  ```
120  template<T = {double}>
121  void func(const T& x);
122  ```
123 
124  will give
125 
126  ```
127  m_.def("funcDouble",[](const double& x){
128  ::func<double>(x);
129  }, py::arg("x"));
130  ```
131  """
132 
133  rule = (Or(BASIC_TYPES)("typename")).setParseAction(lambda t: BasicType(t))
134 
135  def __init__(self, t: ParseResults):
136  self.typename = Typename(t)
137 
138 
140  """
141  Custom defined types with the namespace.
142  Essentially any C++ data type that is not a BasicType.
143 
144  E.g.
145  ```
146  gtsam::Matrix wTc;
147  ```
148 
149  Here `gtsam::Matrix` is a custom type.
150  """
151 
152  rule = (Typename.rule("typename")).setParseAction(lambda t: CustomType(t))
153 
154  def __init__(self, t: ParseResults):
155  self.typename = Typename(t)
156 
157 
158 class Type:
159  """
160  Parsed datatype, can be either a fundamental/basic type or a custom datatype.
161  E.g. void, double, size_t, Matrix.
162  Think of this as a high-level type which encodes the typename and other
163  characteristics of the type.
164 
165  The type can optionally be a raw pointer, shared pointer or reference.
166  Can also be optionally qualified with a `const`, e.g. `const int`.
167  """
168  rule = (
169  Optional(CONST("is_const")) #
170  + (BasicType.rule("basic") | CustomType.rule("qualified")) # BR
171  + Optional(
172  SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr")
173  | REF("is_ref")) #
174  ).setParseAction(lambda t: Type.from_parse_result(t))
175 
176  def __init__(self, typename: Typename, is_const: str, is_shared_ptr: str,
177  is_ptr: str, is_ref: str, is_basic: bool):
178  self.typename = typename
179  self.is_const = is_const
180  self.is_shared_ptr = is_shared_ptr
181  self.is_ptr = is_ptr
182  self.is_ref = is_ref
183  self.is_basic = is_basic
184 
185  @staticmethod
186  def from_parse_result(t: ParseResults):
187  """Return the resulting Type from parsing the source."""
188  # If the type is a basic/fundamental c++ type (e.g int, bool)
189  if t.basic:
190  return Type(
191  typename=t.basic.typename,
192  is_const=t.is_const,
193  is_shared_ptr=t.is_shared_ptr,
194  is_ptr=t.is_ptr,
195  is_ref=t.is_ref,
196  is_basic=True,
197  )
198  elif t.qualified:
199  return Type(
200  typename=t.qualified.typename,
201  is_const=t.is_const,
202  is_shared_ptr=t.is_shared_ptr,
203  is_ptr=t.is_ptr,
204  is_ref=t.is_ref,
205  is_basic=False,
206  )
207  else:
208  raise ValueError("Parse result is not a Type")
209 
210  def __repr__(self) -> str:
211  is_ptr_or_ref = "{0}{1}{2}".format(self.is_shared_ptr, self.is_ptr,
212  self.is_ref)
213  return "{is_const}{self.typename}{is_ptr_or_ref}".format(
214  self=self,
215  is_const="const " if self.is_const else "",
216  is_ptr_or_ref=" " + is_ptr_or_ref if is_ptr_or_ref else "")
217 
218  def to_cpp(self) -> str:
219  """
220  Generate the C++ code for wrapping.
221 
222  Treat all pointers as "const shared_ptr<T>&"
223  Treat Matrix and Vector as "const Matrix&" and "const Vector&" resp.
224  """
225 
226  if self.is_shared_ptr:
227  typename = "std::shared_ptr<{typename}>".format(
228  typename=self.typename.to_cpp())
229  elif self.is_ptr:
230  typename = "{typename}*".format(typename=self.typename.to_cpp())
231  elif self.is_ref or self.typename.name in ["Matrix", "Vector"]:
232  typename = typename = "{typename}&".format(
233  typename=self.typename.to_cpp())
234  else:
235  typename = self.typename.to_cpp()
236 
237  return ("{const}{typename}".format(
238  const="const " if
239  (self.is_const
240  or self.typename.name in ["Matrix", "Vector"]) else "",
241  typename=typename))
242 
243  def get_typename(self):
244  """Convenience method to get the typename of this type."""
245  return self.typename.name
246 
247 
249  """
250  Parser rule for data types which are templated.
251  This is done so that the template parameters can be pointers/references.
252 
253  E.g. std::vector<double>, BearingRange<Pose3, Point3>
254  """
255 
256  rule = Forward()
257  rule << (
258  Optional(CONST("is_const")) #
259  + Typename.rule("typename") #
260  + (
261  LOPBRACK #
262  + delimitedList(Type.rule ^ rule, ",")("template_params") #
263  + ROPBRACK) #
264  + Optional(
265  SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr")
266  | REF("is_ref")) #
267  ).setParseAction(lambda t: TemplatedType.from_parse_result(t))
268 
269  def __init__(self, typename: Typename, template_params: List[Type],
270  is_const: str, is_shared_ptr: str, is_ptr: str, is_ref: str):
271  instantiations = [param.typename for param in template_params]
272  # Recreate the typename but with the template params as instantiations.
273  self.typename = Typename(typename.namespaces + [typename.name],
274  instantiations)
275 
276  self.template_params = template_params
277 
278  self.is_const = is_const
279  self.is_shared_ptr = is_shared_ptr
280  self.is_ptr = is_ptr
281  self.is_ref = is_ref
282 
283  @staticmethod
284  def from_parse_result(t: ParseResults):
285  """Get the TemplatedType from the parser results."""
286  return TemplatedType(t.typename, t.template_params, t.is_const,
287  t.is_shared_ptr, t.is_ptr, t.is_ref)
288 
289  def __repr__(self):
290  return "TemplatedType({typename.namespaces}::{typename.name})".format(
291  typename=self.typename)
292 
293  def to_cpp(self):
294  """
295  Generate the C++ code for wrapping.
296  """
297  # Use Type.to_cpp to do the heavy lifting for the template parameters.
298  template_args = ", ".join([t.to_cpp() for t in self.template_params])
299 
300  typename = "{typename}<{template_args}>".format(
301  typename=self.typename.qualified_name(),
302  template_args=template_args)
303 
304  if self.is_shared_ptr:
305  typename = f"std::shared_ptr<{typename}>"
306  elif self.is_ptr:
307  typename = "{typename}*".format(typename=typename)
308  elif self.is_ref or self.typename.name in ["Matrix", "Vector"]:
309  typename = typename = "{typename}&".format(typename=typename)
310  else:
311  pass
312 
313  return ("{const}{typename}".format(
314  const="const " if
315  (self.is_const
316  or self.typename.name in ["Matrix", "Vector"]) else "",
317  typename=typename))
Eigen::Forward
@ Forward
Definition: NumericalDiff.h:19
gtwrap.interface_parser.type.TemplatedType.is_ref
is_ref
Definition: type.py:280
format
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
Definition: openglsupport.cpp:226
gtwrap.interface_parser.type.Typename.name
name
Definition: type.py:49
gtwrap.interface_parser.type.Type.get_typename
def get_typename(self)
Definition: type.py:243
gtwrap.interface_parser.type.TemplatedType.__init__
def __init__(self, Typename typename, List[Type] template_params, str is_const, str is_shared_ptr, str is_ptr, str is_ref)
Definition: type.py:269
gtwrap.interface_parser.type.TemplatedType.__repr__
def __repr__(self)
Definition: type.py:289
gtwrap.interface_parser.type.Typename.__eq__
bool __eq__(self, other)
Definition: type.py:101
gtwrap.interface_parser.type.Typename
Definition: type.py:24
gtwrap.interface_parser.type.Type.__repr__
str __repr__(self)
Definition: type.py:210
gtwrap.interface_parser.type.TemplatedType.typename
typename
Definition: type.py:272
gtwrap.interface_parser.tokens.SHARED_POINTER
SHARED_POINTER
Definition: tokens.py:21
gtwrap.interface_parser.type.Typename.__repr__
str __repr__(self)
Definition: type.py:74
gtwrap.interface_parser.type.TemplatedType
Definition: type.py:248
gtwrap.interface_parser.type.Typename.to_cpp
str to_cpp(self)
Definition: type.py:88
gtwrap.interface_parser.type.Type.is_basic
is_basic
Definition: type.py:182
gtwrap.interface_parser.type.Type.is_ptr
is_ptr
Definition: type.py:180
gtwrap.interface_parser.tokens.REF
REF
Definition: tokens.py:21
gtwrap.interface_parser.type.CustomType.__init__
def __init__(self, ParseResults t)
Definition: type.py:154
gtwrap.interface_parser.type.BasicType.typename
typename
Definition: type.py:136
gtwrap.interface_parser.type.CustomType
Definition: type.py:139
isinstance
bool isinstance(handle obj)
Definition: pytypes.h:825
gtwrap.interface_parser.type.CustomType.typename
typename
Definition: type.py:155
gtwrap.interface_parser.type.Type.to_cpp
str to_cpp(self)
Definition: type.py:218
gtwrap.interface_parser.type.Typename.__ne__
bool __ne__(self, other)
Definition: type.py:107
gtwrap.interface_parser.type.Typename.qualified_name
def qualified_name(self)
Definition: type.py:84
gtwrap.interface_parser.type.Type.from_parse_result
def from_parse_result(ParseResults t)
Definition: type.py:186
gtwrap.interface_parser.type.Type
Definition: type.py:158
gtwrap.interface_parser.type.TemplatedType.is_shared_ptr
is_shared_ptr
Definition: type.py:278
gtwrap.interface_parser.type.BasicType
Definition: type.py:112
str
Definition: pytypes.h:1524
gtwrap.interface_parser.type.TemplatedType.from_parse_result
def from_parse_result(ParseResults t)
Definition: type.py:284
gtwrap.interface_parser.type.Type.is_shared_ptr
is_shared_ptr
Definition: type.py:179
gtwrap.interface_parser.type.TemplatedType.template_params
template_params
Definition: type.py:275
gtwrap.interface_parser.type.Typename.from_parse_result
def from_parse_result(Union[str, list] parse_result)
Definition: type.py:70
gtwrap.interface_parser.type.Type.is_ref
is_ref
Definition: type.py:181
gtwrap.interface_parser.tokens.CONST
CONST
Definition: tokens.py:42
gtwrap.interface_parser.type.Type.typename
typename
Definition: type.py:177
gtwrap.interface_parser.type.Typename.instantiations
instantiations
Definition: type.py:58
gtwrap.interface_parser.type.TemplatedType.is_ptr
is_ptr
Definition: type.py:279
gtwrap.interface_parser.type.Type.is_const
is_const
Definition: type.py:178
gtwrap.interface_parser.type.TemplatedType.is_const
is_const
Definition: type.py:277
gtwrap.interface_parser.type.Type.__init__
def __init__(self, Typename typename, str is_const, str is_shared_ptr, str is_ptr, str is_ref, bool is_basic)
Definition: type.py:176
gtwrap.interface_parser.type.BasicType.__init__
def __init__(self, ParseResults t)
Definition: type.py:135
gtwrap.interface_parser.type.Typename.namespaces
namespaces
Definition: type.py:50
gtwrap.interface_parser.tokens.RAW_POINTER
RAW_POINTER
Definition: tokens.py:21
gtwrap.interface_parser.type.Typename.__init__
def __init__(self, ParseResults t, Sequence[ParseResults] instantiations=())
Definition: type.py:48
gtwrap.interface_parser.type.Typename.instantiated_name
str instantiated_name(self)
Definition: type.py:77
gtwrap.interface_parser.type.Typename.namespaces_name_rule
namespaces_name_rule
Definition: type.py:42
gtwrap.interface_parser.type.TemplatedType.to_cpp
def to_cpp(self)
Definition: type.py:293


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:07:51