3.8. Templates#
Yes, you read that correctly: Caterpillar supports class templates, similar to the concept in C++. Templates allow you to create generic structures that can be tailored with specific types when they are derived.
If you’d like more details about the design decisions and limitations regarding templates, refer to the Templates section in the data model description.
3.8.1. Defining a Template#
You can define templates using a special syntax. First, you create template type variables, and then you use them within your class definition. These templates can be instantiated later with specific types or values.
A = TemplateTypeVar("A")
@template(A, "B") # <-- either strings or global variables
class FormatTemplate:
foo: A[uint8::] # <-- prefixed generic array
bar: B # <-- this won't throw an exception, because
# 'B' is created temporarily.
A
is a template type variable of an unknown generic typeThe class
FormatTemplate
usesA
and:code: B as type parameters, but these types will be defined when the template is derived into a specific class.A[uint8::]
creates a generic array prefixed with the typeuint8
.B
is used as a type in the fieldbar
. This type will be specified when the template is instantiated, and the library ensures no exceptions are thrown becauseB
is set dynamically during class definition.
3.8.2. Deriving a Template#
Once you have defined a template, you can create specific classes (known as derivations) by providing the template with concrete types. This allows you to reuse the logic from the template with different type combinations, e.g. creating specialized structs.
@struct
class Format32(derive(FormatTemplate, A=uint32, B=uint32)): # <- Derived Struct
baz: uint32
Sub-templates or partial templates allow you to create smaller, more focused templates based on an existing template. When you derive a sub-template, only some of the template parameters are provided initially, and others are deferred.
# template sub-classes are allowed as well
FormatSubTemplate = derive(FormatTemplate, A=uint8, partial=True) # <- Derived Template
Note
While you can pass keyword arguments to define template parameters, you can also use positional arguments if the original template decorator defines them in that way.
Warning
Currently, there are some limitations with the template type variables, and extended support for this feature will be part of future enhancements in this project.