zserio icon indicating copy to clipboard operation
zserio copied to clipboard

Define type_traits or actual templates for templated types

Open MikeLankamp-TomTom opened this issue 2 years ago • 3 comments

zserio supports templated types. To enable easily writing generic code to use them, it would be nice for the C++ generator to define a type_traits instance of it.

For instance, for the following definition:

struct Field<FOO>
{
    FOO value;
};

instantiate Field<SomeType> SomeField;

It would be nice if this was also generated:

template <typename FOOType>
struct type_traits<Field<FOOType>>
{
    using FOO = FOOType;
};

This way, generic code can easily be written to deal with any Field:

template <typename FieldType>
void HandleField(FieldType& field) {
  type_traits<FieldType>::FOO new_value = /* ... */;
  field.value = new_value;
}

Even better might be if templated types are generated as actual C++ templates, to cut down on the amount of repetition and combine with type_traits, e.g.:

template <typename FOO>
class Field {
    using FOOType = FOO;

    const FOO& getValue() const;
    // ...
}

using SomeField = Field<SomeType>;

That way the code using it can be made without type_traits:

template <typename FOOType>
void HandleField(Field<FOOType>& field) {
  FOOType new_value = /* ... */;
  field.value = new_value;
}

MikeLankamp-TomTom avatar Dec 14 '23 19:12 MikeLankamp-TomTom

Thanks for type_traits idea, this could be usefull.

Regarding generation of C++ templates, we had problem with simple types, please see https://github.com/ndsev/zserio/discussions/444. This could be annoying for users as well. But if it turns out that this won't be a big problem, we can try to implement zserio templates directly using C++ templates.

mikir avatar Dec 15 '23 10:12 mikir

To comment on #444, I will suggest an approach that I also mentioned in #557: strong typedefs.

If uint16 and varuint16 are strong typedefs of std::uint16_t, then method overloads will work as you expect. And this will have benefits for #557 as well, creating unions can be done with a constructor overloaded on strong typedefs, and this will even work for types which are typedef'd to "dummy" types, just for setting flags.

MikeLankamp-TomTom avatar Dec 15 '23 10:12 MikeLankamp-TomTom

To comment on #444, I will suggest an approach that I also mentioned in #557: strong typedefs.

If uint16 and varuint16 are strong typedefs of std::uint16_t, then method overloads will work as you expect. And this will have benefits for #557 as well, creating unions can be done with a constructor overloaded on strong typedefs, and this will even work for types which are typedef'd to "dummy" types, just for setting flags.

Yes, strong typedefs are a good idea. We support this.

mikir avatar Dec 15 '23 10:12 mikir