test_template_instantiator.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 Tests for template_instantiator.
9 
10 Author: Varun Agrawal
11 """
12 
13 # pylint: disable=import-error,wrong-import-position
14 
15 import os
16 import sys
17 import unittest
18 
19 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
20 
21 from gtwrap.interface_parser import (Argument, ArgumentList, Class,
22  Constructor, ForwardDeclaration,
23  GlobalFunction, Include, Method,
24  Namespace, ReturnType, StaticMethod,
25  Typename)
26 from gtwrap.template_instantiator import (
27  InstantiatedClass, InstantiatedConstructor, InstantiatedDeclaration,
28  InstantiatedGlobalFunction, InstantiatedMethod, InstantiatedStaticMethod,
29  InstantiationHelper, instantiate_args_list, instantiate_name,
30  instantiate_namespace, instantiate_return_type, instantiate_type,
31  is_scoped_template)
32 
33 
34 class TestInstantiationHelper(unittest.TestCase):
35  """Tests for the InstantiationHelper class."""
36  def test_constructor(self):
37  """Test constructor."""
38  helper = InstantiationHelper(InstantiatedClass)
39  self.assertEqual(helper.instantiation_type, InstantiatedClass)
40  helper = InstantiationHelper(InstantiatedConstructor)
41  self.assertEqual(helper.instantiation_type, InstantiatedConstructor)
42  helper = InstantiationHelper(InstantiatedDeclaration)
43  self.assertEqual(helper.instantiation_type, InstantiatedDeclaration)
44  helper = InstantiationHelper(InstantiatedGlobalFunction)
45  self.assertEqual(helper.instantiation_type, InstantiatedGlobalFunction)
46  helper = InstantiationHelper(InstantiatedMethod)
47  self.assertEqual(helper.instantiation_type, InstantiatedMethod)
48  helper = InstantiationHelper(InstantiatedStaticMethod)
49  self.assertEqual(helper.instantiation_type, InstantiatedStaticMethod)
50 
51  def test_instantiate(self):
52  """Test instantiate method."""
53  method = Method.rule.parseString("""
54  template<U={double}>
55  double method(const T x, const U& param);
56  """)[0]
57  cls = Class.rule.parseString("""
58  template<T={string}>
59  class Foo {};
60  """)[0]
61  typenames = ['T', 'U']
62  class_instantiations = [Typename.rule.parseString("string")[0]]
63  method_instantiations = [Typename.rule.parseString("double")[0]]
64 
65  parent = InstantiatedClass(cls, class_instantiations)
66 
67  helper = InstantiationHelper(InstantiatedMethod)
68  instantiated_methods = helper.instantiate([], method, typenames,
69  class_instantiations,
70  method_instantiations,
71  parent)
72 
73  self.assertEqual(len(instantiated_methods), 1)
74  args_list = instantiated_methods[0].args.list()
75  self.assertEqual(args_list[0].ctype.get_typename(), 'string')
76  self.assertEqual(args_list[1].ctype.get_typename(), 'double')
77 
79  """
80  Test method for multilevel instantiation
81  i.e. instantiation at both the class and method level.
82  """
83  cls = Class.rule.parseString("""
84  template<T={string}>
85  class Foo {
86  template<U={double}>
87  double method1(const T x, const U& param);
88 
89  template<V={int}>
90  V method2(const T x);
91  };
92  """)[0]
93 
94  typenames = ['T']
95  class_instantiations = [Typename.rule.parseString("string")[0]]
96  parent = InstantiatedClass(cls, class_instantiations)
97 
98  helper = InstantiationHelper(InstantiatedMethod)
99 
100  instantiated_methods = helper.multilevel_instantiation(
101  cls.methods, typenames, parent)
102  self.assertEqual(len(instantiated_methods), 2)
103  self.assertEqual(
104  instantiated_methods[0].args.list()[0].ctype.get_typename(),
105  'string')
106  self.assertEqual(
107  instantiated_methods[0].args.list()[1].ctype.get_typename(),
108  'double')
109  self.assertEqual(
110  instantiated_methods[1].args.list()[0].ctype.get_typename(),
111  'string')
112  self.assertEqual(
113  instantiated_methods[1].return_type.type1.get_typename(), 'int')
114 
115 
116 class TestInstantiatedGlobalFunction(unittest.TestCase):
117  """Tests for the InstantiatedGlobalFunction class."""
118  def setUp(self):
119  original = GlobalFunction.rule.parseString("""
120  template<T={int}, R={double}>
121  R function(const T& x);
122  """)[0]
123  instantiations = [
124  Typename.rule.parseString("int")[0],
125  Typename.rule.parseString("double")[0]
126  ]
127  self.func = InstantiatedGlobalFunction(original, instantiations)
128 
129  def test_constructor(self):
130  """Test constructor."""
131  self.assertIsInstance(self.func, InstantiatedGlobalFunction)
132  self.assertIsInstance(self.func.original, GlobalFunction)
133  self.assertEqual(self.func.name, "functionIntDouble")
134  self.assertEqual(len(self.func.args.list()), 1)
135  self.assertEqual(self.func.args.list()[0].ctype.get_typename(), "int")
136  self.assertEqual(self.func.return_type.type1.get_typename(), "double")
137 
138  def test_to_cpp(self):
139  """Test to_cpp method."""
140  actual = self.func.to_cpp()
141  self.assertEqual(actual, "function<int,double>")
142 
143 
144 class TestInstantiatedConstructor(unittest.TestCase):
145  """Tests for the InstantiatedConstructor class."""
146  def setUp(self):
147  constructor = Constructor.rule.parseString("""
148  template<U={double}>
149  Class(C x, const U& param);
150  """)[0]
151  instantiations = [
152  Typename.rule.parseString("double")[0],
153  Typename.rule.parseString("string")[0]
154  ]
155  self.constructor = InstantiatedConstructor(constructor, instantiations)
156 
157  def test_constructor(self):
158  """Test constructor."""
159  self.assertIsInstance(self.constructor, InstantiatedConstructor)
160  self.assertIsInstance(self.constructor.original, Constructor)
161 
162  def test_construct(self):
163  """Test the construct classmethod."""
164  constructor = Constructor.rule.parseString("""
165  template<U={double}>
166  Class(C x, const U& param);
167  """)[0]
168  c = Class.rule.parseString("""
169  template<C={string}>
170  class Class {};
171  """)[0]
172  class_instantiations = [Typename.rule.parseString("double")[0]]
173  method_instantiations = [Typename.rule.parseString("string")[0]]
174  typenames = ['C', 'U']
175  parent = InstantiatedClass(c, class_instantiations)
176  instantiated_args = instantiate_args_list(
177  constructor.args.list(),
178  typenames, class_instantiations + method_instantiations,
179  parent.cpp_typename())
180 
181  instantiated_constructor = InstantiatedConstructor.construct(
182  constructor, typenames, class_instantiations,
183  method_instantiations, instantiated_args, parent)
184  self.assertEqual(instantiated_constructor.name, "ClassDouble")
185  self.assertEqual(
186  instantiated_constructor.args.list()[0].ctype.get_typename(),
187  "double")
188  self.assertEqual(
189  instantiated_constructor.args.list()[1].ctype.get_typename(),
190  "string")
191 
192  def test_to_cpp(self):
193  """Test the to_cpp method."""
194  actual = self.constructor.to_cpp()
195  self.assertEqual(actual, "Class<double,string>")
196 
197 
198 class TestInstantiatedMethod(unittest.TestCase):
199  """Tests for the InstantiatedMethod class."""
200  def setUp(self):
201  method = Method.rule.parseString("""
202  template<U={double}>
203  double method(const U& param);
204  """)[0]
205  instantiations = [Typename.rule.parseString("double")[0]]
206  self.method = InstantiatedMethod(method, instantiations)
207 
208  def test_constructor(self):
209  """Test constructor."""
210  self.assertIsInstance(self.method, InstantiatedMethod)
211  self.assertIsInstance(self.method.original, Method)
212  self.assertEqual(self.method.name, "methodDouble")
213 
214  def test_construct(self):
215  """Test the construct classmethod."""
216  method = Method.rule.parseString("""
217  template<U={double}>
218  T method(U& param);
219  """)[0]
220  method_instantiations = [Typename.rule.parseString("double")[0]]
221  c = Class.rule.parseString("""
222  template<T={string}>
223  class Class {};
224  """)[0]
225  class_instantiations = [Typename.rule.parseString("string")[0]]
226 
227  typenames = ['T', 'U']
228  parent = InstantiatedClass(c, class_instantiations)
229  instantiated_args = instantiate_args_list(
230  method.args.list(),
231  typenames, class_instantiations + method_instantiations,
232  parent.cpp_typename())
233 
234  instantiated_method = InstantiatedMethod.construct(
235  method, typenames, class_instantiations, method_instantiations,
236  instantiated_args, parent)
237  self.assertEqual(instantiated_method.name, "methodDouble")
238  self.assertEqual(
239  instantiated_method.args.list()[0].ctype.get_typename(), "double")
240  self.assertEqual(instantiated_method.return_type.type1.get_typename(),
241  "string")
242 
243  def test_to_cpp(self):
244  """Test the to_cpp method."""
245  actual = self.method.to_cpp()
246  self.assertEqual(actual, "method<double>")
247 
248 
249 class TestInstantiatedStaticMethod(unittest.TestCase):
250  """Tests for the InstantiatedStaticMethod class."""
251  def setUp(self):
252  static_method = StaticMethod.rule.parseString("""
253  template<U={double}>
254  static T staticMethod(const U& param);
255  """)[0]
256  instantiations = [Typename.rule.parseString("double")[0]]
257  self.static_method = InstantiatedStaticMethod(static_method,
258  instantiations)
259 
260  def test_constructor(self):
261  """Test constructor."""
262  self.assertIsInstance(self.static_method, InstantiatedStaticMethod)
263  self.assertIsInstance(self.static_method.original, StaticMethod)
264  self.assertEqual(self.static_method.name, "staticMethodDouble")
265 
266  def test_construct(self):
267  """Test the construct classmethod."""
268  static_method = StaticMethod.rule.parseString("""
269  template<U={double}>
270  static T staticMethod(U& param);
271  """)[0]
272  method_instantiations = [Typename.rule.parseString("double")[0]]
273  c = Class.rule.parseString("""
274  template<T={string}>
275  class Class {};
276  """)[0]
277  class_instantiations = [Typename.rule.parseString("string")[0]]
278 
279  typenames = ['T', 'U']
280  parent = InstantiatedClass(c, class_instantiations)
281  instantiated_args = instantiate_args_list(
282  static_method.args.list(),
283  typenames, class_instantiations + method_instantiations,
284  parent.cpp_typename())
285 
286  instantiated_static_method = InstantiatedStaticMethod.construct(
287  static_method, typenames, class_instantiations,
288  method_instantiations, instantiated_args, parent)
289  self.assertEqual(instantiated_static_method.name, "staticMethodDouble")
290  self.assertEqual(
291  instantiated_static_method.args.list()[0].ctype.get_typename(),
292  "double")
293  self.assertEqual(
294  instantiated_static_method.return_type.type1.get_typename(),
295  "string")
296 
297  def test_to_cpp(self):
298  """Test the to_cpp method."""
299  actual = self.static_method.to_cpp()
300  self.assertEqual(actual, "staticMethod<double>")
301 
302 
303 class TestInstantiatedClass(unittest.TestCase):
304  """Tests for the InstantiatedClass class."""
305  def setUp(self):
306  cl = Class.rule.parseString("""
307  template<T={string}>
308  class Foo {
309  template<C={int}>
310  Foo(C& c);
311 
312  template<S={char}>
313  static T staticMethod(const S& s);
314 
315  template<M={double}>
316  T method(const M& m);
317 
318  T operator*(T other) const;
319 
320  T prop;
321  };
322  """)[0]
323  class_instantiations = [Typename.rule.parseString('string')[0]]
325  Typename.rule.parseString('int')[0],
326  Typename.rule.parseString('char')[0],
327  Typename.rule.parseString('double')[0],
328  ]
329  self.cl = InstantiatedClass(cl, class_instantiations)
330  self.typenames = self.cl.original.template.typenames
331 
332  def test_constructor(self):
333  """Test constructor."""
334  self.assertIsInstance(self.cl, InstantiatedClass)
335  self.assertIsInstance(self.cl.original, Class)
336  self.assertEqual(self.cl.name, "FooString")
337 
339  """Test instantiate_ctors method."""
340  ctors = self.cl.instantiate_ctors(self.typenames)
341  self.assertEqual(len(ctors), 1)
342  self.assertEqual(ctors[0].name, "FooString")
343  self.assertEqual(ctors[0].args.list()[0].ctype.get_typename(), "int")
344 
346  """Test instantiate_static_methods method."""
347  static_methods = self.cl.instantiate_static_methods(self.typenames)
348  self.assertEqual(len(static_methods), 1)
349  self.assertEqual(static_methods[0].name, "staticMethodChar")
350  self.assertEqual(static_methods[0].args.list()[0].ctype.get_typename(),
351  "char")
352  self.assertEqual(static_methods[0].return_type.type1.get_typename(),
353  "string")
354 
356  """Test instantiate_methods method."""
357  methods = self.cl.instantiate_methods(self.typenames)
358  self.assertEqual(len(methods), 1)
359  self.assertEqual(methods[0].name, "methodDouble")
360  self.assertEqual(methods[0].args.list()[0].ctype.get_typename(),
361  "double")
362  self.assertEqual(methods[0].return_type.type1.get_typename(), "string")
363 
365  """Test instantiate_operators method."""
366  operators = self.cl.instantiate_operators(self.typenames)
367  self.assertEqual(len(operators), 1)
368  self.assertEqual(operators[0].operator, "*")
369  self.assertEqual(operators[0].args.list()[0].ctype.get_typename(),
370  "string")
371  self.assertEqual(operators[0].return_type.type1.get_typename(),
372  "string")
373 
375  """Test instantiate_properties method."""
376  properties = self.cl.instantiate_properties(self.typenames)
377  self.assertEqual(len(properties), 1)
378  self.assertEqual(properties[0].name, "prop")
379  self.assertEqual(properties[0].ctype.get_typename(), "string")
380 
381  def test_cpp_typename(self):
382  """Test cpp_typename method."""
383  actual = self.cl.cpp_typename()
384  self.assertEqual(actual.name, "Foo<string>")
385 
386  def test_to_cpp(self):
387  """Test to_cpp method."""
388  actual = self.cl.to_cpp()
389  self.assertEqual(actual, "Foo<string>")
390 
391 
392 class TestInstantiatedDeclaration(unittest.TestCase):
393  """Tests for the InstantiatedDeclaration class."""
394  def setUp(self):
395  #TODO(Varun) Need to support templated class forward declaration.
396  forward_declaration = ForwardDeclaration.rule.parseString("""
397  class FooBar;
398  """)[0]
399  instantiations = [Typename.rule.parseString("double")[0]]
400  self.declaration = InstantiatedDeclaration(
401  forward_declaration, instantiations=instantiations)
402 
403  def test_constructor(self):
404  """Test constructor."""
405  self.assertIsInstance(self.declaration, InstantiatedDeclaration)
406  self.assertIsInstance(self.declaration.original, ForwardDeclaration)
407  self.assertEqual(self.declaration.instantiations[0].name, "double")
408 
409  def test_to_cpp(self):
410  """Test to_cpp method."""
411  cpp = self.declaration.to_cpp()
412  self.assertEqual(cpp, "FooBar<double>")
413 
414 
415 class TestTemplateInstantiator(unittest.TestCase):
416  """
417  Test overall template instantiation and the functions in the module.
418  """
420  """Test is_scoped_template."""
421  # Test if not scoped template.
422  template_typenames = ['T']
423  str_arg_typename = "double"
424  scoped_template, scoped_idx = is_scoped_template(
425  template_typenames, str_arg_typename)
426  self.assertFalse(scoped_template)
427  self.assertEqual(scoped_idx, -1)
428 
429  # Check for correct template match.
430  template_typenames = ['T']
431  str_arg_typename = "gtsam::Matrix"
432  scoped_template, scoped_idx = is_scoped_template(
433  template_typenames, str_arg_typename)
434  self.assertFalse(scoped_template)
435  self.assertEqual(scoped_idx, -1)
436 
437  # Test scoped templatte
438  template_typenames = ['T']
439  str_arg_typename = "T::Value"
440  scoped_template, scoped_idx = is_scoped_template(
441  template_typenames, str_arg_typename)
442  self.assertEqual(scoped_template, "T")
443  self.assertEqual(scoped_idx, 0)
444 
445  template_typenames = ['U', 'T']
446  str_arg_typename = "T::Value"
447  scoped_template, scoped_idx = is_scoped_template(
448  template_typenames, str_arg_typename)
449  self.assertEqual(scoped_template, "T")
450  self.assertEqual(scoped_idx, 1)
451 
453  """Test for instantiate_type."""
454  arg = Argument.rule.parseString("const T x")[0]
455  template_typenames = ["T"]
456  instantiations = [Typename.rule.parseString("double")[0]]
457  cpp_typename = "ExampleClass"
458  new_type = instantiate_type(arg.ctype,
459  template_typenames,
460  instantiations=instantiations,
461  cpp_typename=cpp_typename,
462  instantiated_class=None)
463 
464  new_typename = new_type.typename
465  self.assertEqual(new_typename.name, "double")
466  self.assertEqual(new_typename.instantiated_name(), "double")
467 
469  """Test for instantiate_args_list."""
470  args = ArgumentList.rule.parseString("T x, double y, string z")[0]
471  args_list = args.list()
472  template_typenames = ['T']
473  instantiations = [Typename.rule.parseString("double")[0]]
474  instantiated_args_list = instantiate_args_list(
475  args_list,
476  template_typenames,
477  instantiations,
478  cpp_typename="ExampleClass")
479 
480  self.assertEqual(instantiated_args_list[0].ctype.get_typename(),
481  "double")
482 
483  args = ArgumentList.rule.parseString("T x, U y, string z")[0]
484  args_list = args.list()
485  template_typenames = ['T', 'U']
486  instantiations = [
487  Typename.rule.parseString("double")[0],
488  Typename.rule.parseString("Matrix")[0]
489  ]
490  instantiated_args_list = instantiate_args_list(
491  args_list,
492  template_typenames,
493  instantiations,
494  cpp_typename="ExampleClass")
495  self.assertEqual(instantiated_args_list[0].ctype.get_typename(),
496  "double")
497  self.assertEqual(instantiated_args_list[1].ctype.get_typename(),
498  "Matrix")
499 
500  args = ArgumentList.rule.parseString("T x, U y, T z")[0]
501  args_list = args.list()
502  template_typenames = ['T', 'U']
503  instantiations = [
504  Typename.rule.parseString("double")[0],
505  Typename.rule.parseString("Matrix")[0]
506  ]
507  instantiated_args_list = instantiate_args_list(
508  args_list,
509  template_typenames,
510  instantiations,
511  cpp_typename="ExampleClass")
512  self.assertEqual(instantiated_args_list[0].ctype.get_typename(),
513  "double")
514  self.assertEqual(instantiated_args_list[1].ctype.get_typename(),
515  "Matrix")
516  self.assertEqual(instantiated_args_list[2].ctype.get_typename(),
517  "double")
518 
520  """Test for instantiate_return_type."""
521  return_type = ReturnType.rule.parseString("T")[0]
522  template_typenames = ['T']
523  instantiations = [Typename.rule.parseString("double")[0]]
524  instantiated_return_type = instantiate_return_type(
525  return_type,
526  template_typenames,
527  instantiations,
528  cpp_typename="ExampleClass")
529 
530  self.assertEqual(instantiated_return_type.type1.get_typename(),
531  "double")
532 
533  return_type = ReturnType.rule.parseString("pair<T, U>")[0]
534  template_typenames = ['T', 'U']
535  instantiations = [
536  Typename.rule.parseString("double")[0],
537  Typename.rule.parseString("char")[0],
538  ]
539  instantiated_return_type = instantiate_return_type(
540  return_type,
541  template_typenames,
542  instantiations,
543  cpp_typename="ExampleClass")
544 
545  self.assertEqual(instantiated_return_type.type1.get_typename(),
546  "double")
547  self.assertEqual(instantiated_return_type.type2.get_typename(), "char")
548 
550  """Test for instantiate_name."""
551  instantiations = [Typename.rule.parseString("Man")[0]]
552  instantiated_name = instantiate_name("Iron", instantiations)
553  self.assertEqual(instantiated_name, "IronMan")
554 
556  """Test for instantiate_namespace."""
557  namespace = Namespace.rule.parseString("""
558  namespace gtsam {
559  #include <gtsam/nonlinear/Values.h>
560  template<T={gtsam::Basis}>
561  class Values {
562  Values(const T& other);
563 
564  template<V={Vector, Matrix}>
565  void insert(size_t j, V x);
566 
567  template<S={double}>
568  static S staticMethod(const S& s);
569  };
570  }
571  """)[0]
572  instantiated_namespace = instantiate_namespace(namespace)
573 
574  self.assertEqual(instantiated_namespace.name, "gtsam")
575  self.assertEqual(instantiated_namespace.parent, "")
576 
577  self.assertEqual(instantiated_namespace.content[0].header,
578  "gtsam/nonlinear/Values.h")
579  self.assertIsInstance(instantiated_namespace.content[0], Include)
580 
581  self.assertEqual(instantiated_namespace.content[1].name, "ValuesBasis")
582  self.assertIsInstance(instantiated_namespace.content[1], Class)
583 
584  self.assertIsInstance(instantiated_namespace.content[1].ctors[0],
585  Constructor)
586  self.assertEqual(instantiated_namespace.content[1].ctors[0].name,
587  "ValuesBasis")
588 
589  self.assertIsInstance(instantiated_namespace.content[1].methods[0],
590  Method)
591  self.assertIsInstance(instantiated_namespace.content[1].methods[1],
592  Method)
593  self.assertEqual(instantiated_namespace.content[1].methods[0].name,
594  "insertVector")
595  self.assertEqual(instantiated_namespace.content[1].methods[1].name,
596  "insertMatrix")
597 
598  self.assertIsInstance(
599  instantiated_namespace.content[1].static_methods[0], StaticMethod)
600  self.assertEqual(
601  instantiated_namespace.content[1].static_methods[0].name,
602  "staticMethodDouble")
603 
604 
605 if __name__ == '__main__':
606  unittest.main()
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:37:46