-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto-generated ext_h101 structs #865
Comments
I don't quite get it. What is its advantage compared to directly defining the struct? struct MyStruct{
uint_16 fFoo;
uint_16 fBar;
uint_16 fBaz;
};
auto a = Data<MyStruct>{}; |
Because that way, you end up with stuff like this, e.g. each variable needs three lines of macros like:
By contrast, my way needs only a different macro invocation instead of macro definitions to be able to do the equivalent of the above. Naturally, my code is still a toy example. In reality, you would have to call When R3BUcesbSource is rewritten, there is nothing to stop us from using
While it would be tempting to also autogenerate the FooReader code altogether, it is probably not feasible for readers due to resource overhead. (Of course, there is the way to define every class as a |
Alright, maybe we could first see what are the "industrial standards" to serialise or deserialise C++ data structures. As far as I know, the most popular one is google protobuf. It's very similar to our home-made ucesb, which requires users to define the data structure in a separate file. Then it generates a header file containing the corresponding C++ structure. "cereal" is another type of serialisation tool, which instead requires user to define a serialisation method inside the data structure, such as: struct MyRecord
{
uint8_t x, y;
float z;
template <class Archive>
void serialize( Archive & ar )
{
ar( x, y, z );
}
}; And then you call a global function to serialise/deserialise the data structure. The third method (the best one in my opinion) can be found in libraries like "boost::serialization" or "zpp_bits", which requires nothing from users except the plain definition of the C++ structure: struct MyStruct{
uint_16 fFoo;
uint_16 fBar;
uint_16 fBaz;
} myStruct;
auto data = std::vector<std::byte>{};
Serialize(data, myStruct);
Deserialize(data, myStruct); And what is blowing my mind is that the third one is very simple to implement and there is no heavy usage on C macros. The trick of imitating a reflection on data structure is using the structure binding. But we need to numerate every single case of such kind of bindings: if constexpr (size == 2) auto&& [m1, m2] = myStruct;
else if constexpr (size ==3) auto && [m1, m2, m3] = myStruct;
//... And this can get quite long. So the best solution is to wait for the new feature of C++26, when we can do something like: auto && [ ... m ] = myStruct; |
When I stated, in my musings in #712
I was wrong. (I am unsure if my C++ is good enough to make this a case of me fulfilling Clarke's first law.)
While you can not directly pass on anonymous classes as template parameters, you can certainly pass lambda expressions returning arbitrary types as template parameters, which is sufficient.
See proof of concept here. (Trigger warnings: C++, preprocessor macros, virtual inheritance, variadic templates).
The gist is that you can run
where
a
will have members fFoo, fBar and fBaz and onInit will call lambdas which have access to their variables and the names of these variables as a string.For zero suppressed 1d arrays, we could have a macro which takes a name Foo and defines Foo, FooI and Foov appropriately, as well as calling the correct
EXT_STR_ITEM_INFO_...
for them.Arguments could be easily added to the onInit and the lambda expressions. The handling of n-dimensional arrays is left as an exercise for the reader. So is passing stuff to constructors, if one needed that for some reason.
I think in the spirit of "Don't Repeat Yourself" (DRY), it is better to have this in one place instead of having longish macros saying
map the variable Foo to "Foo"
for 100s of variables.The text was updated successfully, but these errors were encountered: