Skip to content
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

Serializing std::variant<T, std::vector<T>> #2045

Closed
rioki opened this issue Apr 16, 2020 · 3 comments
Closed

Serializing std::variant<T, std::vector<T>> #2045

rioki opened this issue Apr 16, 2020 · 3 comments
Labels
kind: enhancement/improvement state: needs more info the author of the issue needs to provide more details

Comments

@rioki
Copy link

rioki commented Apr 16, 2020

I am aware of #1261 , but though one special case may be considered. I use a variant to read "scalar" and "vector" of same types. The JSON code would be

{
  "scalar": 42,
  "vector": [1, 2, 3, 4]
}

To map this data into C++ I use a std::variant<double, std::vector> and found the serialization and deserialization to be a bit overly complicated.

After reading up on #1261 I understand why general purpose std::variant can not be serialized and the proposed solution there is not really useful for my use case.

I came up with the following code to integrate this use case into the built in serialization:

namespace nlohmann
{
	template <typename T>
	struct adl_serializer<std::variant<T, std::vector<T>>>
	{
		static void to_json(json& j, std::variant<T, std::vector<T>> const& v)
		{
			std::visit([&](auto&& value) {
				j = std::forward<decltype(value)>(value);
			}, v);
		}

		static void from_json(json const& j, std::variant<T, std::vector<T>>& v)
		{
			if (j.is_array())
			{
				v = j.get<std::vector<T>>();
			}
			else
			{
				v = j.get<T>();
			}
		}
	};
}

Obviously this is not the general / general solution as other containers should be considered and probably it can be done better. It would be nice if this use case can be included in the library, but if not I understand and this request can still be useful for posterity.

@nlohmann
Copy link
Owner

What is your proposal?

@nlohmann nlohmann added the state: needs more info the author of the issue needs to provide more details label Apr 19, 2020
@rioki
Copy link
Author

rioki commented Apr 24, 2020

It's right there in the comment, IMHO all you need to do is duplicate the vector version and supply a std::list and std::deque version and it basically fills the requirement. For C++20 you could build a version that builds on the Container concept, but that is something I would need to research.

@nlohmann
Copy link
Owner

Processing <std::variant<T, std::vector<T> is a very specific situation. I am not sure why such a case should be added to the library. It also makes an assumption how the serialization should look like.

@nlohmann nlohmann closed this as completed May 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement/improvement state: needs more info the author of the issue needs to provide more details
Projects
None yet
Development

No branches or pull requests

2 participants