-
Notifications
You must be signed in to change notification settings - Fork 121
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
Add support for unions (like variants) #969
Comments
Your single lambda approach invokes the function for both reading and writing. To split out different behaviors for reading and writing with lambdas you can register separate lambdas using A basic example: struct custom_load_t
{
std::vector<int> x{};
std::vector<int> y{};
struct glaze
{
static constexpr auto read_x = [](auto& s) -> auto& { return s.x; };
static constexpr auto write_x = [](auto& s) -> auto& { return s.y; };
static constexpr auto value = glz::object("x", glz::custom<read_x, write_x>);
};
};
|
You probably have a good reason for using unions, but Glaze also has a lot of support for std::variant that can achieve similar goals: docs/variant-handling.md |
Thanks for the quick response! This looks like what I'm going for and I'll give it a try. In the meantime I came up with another solution where I define a "normalizing" struct to act as a shim for reading/writing data that just uses the
I'll weigh the two options if I ever need to add new structs, and if I ever move to variants I'll give that a second look. One last question (slightly related), my glz::meta seems to output the incorrect key (just uses member name for reflection rather than how I specified it). Is there an option needed in order to enable dasherized/hyphenated key names? Below is the output
|
Cool, that sounds good. And, std::variant is really nice if you get around to experimenting with it.
This issue is something I haven't seen before. Maybe your |
No problem. I think it's what you're saying, I changed the names entirely and they don't seem to have any effect. This should be a working example (I added a bit more of my actual code to illustrate what's happening):
Reflection.h
These two structs are in separate header files inside of the same library, built using CMake. Here's my test code:
|
No need to chase this down, it was the include order that was throwing things off. I fixed it by just moving the meta specialization into the same header. Appreciate all the help! |
Sorry to reopen this, but kind of ran into trouble with this approach further down the line, but it seems like there isn't a way to access the data read from the json string inside my lambda:
When I run this code all I get in the lambda is the empty struct Im trying to read into. I guess the real thing I'm after here is full control over how data gets written/read from json based on access to both the struct we're reading into, and the raw json data. Is there a way to pass more arguments to custom readers and writers than just something like: |
I think I see how to do this now based on the compile error messages
It still doesn't eliminate the need for tagged union support (I'd imagine it'd be very similar to the variant support) We do have strong reasons for wanting to control the size of the union but if we ever make the change it should work for our purposes. Are there any plans to support tagged unions? e.g.
I started down my own workaround to imitate what you do for variant, but it seems there's no support for union:
|
The problem is that I don't think C++ has a mechanism to determine the alternative types of a union. Whereas, with a std::variant we can look at the types at compile time and build logic about how to serialize/deserialize it. In the I do think it would be useful to add union support to Glaze (for trivial types). I'll update this issue's name appropriately. |
Hello there, new to using this library so trying to find the best way to use it to serialialize/unserialize the following struct to a known JSON format:
So basically, I have a struct that contains some members that are dependent on each other, several of which require transformation functions to/from json, specifically focusing on m_union, m_unionType for this example.
I've been experimenting with the glaze metadata and so far was able to come up with this for serializing the union based on the type:
The output JSON in buf is:
"{"custom_field_name":"valueForType1" }
, which is great, just what I intended.This works for
glz::write_json(data, buffer)
, wherecustom_field_name
is the name I want the field to have. However, it isn't clear to me how to provide the analogous glz::read meta method (does the lambda get applied for both read/write or is there a way to define the read lambda explicitly & separately?)How would I use glaze::meta to deserialize (
read_json
orread
) a field (potentially with different JSON field name) back into my union/union type members?My thought is that there would be an analogous meta struct defined for doing glz::read into the same struct, just with different lambdas or static utility methods I have defined outside my Data struct, but I haven't been able to figure out how this is done yet.
My current approach is using
to_json
andfrom_json
but I'm not sure if it's the correct way to do this. Right now the API seems to have a hook for transforming a struct, but Im not sure I can specify which field Im reading/writing from/to. I've seen examples specializing this template for each individual struct field type, but none yet for working with other struct fields that depend on each other. To do that I would imagine we would just specialize the whole struct and read/write to each field inside each to/from method:Thanks, let me know if I can clarify my issue any further or if this is the proper way to accomplish this.
The text was updated successfully, but these errors were encountered: