"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "doc/tutorial.md" between
rapidjson-1.0.2.tar.gz and rapidjson-1.1.0.tar.gz

About: RapidJSON is a fast JSON parser/generator for C++ with both SAX/DOM style API.

tutorial.md  (rapidjson-1.0.2):tutorial.md  (rapidjson-1.1.0)
skipping to change at line 136 skipping to change at line 136
Array is similar to `std::vector`, instead of using indices, you may also use it erator to access all the elements. Array is similar to `std::vector`, instead of using indices, you may also use it erator to access all the elements.
~~~~~~~~~~cpp ~~~~~~~~~~cpp
for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
printf("%d ", itr->GetInt()); printf("%d ", itr->GetInt());
~~~~~~~~~~ ~~~~~~~~~~
And other familiar query functions: And other familiar query functions:
* `SizeType Capacity() const` * `SizeType Capacity() const`
* `bool Empty() const` * `bool Empty() const`
### Range-based For Loop (New in v1.1.0)
When C++11 is enabled, you can use range-based for loop to access all elements i
n an array.
~~~~~~~~~~cpp
for (auto& v : a.GetArray())
printf("%d ", v.GetInt());
~~~~~~~~~~
## Query Object {#QueryObject} ## Query Object {#QueryObject}
Similar to array, we can access all object members by iterator: Similar to array, we can access all object members by iterator:
~~~~~~~~~~cpp ~~~~~~~~~~cpp
static const char* kTypeNames[] = static const char* kTypeNames[] =
{ "Null", "False", "True", "Object", "Array", "String", "Number" }; { "Null", "False", "True", "Object", "Array", "String", "Number" };
for (Value::ConstMemberIterator itr = document.MemberBegin(); for (Value::ConstMemberIterator itr = document.MemberBegin();
itr != document.MemberEnd(); ++itr) itr != document.MemberEnd(); ++itr)
skipping to change at line 169 skipping to change at line 178
Type of member a is Array Type of member a is Array
~~~~~~~~~~ ~~~~~~~~~~
Note that, when `operator[](const char*)` cannot find the member, it will fail a n assertion. Note that, when `operator[](const char*)` cannot find the member, it will fail a n assertion.
If we are unsure whether a member exists, we need to call `HasMember()` before c alling `operator[](const char*)`. However, this incurs two lookup. A better way is to call `FindMember()`, which can check the existence of member and obtain it s value at once: If we are unsure whether a member exists, we need to call `HasMember()` before c alling `operator[](const char*)`. However, this incurs two lookup. A better way is to call `FindMember()`, which can check the existence of member and obtain it s value at once:
~~~~~~~~~~cpp ~~~~~~~~~~cpp
Value::ConstMemberIterator itr = document.FindMember("hello"); Value::ConstMemberIterator itr = document.FindMember("hello");
if (itr != document.MemberEnd()) if (itr != document.MemberEnd())
printf("%s %s\n", itr->value.GetString()); printf("%s\n", itr->value.GetString());
~~~~~~~~~~
### Range-based For Loop (New in v1.1.0)
When C++11 is enabled, you can use range-based for loop to access all members in
an object.
~~~~~~~~~~cpp
for (auto& m : document.GetObject())
printf("Type of member %s is %s\n",
m.name.GetString(), kTypeNames[m.value.GetType()]);
~~~~~~~~~~ ~~~~~~~~~~
## Querying Number {#QueryNumber} ## Querying Number {#QueryNumber}
JSON provide a single numerical type called Number. Number can be integer or rea l numbers. RFC 4627 says the range of Number is specified by parser. JSON provide a single numerical type called Number. Number can be integer or rea l numbers. RFC 4627 says the range of Number is specified by parser.
As C++ provides several integer and floating point number types, the DOM tries t o handle these with widest possible range and good performance. As C++ provides several integer and floating point number types, the DOM tries t o handle these with widest possible range and good performance.
When a Number is parsed, it is stored in the DOM as either one of the following type: When a Number is parsed, it is stored in the DOM as either one of the following type:
skipping to change at line 295 skipping to change at line 314
![Assignment with move semantics.](diagram/move1.png) ![Assignment with move semantics.](diagram/move1.png)
Why? What is the advantage of this semantics? Why? What is the advantage of this semantics?
The simple answer is performance. For fixed size JSON types (Number, True, False , Null), copying them is fast and easy. However, For variable size JSON types (S tring, Array, Object), copying them will incur a lot of overheads. And these ove rheads are often unnoticed. Especially when we need to create temporary object, copy it to another variable, and then destruct it. The simple answer is performance. For fixed size JSON types (Number, True, False , Null), copying them is fast and easy. However, For variable size JSON types (S tring, Array, Object), copying them will incur a lot of overheads. And these ove rheads are often unnoticed. Especially when we need to create temporary object, copy it to another variable, and then destruct it.
For example, if normal *copy* semantics was used: For example, if normal *copy* semantics was used:
~~~~~~~~~~cpp ~~~~~~~~~~cpp
Document d;
Value o(kObjectType); Value o(kObjectType);
{ {
Value contacts(kArrayType); Value contacts(kArrayType);
// adding elements to contacts array. // adding elements to contacts array.
// ... // ...
o.AddMember("contacts", contacts); // deep clone contacts (may be with lots of allocations) o.AddMember("contacts", contacts, d.GetAllocator()); // deep clone contacts (may be with lots of allocations)
// destruct contacts. // destruct contacts.
} }
~~~~~~~~~~ ~~~~~~~~~~
![Copy semantics makes a lots of copy operations.](diagram/move2.png) ![Copy semantics makes a lots of copy operations.](diagram/move2.png)
The object `o` needs to allocate a buffer of same size as contacts, makes a deep clone of it, and then finally contacts is destructed. This will incur a lot of unnecessary allocations/deallocations and memory copying. The object `o` needs to allocate a buffer of same size as contacts, makes a deep clone of it, and then finally contacts is destructed. This will incur a lot of unnecessary allocations/deallocations and memory copying.
There are solutions to prevent actual copying these data, such as reference coun ting and garbage collection(GC). There are solutions to prevent actual copying these data, such as reference coun ting and garbage collection(GC).
To make RapidJSON simple and fast, we chose to use *move* semantics for assignme nt. It is similar to `std::auto_ptr` which transfer ownership during assignment. Move is much faster and simpler, it just destructs the original value, `memcpy( )` the source to destination, and finally sets the source as Null type. To make RapidJSON simple and fast, we chose to use *move* semantics for assignme nt. It is similar to `std::auto_ptr` which transfer ownership during assignment. Move is much faster and simpler, it just destructs the original value, `memcpy( )` the source to destination, and finally sets the source as Null type.
So, with move semantics, the above example becomes: So, with move semantics, the above example becomes:
~~~~~~~~~~cpp ~~~~~~~~~~cpp
Document d;
Value o(kObjectType); Value o(kObjectType);
{ {
Value contacts(kArrayType); Value contacts(kArrayType);
// adding elements to contacts array. // adding elements to contacts array.
o.AddMember("contacts", contacts); // just memcpy() of contacts itself to t he value of new member (16 bytes) o.AddMember("contacts", contacts, d.GetAllocator()); // just memcpy() of co ntacts itself to the value of new member (16 bytes)
// contacts became Null here. Its destruction is trivial. // contacts became Null here. Its destruction is trivial.
} }
~~~~~~~~~~ ~~~~~~~~~~
![Move semantics makes no copying.](diagram/move3.png) ![Move semantics makes no copying.](diagram/move3.png)
This is called move assignment operator in C++11. As RapidJSON supports C++03, i t adopts move semantics using assignment operator, and all other modifying funct ion like `AddMember()`, `PushBack()`. This is called move assignment operator in C++11. As RapidJSON supports C++03, i t adopts move semantics using assignment operator, and all other modifying funct ion like `AddMember()`, `PushBack()`.
### Move semantics and temporary values {#TemporaryValues} ### Move semantics and temporary values {#TemporaryValues}
 End of changes. 6 change blocks. 
3 lines changed or deleted 26 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)