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  @staticmethod
67  def from_parse_result(parse_result: Union[str, list]):
68  """Unpack the parsed result to get the Typename instance."""
69  return parse_result[0]
70 
71  def __repr__(self) -> str:
72  return self.to_cpp()
73 
74  def instantiated_name(self) -> str:
75  """Get the instantiated name of the type."""
76  res = self.name
77  for instantiation in self.instantiations:
78  res += instantiation.instantiated_name()
79  return res
80 
81  def qualified_name(self):
82  """Return the fully qualified name, e.g. `gtsam::internal::PoseKey`."""
83  return "::".join(self.namespaces + [self.name])
84 
85  def to_cpp(self) -> str:
86  """Generate the C++ code for wrapping."""
87  if self.instantiations:
88  cpp_name = self.name + "<{}>".format(", ".join(
89  [inst.to_cpp() for inst in self.instantiations]))
90  else:
91  cpp_name = self.name
92  return '{}{}{}'.format(
93  "::".join(self.namespaces),
94  "::" if self.namespaces else "",
95  cpp_name,
96  )
97 
98  def __eq__(self, other) -> bool:
99  if isinstance(other, Typename):
100  return str(self) == str(other)
101  else:
102  return False
103 
104  def __ne__(self, other) -> bool:
105  res = self.__eq__(other)
106  return not res
107 
108 
109 class BasicType:
110  """
111  Basic types are the fundamental built-in types in C++ such as double, int, char, etc.
112 
113  When using templates, the basic type will take on the same form as the template.
114 
115  E.g.
116  ```
117  template<T = {double}>
118  void func(const T& x);
119  ```
120 
121  will give
122 
123  ```
124  m_.def("funcDouble",[](const double& x){
125  ::func<double>(x);
126  }, py::arg("x"));
127  ```
128  """
129 
130  rule = (Or(BASIC_TYPES)("typename")).setParseAction(lambda t: BasicType(t))
131 
132  def __init__(self, t: ParseResults):
133  self.typename = Typename(t)
134 
135 
137  """
138  Custom defined types with the namespace.
139  Essentially any C++ data type that is not a BasicType.
140 
141  E.g.
142  ```
143  gtsam::Matrix wTc;
144  ```
145 
146  Here `gtsam::Matrix` is a custom type.
147  """
148 
149  rule = (Typename.rule("typename")).setParseAction(lambda t: CustomType(t))
150 
151  def __init__(self, t: ParseResults):
152  self.typename = Typename(t)
153 
154 
155 class Type:
156  """
157  Parsed datatype, can be either a fundamental/basic type or a custom datatype.
158  E.g. void, double, size_t, Matrix.
159  Think of this as a high-level type which encodes the typename and other
160  characteristics of the type.
161 
162  The type can optionally be a raw pointer, shared pointer or reference.
163  Can also be optionally qualified with a `const`, e.g. `const int`.
164  """
165  rule = (
166  Optional(CONST("is_const")) #
167  + (BasicType.rule("basic") | CustomType.rule("qualified")) # BR
168  + Optional(
169  SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr")
170  | REF("is_ref")) #
171  ).setParseAction(lambda t: Type.from_parse_result(t))
172 
173  def __init__(self, typename: Typename, is_const: str, is_shared_ptr: str,
174  is_ptr: str, is_ref: str, is_basic: bool):
175  self.typename = typename
176  self.is_const = is_const
177  self.is_shared_ptr = is_shared_ptr
178  self.is_ptr = is_ptr
179  self.is_ref = is_ref
180  self.is_basic = is_basic
181 
182  @staticmethod
183  def from_parse_result(t: ParseResults):
184  """Return the resulting Type from parsing the source."""
185  # If the type is a basic/fundamental c++ type (e.g int, bool)
186  if t.basic:
187  return Type(
188  typename=t.basic.typename,
189  is_const=t.is_const,
190  is_shared_ptr=t.is_shared_ptr,
191  is_ptr=t.is_ptr,
192  is_ref=t.is_ref,
193  is_basic=True,
194  )
195  elif t.qualified:
196  return Type(
197  typename=t.qualified.typename,
198  is_const=t.is_const,
199  is_shared_ptr=t.is_shared_ptr,
200  is_ptr=t.is_ptr,
201  is_ref=t.is_ref,
202  is_basic=False,
203  )
204  else:
205  raise ValueError("Parse result is not a Type")
206 
207  def __repr__(self) -> str:
208  is_ptr_or_ref = "{0}{1}{2}".format(self.is_shared_ptr, self.is_ptr,
209  self.is_ref)
210  return "{is_const}{self.typename}{is_ptr_or_ref}".format(
211  self=self,
212  is_const="const " if self.is_const else "",
213  is_ptr_or_ref=" " + is_ptr_or_ref if is_ptr_or_ref else "")
214 
215  def to_cpp(self) -> str:
216  """
217  Generate the C++ code for wrapping.
218 
219  Treat all pointers as "const shared_ptr<T>&"
220  """
221 
222  if self.is_shared_ptr:
223  typename = "std::shared_ptr<{typename}>".format(
224  typename=self.typename.to_cpp())
225  elif self.is_ptr:
226  typename = "{typename}*".format(typename=self.typename.to_cpp())
227  elif self.is_ref:
228  typename = typename = "{typename}&".format(
229  typename=self.typename.to_cpp())
230  else:
231  typename = self.typename.to_cpp()
232 
233  return ("{const}{typename}".format(
234  const="const " if self.is_const else "", typename=typename))
235 
236  def get_typename(self):
237  """Convenience method to get the typename of this type."""
238  return self.typename.name
239 
240 
242  """
243  Parser rule for data types which are templated.
244  This is done so that the template parameters can be pointers/references.
245 
246  E.g. std::vector<double>, BearingRange<Pose3, Point3>
247  """
248 
249  rule = Forward()
250  rule << (
251  Optional(CONST("is_const")) #
252  + Typename.rule("typename") #
253  + (
254  LOPBRACK #
255  + delimitedList(Type.rule ^ rule, ",")("template_params") #
256  + ROPBRACK) #
257  + Optional(
258  SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr")
259  | REF("is_ref")) #
260  ).setParseAction(lambda t: TemplatedType.from_parse_result(t))
261 
262  def __init__(self, typename: Typename, template_params: List[Type],
263  is_const: str, is_shared_ptr: str, is_ptr: str, is_ref: str):
264  instantiations = [param.typename for param in template_params]
265  # Recreate the typename but with the template params as instantiations.
266  self.typename = Typename(typename.namespaces + [typename.name],
267  instantiations)
268 
269  self.template_params = template_params
270 
271  self.is_const = is_const
272  self.is_shared_ptr = is_shared_ptr
273  self.is_ptr = is_ptr
274  self.is_ref = is_ref
275 
276  @staticmethod
277  def from_parse_result(t: ParseResults):
278  """Get the TemplatedType from the parser results."""
279  return TemplatedType(t.typename, t.template_params, t.is_const,
280  t.is_shared_ptr, t.is_ptr, t.is_ref)
281 
282  def __repr__(self):
283  return "TemplatedType({typename.namespaces}::{typename.name})".format(
284  typename=self.typename)
285 
286  def to_cpp(self):
287  """
288  Generate the C++ code for wrapping.
289  """
290  # Use Type.to_cpp to do the heavy lifting for the template parameters.
291  template_args = ", ".join([t.to_cpp() for t in self.template_params])
292 
293  typename = "{typename}<{template_args}>".format(
294  typename=self.typename.qualified_name(),
295  template_args=template_args)
296 
297  if self.is_shared_ptr:
298  typename = f"std::shared_ptr<{typename}>"
299  elif self.is_ptr:
300  typename = "{typename}*".format(typename=typename)
301  elif self.is_ref:
302  typename = typename = "{typename}&".format(typename=typename)
303  else:
304  pass
305 
306  return ("{const}{typename}".format(
307  const="const " if self.is_const else "", typename=typename))
Eigen::Forward
@ Forward
Definition: NumericalDiff.h:19
gtwrap.interface_parser.type.TemplatedType.is_ref
is_ref
Definition: type.py:273
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:236
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:262
gtwrap.interface_parser.type.TemplatedType.__repr__
def __repr__(self)
Definition: type.py:282
gtwrap.interface_parser.type.Typename.__eq__
bool __eq__(self, other)
Definition: type.py:98
gtwrap.interface_parser.type.Typename
Definition: type.py:24
gtwrap.interface_parser.type.Type.__repr__
str __repr__(self)
Definition: type.py:207
gtwrap.interface_parser.type.TemplatedType.typename
typename
Definition: type.py:265
gtwrap.interface_parser.tokens.SHARED_POINTER
SHARED_POINTER
Definition: tokens.py:21
gtwrap.interface_parser.type.Typename.__repr__
str __repr__(self)
Definition: type.py:71
gtwrap.interface_parser.type.TemplatedType
Definition: type.py:241
gtwrap.interface_parser.type.Typename.to_cpp
str to_cpp(self)
Definition: type.py:85
gtwrap.interface_parser.type.Type.is_basic
is_basic
Definition: type.py:179
gtwrap.interface_parser.type.Type.is_ptr
is_ptr
Definition: type.py:177
gtwrap.interface_parser.tokens.REF
REF
Definition: tokens.py:21
gtwrap.interface_parser.type.CustomType.__init__
def __init__(self, ParseResults t)
Definition: type.py:151
gtwrap.interface_parser.type.BasicType.typename
typename
Definition: type.py:133
gtwrap.interface_parser.type.CustomType
Definition: type.py:136
isinstance
bool isinstance(handle obj)
Definition: pytypes.h:842
gtwrap.interface_parser.type.CustomType.typename
typename
Definition: type.py:152
gtwrap.interface_parser.type.Type.to_cpp
str to_cpp(self)
Definition: type.py:215
gtwrap.interface_parser.type.Typename.__ne__
bool __ne__(self, other)
Definition: type.py:104
gtwrap.interface_parser.type.Typename.qualified_name
def qualified_name(self)
Definition: type.py:81
gtwrap.interface_parser.type.Type.from_parse_result
def from_parse_result(ParseResults t)
Definition: type.py:183
gtwrap.interface_parser.type.Type
Definition: type.py:155
gtwrap.interface_parser.type.TemplatedType.is_shared_ptr
is_shared_ptr
Definition: type.py:271
gtwrap.interface_parser.type.BasicType
Definition: type.py:109
str
Definition: pytypes.h:1558
gtwrap.interface_parser.type.TemplatedType.from_parse_result
def from_parse_result(ParseResults t)
Definition: type.py:277
gtwrap.interface_parser.type.Type.is_shared_ptr
is_shared_ptr
Definition: type.py:176
gtwrap.interface_parser.type.TemplatedType.template_params
template_params
Definition: type.py:268
gtwrap.interface_parser.type.Typename.from_parse_result
def from_parse_result(Union[str, list] parse_result)
Definition: type.py:67
gtwrap.interface_parser.type.Type.is_ref
is_ref
Definition: type.py:178
gtwrap.interface_parser.tokens.CONST
CONST
Definition: tokens.py:42
gtwrap.interface_parser.type.Type.typename
typename
Definition: type.py:174
gtwrap.interface_parser.type.Typename.instantiations
instantiations
Definition: type.py:58
gtwrap.interface_parser.type.TemplatedType.is_ptr
is_ptr
Definition: type.py:272
gtwrap.interface_parser.type.Type.is_const
is_const
Definition: type.py:175
gtwrap.interface_parser.type.TemplatedType.is_const
is_const
Definition: type.py:270
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:173
gtwrap.interface_parser.type.BasicType.__init__
def __init__(self, ParseResults t)
Definition: type.py:132
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:74
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:286


gtsam
Author(s):
autogenerated on Fri Nov 1 2024 03:43:02