Filling up an element_array

Jun 17, 2013 at 3:27 PM
Edited Jun 17, 2013 at 3:28 PM
Hello everybody.

I'm using the lastest release of Casablanca.

I'm using it to call a Post method in a web service of mine. So far, usage have been successful. The problem I'm facing now is while dynamically creating a json array. For this purpose I'm using an web::json::value::element_vector, since that's what json::value::array constructor needs.

The problem is, I dinamically generate 'std::json::value's, and try inserting them to the above mentioned web::json::value::element_vector, but calling insert on it fails since it's expecting a pair of values, but what does it means? I'm inserting values into an array, so it makes sese to me that it expect a single value. What does this pair means?
Jun 17, 2013 at 3:45 PM
Edited Jun 17, 2013 at 3:45 PM
Hi fabzter,

To make iterating over both objects and arrays inexpensive and the same, we store each array element as a pair, with the index as the first element. Constructing an array directly from an element_vector when you know exactly how many elements you will have is fast, but you have to know what you are doing. Note that the element vector should start at 0 and increase by 1 for each element: no gaps.
    json::value::element_vector e;
    e.push_back(std::make_pair(json::value(0), json::value(false)));
    e.push_back(std::make_pair(json::value(1), json::value::string(U("hello"))));
    json::value arr(e);
A more convenient way to create an array would be to create a value and then start assigning into the elements of the array. As you keep assigning into the array, its underlying storage will expand, and you may wind up with re-allocation of storage, so it may not be as fast as the first method in situations where you know the number of elements beforehand.
   json::value arr;
   arr3[0] = json::value(false);
   arr3[1] = json::value(U("hello"));
Jun 17, 2013 at 3:58 PM
Edited Jun 17, 2013 at 4:00 PM
Hi and thanks, Niklas.

Well, it does make some sense once explained :) But I still think the intention is not very clear. I think it would be nice having this detail explained somewhere.
Jun 17, 2013 at 4:07 PM
Edited Jun 17, 2013 at 4:07 PM
It's all about making this possible:
    typedef std::vector<std::pair<json::value,json::value>>::iterator iterator;
Unless we store array elements as a pair, we couldn't have a single iterator definition for both objects and arrays and still be efficient at runtime. In other words, we traded off space for speed, and unfortunately, that leaks into the API. You might argue that letting this leak occur is a no-no, but to allow you to get a little bit more efficiency out of the API when you want it (and can spend the time learning what to do), we felt it was right to leave the constructor that takes the vector in the API.

We take a look at how we can better document this on the JSON section. Another resource, in general, is to take a look at the source code for the unit tests, where most of the APIs (overall, not just JSON) are covered.