dbg-macro
dbg-macro copied to clipboard
Add support for simple structs?
It would be cool to somehow add support for simple struct
s/class
es like
struct CustomDatatype {
int field1;
std::string field2;
};
// …
CustomDatatype c{42, "hello"};
dbg(c);
We would somehow have to iterate over all members... without modifying to original struct definition. Not sure if this is possible in C++ (without reflection).
You can use magic_get (https://www.youtube.com/watch?v=abdeAew3gmQ). Requires C++14.
magic_get
looks fantastic, thank you for the reference.
If there is a small subset of the code that we could include in dbg.h
(assuming there are no licensing problems, see similar discussion in #4 and #5), I think that would be a great addition. It looks like there is no way to get the actual name of the fields, so the best we could do would probably be an output like:
dbg(c); // CustomDatatype{42, "hello"}
(which would already be great).
There's also cista, which uses another approach for simple type reflection (see to_tuple.h for example).
There's also cista, which uses another approach for simple type reflection (see to_tuple.h for example).
Thank you for the reference! Unfortunately, it seems to rely on C++17 functionality, but I would really like dbg(…)
to be C++11 compatible.
Would it be good enough if magic_get
-derived functionality was under #ifdef __cplusplus
, so people using C++14 or later get it automatically and those limited to C++11 define showValue
as usual?
For C++11, I think it's possible to define a macro so SHOW(CustomDatatype, field1, field2)
expands to
inline bool pretty_print(std::ostream& stream, const CustomDatatype& value) {
stream << "CustomDatatype" "{" "field1" ": " << value.field1 << ", " "field2" ": " << value.field2 << "}";
return true;
}
based on this technique but it's tricky.
Agreed. If the concerns above (license, code size) can be clarified, I'd be willing to accept this addition.
@sharkdp Here is a proposal to incorporate this feature. This is a working example that I came up with based on the above discussions and some snippets from here.
Sample driver code
struct MetaData {
std::string name;
int64_t id;
};
struct Entity3D {
int32_t x, y, z;
MetaData meta;
};
DBG_REGISTER_STRUCT(MetaData, name, id)
DBG_REGISTER_STRUCT(Entity3D, x, y, z, meta)
int32_t main() {
Entity3D e = {3, 2, 1, {"dummy_name", 98765}};
dbg(e); // [main.cc:34 (main)] e = {'x': 3, 'y': 2, 'z': 1, 'meta': {'name': "dummy_name", 'id': 98765}} (Entity3D)
}
If this is satisfactory I'll be glad to open a PR!
Thank you. If we add support for this, then I would definitely look for a solution which does not require any additional macro calls like DBG_REGISTER_STRUCT
.