std::pair of structs fails round trip
Tested on msvc, glaze 3.1.9, 3.2.1 and 3.2.5
Given code such as
#include <iostream>
#include "glaze-3.2.5/include/glaze/glaze.hpp"
struct FirstStruct {
int64_t MyVar {};
};
struct SecondStruct {
int64_t OtherVar{};
};
int main() {
std::pair<FirstStruct, SecondStruct> testPair{ {1}, {2} };
std::string buffer;
auto ec = glz::write_json(testPair, buffer);
if (!ec) {
std::cout << buffer << std::endl;
} else {
std::cout << "Error: " << glz::format_error(ec) << std::endl;
}
std::pair<FirstStruct, SecondStruct> testPair2;
auto testPairDeserRes = glz::read_json(testPair2, buffer);
if (!testPairDeserRes) {
std::cout << testPair2.first.MyVar << ":" << testPair2.second.OtherVar << std::endl;
} else {
std::cout << "Error: " << glz::format_error(testPairDeserRes, buffer) << std::endl;
}
return 0;
}
The output is
{"{\"MyVar\":1}":{"OtherVar":2}}
Error: 1:17: expected_quote
{"{\"MyVar\":1}":{"OtherVar":2}}
^
If using a pair of fundamental types, the round trip succeeds. It looks like this is treated as a map, and the "key" is quoted when serializing, but the deserialization also expects the value to be quoted?
Yes, this is an active issue here #1000, but thanks for bringing more attention to it.
I see, I wasn't sure if it was related since that mentioned arrays specifically. Thanks!
It's taken me a while to come back to this, but I've been improving the pair handling.
Glaze treats std::pair as a single element object (key and value). This works well with C++ because types like std::map use std::pair for elements.
A pair of structs like you are using here doesn't make a lot of sense, because the first struct would be the key for the other struct. And, you can't generally decode a string key into an object (struct).
I'm sorry I didn't look into this more carefully before. For your use case you should probably just use a std::tuple<FirstStruct, SecondStruct>. Glaze treats a std::tuple as an array, which will properly roundtrip.
I'm going to close this issue, but definitely comment if there is something that you think ought to be done.