I am using CppRestSdk and Guillaume's Json parsing solution from here C++ JSON Serialization . It works great for simple types like string, int and i have also been able to make it work recursively for sub-objects but array (vectors) don't work.
Are there any examples of how to make this work for arrays or std::vector? here is my code so far
struct PropertyImpl {
constexpr PropertyImpl(T Class::*aMember, const wchar_t * aName) : member{ aMember }, name{ aName } {}
using Type = T;
T Class::*member;
const wchar_t * name;
};
template<typename Class, typename T>
constexpr auto property(T Class::*member, const wchar_t * name) {
return PropertyImpl<Class, T>{member, name};
}
template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
using unpack_t = int[];
(void)unpack_t {
(static_cast<void>(f(std::integral_constant<T, S>{})), 0)..., 0
};
}
template<typename T> T asAny(const web::json::value& value)
{
return fromJson<T>(value);
}
template<>
int asAny<int>(const web::json::value& value)
{
if (value.is_null())
{
return -1;
}
return value.as_integer();
}
template<>
std::wstring asAny<std::wstring>(const web::json::value& value)
{
if (value.is_null())
{
return L"";
}
return value.as_string();
}
template<typename T>
T fromJson(const web::json::value& data) {
T object;
// We first get the number of properties
constexpr auto nbProperties = std::tuple_size<decltype(T::properties())>::value;
// We iterate on the index sequence of size `nbProperties`
for_sequence(std::make_index_sequence<nbProperties>{}, [&](auto i) {
// get the property
constexpr auto property = std::get<i>(T::properties());
// get the type of the property
using Type = typename decltype(property)::Type;
// set the value to the member
// you can also replace `asAny` by `fromJson` to recursively serialize
if (data.has_field(property.name))
{
object.*(property.member) = asAny<Type>(property.name);
}
});
return object;
}
struct Owl
{
std::string name;
};
struct Cat
{
std::string name;
int age;
};
struct Dog {
std::string barkType;
std::string color;
int weight = 0;
Cat cat;
std::vector<Owl> owls;
bool operator==(const Dog& rhs) const {
return barkType == rhs.barkType && color == rhs.color && weight == rhs.weight;
}
constexpr static auto properties = std::make_tuple(
property(&Dog::barkType, "barkType"),
property(&Dog::color, "color"),
property(&Dog::weight, "weight")
property(&Dog::cat, "cat")
property(&Dog::owls, "owls")
);
};
int main() {
auto dog = fromJson<Dog>(jsonDog);
return 0;
}