-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Assigning between different json types #977
Comments
Related: #972 |
I haven't tried with #972 yet, but this issue is because of the to/from_json mechanism. Trying to convert from In order to fix it, we have to decide if we want to support conversions between different |
I would say that it should be supported as much as possible, as long as the data storage types are compatible. If not, then it should probably be a compile error instead of a runtime error. |
I think having a conversion between different |
Thanks for replies and a discussion. |
I'll work on it this week. |
It worked! Thanks.
#include <nlohmann/json.hpp>
#include <iostream>
#include <type_traits>
namespace ns{
struct foo{
int x;
};
template <typename, typename SFINAE = void>
struct foo_serializer;
template<typename T>
struct foo_serializer<T,typename std::enable_if<std::is_same<foo, T>::value>::type> {
template <typename BasicJsonType>
static void to_json(BasicJsonType& j, const T& value) {
j=BasicJsonType{{"x",value.x}};
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) { // !!!
nlohmann::from_json(j.at("x"),value.x);
}
};
template<typename T>
struct foo_serializer<T, typename std::enable_if<!std::is_same<foo, T>::value>::type> {
template <typename BasicJsonType>
static void to_json(BasicJsonType& j, const T& value) {
::nlohmann::to_json(j, value);
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) { //!!!
::nlohmann::from_json(j, value);
}
};
}
using foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
std::uint64_t, double, std::allocator,ns::foo_serializer>;
int main(){
foo_json lj=ns::foo{3};
ns::foo ff=lj;
std::cout<<lj<<std::endl;
std::cout<<ff.x<<std::endl;
nlohmann::json nj=lj; // This line works as expected
} |
Great! By the way, I think you could simplify your serializer a bit: template<typename T, typename = void>
struct foo_serializer {
template <typename BasicJsonType>
static void to_json(BasicJsonType& j, const T& value) {
::nlohmann::to_json(j, value);
}
template <typename BasicJsonType>
static void from_json(const BasicJsonType& j, T& value) {
::nlohmann::from_json(j, value);
}
}; This is roughly the implementation of the |
Thanks for a comment. I'm new to SFINAE and I could not write good example code here. using array_json =
nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
std::uint64_t, double, std::allocator,
array_adl_serializer>;
template <typename T>
struct array_adl_serializer<T, typename std::enable_if<!yos::has_to_json_array<
T, array_json>::value>::type> {
template <typename BasicJsonType, typename ValueType>
static void from_json(BasicJsonType&& j, ValueType& t) {
::nlohmann::from_json(std::forward<BasicJsonType>(j), t);
}
template <typename BasicJsonType, typename ValueType>
static void to_json(BasicJsonType& j, ValueType&& t) {
::nlohmann::to_json(j, std::forward<ValueType>(t));
}
};
template <typename T>
struct array_adl_serializer<T, typename std::enable_if<yos::has_to_json_array<
T, array_json>::value>::type> {
template <typename BasicJsonType, typename ValueType>
static void from_json(BasicJsonType&& j, ValueType& t) {
t.from_json(std::forward<BasicJsonType>(j));
}
template <typename BasicJsonType, typename ValueType>
static void to_json(BasicJsonType& j, ValueType&& t) {
// forward rvalue
std::forward<ValueType>(t).to_json_array(j);
}
}; The array_adl_serializer look for T::to_json_array and use it. |
Looks good, I would still only change the first partial specialization to be the default implementation: template <typename, typename>
struct array_adl_serializer {
template <typename BasicJsonType, typename ValueType>
static void from_json(BasicJsonType&& j, ValueType& t) {
::nlohmann::from_json(std::forward<BasicJsonType>(j), t);
}
template <typename BasicJsonType, typename ValueType>
static void to_json(BasicJsonType& j, ValueType&& t) {
::nlohmann::to_json(j, std::forward<ValueType>(t));
}
}; Then, you can keep the second partial specialization as is :) |
I have 2 different json types, like following:
Basically, they are same type except their JSONSerializer, and I want to copy/assign them one another. But when I copy one type to the other, the program receives SIGSEGV. It seems stack overflow.
How can I make it work?
Demonstration code:
Tested compilers
The text was updated successfully, but these errors were encountered: