Prerequisites:
I have no access to boost.
Im have third-party C header, what describes structs, like
typedef struct
{
int int_value;
char char_value;
bool bool_value;
}
example_struct_t;
I cant make any changes in it.
Target:
I need to serialize data from this structs in custom text format.
I have planned, to make by-type serializers, like SerializerBase, SerializerINT::SerializerBase
, SerializerCHAR::SerializerBase
and etc.
And use it in some template class, (pseudocode):
Serializer<example_struct_t = T>
{
foreach_field_in<T> is field
{
if(field.type == typeof(int))
{
AddToResult(SerializerINT::Serialize(field.value));
}
}
}
Or something less "templated" (pseudocode):
class SerializationSequence<example_struct_t = T>
{
std::vector<SerializerBase> sequence;
SerializationSequence()
{
sequence = GenerateMethodsSequenceForThisStruct<T>(); // Compile time
}
}
Does C has any way to parse this structs in compile time and making something, like
std::tuple<int,char,bool>
?
CodePudding user response:
C reflection proposal does this easy. It isn't in C yet.
There are various ways you can get at C parse trees. It is pretty extreme and involves hacking or using a custom compiler.
Finally, there are some hacks involving detecting airity of brace construction and unpacking with []
s. This might be the most practical.
The basic idea is you can test, in an immeditate context, if T{a0, a1, a2}
is legal. You make a type that has a "universal" template<class T>operator T()
, and find the largest count of those you can make an instance of your type from using {}
s.
Then you unpack via
auto&& [b0, b1, b2] = t;
return std::make_tuple(b0,b1,b2);
and extract the types from the resulting tuple, with a custom ("hand" written) version for each count.
It requires a bunch of code generation, has a max airity it handles, it only handles POD types well (with some extensions). But that technique is the closest you can get in current C .
Here is someone using this approach. I have no idea if they did it well, the license they used, etc; it is just an example of someone else doing this technique.
CodePudding user response:
The OP wrote that using boost is not possible, but then noted that the inclusion of a single header is possible. magic_get aka boost.pfr is a 1 header library, and should do exactly what the OP wants: turning a simple struct into a tuple. See github.com/apolukhin/magic_get