diff --git a/README.md b/README.md index 2f4e94078..fcb92c151 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Assume you want to create the JSON object "list": [1, 0, 2], "object": { "currency": "USD", - "value": "42.99" + "value": 42.99 } } ``` @@ -87,7 +87,7 @@ j["answer"]["everything"] = 42; j["list"] = { 1, 0, 2 }; // add another object (using an initializer list of pairs) -j["object"] = { {"currency", "USD"}, {"value", "42.99"} }; +j["object"] = { {"currency", "USD"}, {"value", 42.99} }; // instead, you could also write (which looks very similar to the JSON above) json j2 = { @@ -101,12 +101,24 @@ json j2 = { {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, - {"value", "42.99"} + {"value", 42.99} }} }; ``` -Note that in all cases, you never need to "tell" the compiler which JSON value you want to use. +Note that in all theses cases, you never need to "tell" the compiler which JSON value you want to use. If you want to be explicit or express some edge cases, the functions `json::array` and `json::object` will help: + +```cpp +// ways to express the empty array [] +json empty_array_implicit = {{}}; +json empty_array_explicit = json::array(); + +// a way to express the empty object {} +json empty_object_explicit = json::object(); + +// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] +json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) }; +``` ### Serialization / Deserialization @@ -207,6 +219,55 @@ for (json::iterator it = o.begin(); it != o.end(); ++it) { } ``` +### Conversion from STL containers + +Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON types (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends how the elements are ordered in the respective STL container. + +```cpp +std::vector c_vector {1, 2, 3, 4}; +json j_vec(c_vector); + +std::set c_set {"one", "two", "three", "four", "one"}; +json j_set(c_set); // only one entry for "one" is used + +std::unordered_set c_uset {"one", "two", "three", "four", "one"}; +json j_uset(c_uset); // only one entry for "one" is used + +std::multiset c_mset {"one", "two", "one", "four"}; +json j_mset(c_mset); // only one entry for "one" is used + +std::unordered_multiset c_umset {"one", "two", "one", "four"}; +json j_umset(c_umset); // both entries for "one" are used + +std::deque c_deque {1.2, 2.3, 3.4, 5.6}; +json j_deque(c_deque); + +std::list c_list {true, true, false, true}; +json j_list(c_list); + +std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; +json j_flist(c_flist); + +std::array c_array {{1, 2, 3, 4}}; +json j_array(c_array); +``` + +Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys are can construct an `std::string` and whose values can be used to construct JSON types (see examples above) can be used to to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container. + +```cpp +std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; +json j_map(c_map); + +std::unordered_map c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; +json j_umap(c_umap); + +std::multimap c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_mmap(c_mmap); // only one entry for key "three" is used + +std::unordered_multimap c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; +json j_ummap(c_ummap); // only one entry for key "three" is used +``` + ### Implicit conversions The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted. diff --git a/test/json_unit.cc b/test/json_unit.cc index 6712dc6a8..8a9bfce0c 100644 --- a/test/json_unit.cc +++ b/test/json_unit.cc @@ -408,6 +408,11 @@ TEST_CASE("array") CHECK(j_vec.type() == json::value_t::array); CHECK(j_vec.size() == 4); + std::vector> cr_vector {{1, 2}, {3}, {4, 5, 6}}; + json j_vecr(cr_vector); + CHECK(j_vecr.type() == json::value_t::array); + CHECK(j_vecr.size() == 3); + std::set c_set {"one", "two", "three", "four", "one"}; json j_set(c_set); CHECK(j_set.type() == json::value_t::array);