Daniel Carvalho has uploaded this change for review. (
https://gem5-review.googlesource.com/11629
Change subject: python: Add minimal template support
......................................................................
python: Add minimal template support
Add minimal template support, so that users can create
basic templated classes that inherit from SimObject. It
does not implement full template support, however.
Templated classes must be abstract.
This adds three parameters:
- 'templated', which informs whether the class is a templated
class or not.
- 'template_params', which is a list of possible template
parameters (list of lists, or list of entries). Within Python
it is used to forward declare template specializations.
- 'template_args', the template arguments used by a class
that inherits from a templated class (list). All declared
'template_args' must be also present in the list of template
params.
Usage example:
Suppose a base templated class
Base<class T0, class T1>.
It is inherited by classes
A : public Base<C, int>
B : public Base<D, float>.
(Assume C and D are other existent classes with a common base.)
A, B and base are declared as they would be in C++. Within their
correspondant Python file, however, the template information must
be given. The common python declarations have been ommited (type,
cxx_header, etc) for simplicity.
class Base(SimObject):
# A templated class must be abstract
abstract = true
templated = true
template_params = [["C", "int"], ["D", "float"]]
class A(Base):
template_args = ["C", "int"]
class B(Base):
template_args = ["D", "float"]
Change-Id: I5fa0d69b7c6420e983f5cbae4dcad8e1870cbb65
---
M src/python/m5/SimObject.py
1 file changed, 69 insertions(+), 14 deletions(-)
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 47e6474..5c37420 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -399,6 +399,7 @@
# that derive from SimObject are instantiated, and provides inherited
# class behavior (just like a class controls how instances of that
# class are instantiated, and provides inherited instance behavior).
+# Templated template parameters are not supported.
class MetaSimObject(type):
# Attributes that can be set only at initialization time
init_keywords = {
@@ -411,6 +412,9 @@
'cxx_extra_bases' : list,
'cxx_exports' : list,
'cxx_param_exports' : list,
+ 'templated' : bool,
+ 'template_params' : list,
+ 'template_args' : list,
}
# Attributes that can be set any time
keywords = { 'check' : FunctionType }
@@ -450,6 +454,14 @@
value_dict['cxx_exports'] += cxx_exports
if 'cxx_param_exports' not in value_dict:
value_dict['cxx_param_exports'] = []
+ if 'templated' not in value_dict:
+ value_dict['templated'] = False
+ else:
+ if 'template_params' not in value_dict:
+ raise AttributeError, \
+ "Missing template parameters for class %s" %
(cls.__name__)
+ if 'template_args' not in value_dict:
+ value_dict['template_args'] = []
cls_dict['_value_dict'] = value_dict
cls = super(MetaSimObject, mcls).__new__(mcls, name, bases,
cls_dict)
if 'type' in value_dict:
@@ -699,6 +711,16 @@
for param in params:
param.pybind_predecls(code)
+ # Forward declare template params
+ if hasattr(cls, 'templated') and cls.templated:
+ for template_param in cls._value_dict['template_params']:
+ if isinstance(template_param, list):
+ for sub_template_param in template_param:
+ code('class ' + sub_template_param + ';')
+ else:
+ code('class ' + template_param + ';')
+ code()
+
code('''namespace py = pybind11;
static void
@@ -744,24 +766,41 @@
elif cls._base:
# If not and if there was a SimObject base, use its c++ class
# as this class' base.
- bases.append(cls._base.cxx_class)
+ if cls._base.templated:
+ bases.append(cls._base.cxx_class + "<" + \
+ ", ".join(cls._value_dict['template_args'])
+ ">")
+ else:
+ bases.append(cls._base.cxx_class)
# Add in any extra bases that were requested.
bases.extend(cls.cxx_extra_bases)
- if bases:
- base_str = ", ".join(bases)
- code('py::class_<${{cls.cxx_class}}, ${base_str}, ' \
- 'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
- 'm, "${py_class_name}")')
+ template_params = []
+ if hasattr(cls, 'templated') and cls.templated:
+ for template_param in cls._value_dict['template_params']:
+ if isinstance(template_param, list):
+ template_params.append("<" + ", ".join(template_param)
+ \
+ ">")
+ else:
+ template_params.append("<" + template_param + ">")
else:
- code('py::class_<${{cls.cxx_class}}, ' \
- 'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
- 'm, "${py_class_name}")')
- code.indent()
- for exp in cls.cxx_exports:
- exp.export(code, cls.cxx_class)
- code(';')
- code.dedent()
+ template_params.append("")
+
+ for template_param in template_params:
+ if bases:
+ base_str = ", ".join(bases)
+ code('py::class_<${{cls.cxx_class}}${template_param}, ' \
+ '${base_str}, ' \
+ 'std::unique_ptr<${{cls.cxx_class}}${template_param}, '
\
+ 'py::nodelete>>(m, "${py_class_name}${template_param}")')
+ else:
+ code('py::class_<${{cls.cxx_class}}${template_param}, ' \
+ 'std::unique_ptr<${{cls.cxx_class}}${template_param}, '
\
+ 'py::nodelete>>(m, "${py_class_name}${template_param}")')
+ code.indent()
+ for exp in cls.cxx_exports:
+ exp.export(code, cls.cxx_class)
+ code(';')
+ code.dedent()
code()
code.dedent()
code('}')
@@ -806,6 +845,22 @@
# declaring a pointer.
for ns in class_path[:-1]:
code('namespace $ns {')
+ # If it is a template, forward declare template <class T0, class
T1...>
+ if hasattr(cls, 'templated') and cls.templated:
+ template_params = ""
+ temp_param_i = 0
+ if isinstance(cls._value_dict['template_params'][0], list):
+ num_params = len(cls._value_dict['template_params'][0])
+ else:
+ num_params = 1
+ # Create sequence of class T1, class T2, ...
+ while temp_param_i < num_params:
+ template_params += "class T" + str(temp_param_i) + ", "
+ temp_param_i += 1
+ # Remove last comma
+ template_params = template_params[:-2]
+
+ code('template <${template_params}>')
code('class $0;', class_path[-1])
for ns in reversed(class_path[:-1]):
code('} // namespace $ns')
--
To view, visit https://gem5-review.googlesource.com/11629
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I5fa0d69b7c6420e983f5cbae4dcad8e1870cbb65
Gerrit-Change-Number: 11629
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev