1

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;
}
  • Perhaps consider something more full featured, like https://github.com/nlohmann/json – Retired Ninja May 19 '21 at 06:19
  • Another reason to consider another library, from cpprestsdk's github page: `cpprestsdk is in maintenance mode and we do not recommend its use in new projects.` – parktomatomi May 19 '21 at 06:53

0 Answers0