Custom generators
Some bindings cannot be produced from the parsed C++ signatures alone — for
example a .def built from a hard-coded list, or a template-method instantiation
like AddCellWriter<CellAgesWriter>. A custom generator lets you inject
hand-written binding code for a class while cppwg generates the rest.
Point a class at a generator with custom_generator:
- name: MeshBasedCellPopulation
custom_generator: "CPPWG_SOURCEROOT/wrapper/PopulationWriterCustomTemplate.py"
CPPWG_SOURCEROOT is replaced with the source root directory. The file defines a
subclass of cppwg.templates.custom.Custom, overriding the hooks it needs.
Hooks
Hook |
Injects |
Where |
|---|---|---|
|
Code before the registration block |
Before |
|
Extra |
Into the |
|
Header names the emitted code needs |
The wrapper |
class_name is the wrapper alias for the current instantiation (e.g.
Foo_2_2), so pre-code and def-code can refer to the class by that name.
Injecting .def code
import cppwg.templates.custom
class PopulationWriterCustomTemplate(cppwg.templates.custom.Custom):
WRITERS = ["CellAgesWriter", "CellIdWriter"]
def get_class_cpp_def_code(self, class_name):
return "".join(
f'.def("AddCellWriter{w}", &{class_name}::AddCellWriter<{w}>)\n'
for w in self.WRITERS
)
Declaring the headers your code needs
Code emitted by a generator can reference types cppwg never sees in the parsed
signatures, so auto_includes cannot resolve their
headers and they would otherwise have to be repeated under source_includes.
Override get_source_includes() to return the header names — spelled as under
source_includes, a bare name like Foo.hpp (cppwg adds the quotes) or an
angle-bracket string like <foo>. cppwg adds them to the wrapper’s #include
block (deduplicated), so the generator and the includes its code needs live in
one place:
class PopulationWriterCustomTemplate(cppwg.templates.custom.Custom):
WRITERS = ["CellAgesWriter", "CellIdWriter"]
def get_class_cpp_def_code(self, class_name):
return "".join(
f'.def("AddCellWriter{w}", &{class_name}::AddCellWriter<{w}>)\n'
for w in self.WRITERS
)
def get_source_includes(self, *args, **kwargs):
return [f"{w}.hpp" for w in self.WRITERS]
See the MutableElement, ReplicatableVector, and population classes in
examples/cells/dynamic/config.yaml and their generator templates for full
examples.