|
| 1 | +# Template types |
| 2 | + |
| 3 | +Template type definitions provide a shorthand syntax to avoid repeating the defintion of methods on common generic types. All of the items within a template type definition are copied into each matching concrete type definition. At the moment, template types are considered unstable and ust be activated with the `#unstable(template_types)` directive. |
| 4 | + |
| 5 | +For example: |
| 6 | +``` |
| 7 | +#unstable(template_types) |
| 8 | +
|
| 9 | +type<T> ::std::option::Option<T> { |
| 10 | + constructor Some(T); |
| 11 | + constructor None; |
| 12 | + fn unwrap(self) -> T; |
| 13 | + fn is_some(&self) -> bool; |
| 14 | +} |
| 15 | +
|
| 16 | +type ::std::option::Option<i32> { |
| 17 | + #layout(size = 8, align = 8); |
| 18 | + wellknown_traits(Copy, Debug); |
| 19 | + // the constructors and methods are automatically defined |
| 20 | +} |
| 21 | +``` |
| 22 | + |
| 23 | +You can also define well-known traits and layouts in template types: |
| 24 | +``` |
| 25 | +type<T> [T] { |
| 26 | + wellknown_traits(?Sized); |
| 27 | +} |
| 28 | +
|
| 29 | +type<T> ::std::vec::Vec<T> { |
| 30 | + #layout(size = 24, align = 8); |
| 31 | +} |
| 32 | +
|
| 33 | +type<T> option::Option<&T> { |
| 34 | + #layout(size = 8, align = 8); |
| 35 | + wellknown_traits(Copy); |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +Note that multiple template defintions can apply to the same concrete type, so `Option<&i32>` would inherit definitions from the `Option<T>` template and the `Option<&T>` template. |
| 40 | + |
| 41 | +You can also override the layout given in a template: |
| 42 | +``` |
| 43 | +type<T> Box<T> { |
| 44 | + #layout(size = 8, align = 8); |
| 45 | + // Most Boxed types are 8 bytes |
| 46 | +} |
| 47 | +
|
| 48 | +type<T> Box<i32> {} // Inherits the 8 byte layouts |
| 49 | +
|
| 50 | +type Box<dyn crate::MyTrait> { |
| 51 | + #layout(size = 16, align = 8); |
| 52 | + // Boxed trait objects are 16 bytes |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +Zngur will still only emit C++ definitions for the concrete types that are defined. Template definitions on their own do not result in any C++ code. This also means that at the moment, any type mentioned in a template definition must be individually defined as well. For example, the following code will fail to compile unless `Option<String>` is defined to make `Result::<String, i64>::ok` valid. If the `Option<T>` template from above is defined, then we must add a definition for `String` as well to support `Option::<String>::unwrap`. |
| 57 | +``` |
| 58 | +type<T, E> ::std::result::Result<T, E> { |
| 59 | + fn ok(self) -> ::std::option::Option<T>; |
| 60 | +} |
| 61 | +
|
| 62 | +type ::std::result::Result<::std::string::String, i64> { |
| 63 | + #layout(size = 24, align = 8); |
| 64 | +} |
| 65 | +``` |
0 commit comments