Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMilo Yip <miloyip@gmail.com>2014-07-09 21:46:49 +0400
committerMilo Yip <miloyip@gmail.com>2014-07-09 21:46:49 +0400
commit2579eca7e245fb49baa9ade4cf1dab8ada451a95 (patch)
tree62452c7d357cbeb9a0977001e10522ad40159371 /doc
parent84126175e40193800834a142cfc4b152deef3779 (diff)
parent63de910d1608cc29fde32b73be98f53a20a0019a (diff)
Merge remote-tracking branch 'origin/master' into document
Diffstat (limited to 'doc')
-rw-r--r--doc/tutorial.md66
1 files changed, 59 insertions, 7 deletions
diff --git a/doc/tutorial.md b/doc/tutorial.md
index f35c4d37..ee5f873e 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -313,6 +313,17 @@ Value o(kObjectType);
This is called move assignment operator in C++11. As RapidJSON supports C++03, it adopts move semantics using assignment operator, and all other modifying function like `AddMember()`, `PushBack()`.
+### Move semantics and temporary values {#TemporaryValues}
+
+Sometimes, it is convenient to construct a Value in place, before passing it to one of the "moving" functions, like `PushBack()` or `AddMember()`. As temporary objects can't be converted to proper Value references, the convenience function `Move()` is available:
+
+~~~~~~~~~~cpp
+Value a(kArrayType);
+// a.PushBack(Value(42)); // will not compile
+a.PushBack(Value().SetInt(42)); // fluent API
+a.PushBack(Value(42).Move()); // same as above
+~~~~~~~~~~
+
## Create String {#CreateString}
RapidJSON provide two strategies for storing string.
@@ -339,15 +350,28 @@ In this example, we get the allocator from a `Document` instance. This is a comm
Besides, the above `SetString()` requires length. This can handle null characters within a string. There is another `SetString()` overloaded function without the length parameter. And it assumes the input is null-terminated and calls a `strlen()`-like function to obtain the length.
-Finally, for literal string or string with safe life-cycle can use const-string version of `SetString()`, which lacks allocator parameter:
+Finally, for literal string or string with safe life-cycle can use const-string version of `SetString()`, which lacks allocator parameter. For string literals (or constant character arrays), simply passing the literal as parameter is safe and efficient:
~~~~~~~~~~cpp
Value s;
-s.SetString("rapidjson", 9); // faster, can contain null character
-s.SetString("rapidjson"); // slower, assumes null-terminated
+s.SetString("rapidjson"); // can contain null character, length derived at compile time
s = "rapidjson"; // shortcut, same as above
~~~~~~~~~~
+For plain string pointers, the RapidJSON requires to mark a string as safe before using it without copying. This can be achieved by using the `StringRef` function:
+
+~~~~~~~~~cpp
+const char * cstr = getenv("USER");
+size_t cstr_len = ...; // in case length is available
+Value s;
+// s.SetString(cstr); // will not compile
+s.SetString(StringRef(cstr)); // ok, assume safe lifetime, null-terminated
+s = StringRef(cstr); // shortcut, same as above
+s.SetString(StringRef(cstr,cstr_len)); // faster, can contain null character
+s = StringRef(cstr,cstr_len); // shortcut, same as above
+
+~~~~~~~~~
+
## Modify Array {#ModifyArray}
Value with array type provides similar APIs as `std::vector`.
@@ -357,7 +381,7 @@ Value with array type provides similar APIs as `std::vector`.
* `template <typename T> GenericValue& PushBack(T, Allocator&)`
* `Value& PopBack()`
-Note that, `Reserve(...)` and `PushBack(...)` may allocate memory, therefore requires an allocator.
+Note that, `Reserve(...)` and `PushBack(...)` may allocate memory for the array elements, therefore require an allocator.
Here is an example of `PushBack()`:
@@ -372,14 +396,26 @@ for (int i = 5; i <= 10; i++)
a.PushBack("Lua", allocator).PushBack("Mio", allocator);
~~~~~~~~~~
-Differs from STL, `PushBack()`/`PopBack()` returns the array reference itself. This is called fluent interface.
+Differs from STL, `PushBack()`/`PopBack()` returns the array reference itself. This is called _fluent interface_.
+
+If you want to add a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)) to the array, you need to create a string Value by using the copy-string API. To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place:
+
+~~~~~~~~~~cpp
+// in-place Value parameter
+contact.PushBack(Value("copy", document.GetAllocator()).Move(), // copy string
+ document.GetAllocator());
+
+// explicit parameters
+Value val("key", document.GetAllocator()); // copy string
+contact.PushBack(val, document.GetAllocator());
+~~~~~~~~~~
## Modify Object {#ModifyObject}
Object is a collection of key-value pairs. Each key must be a string value. The way to manipulating object is to add/remove members:
* `Value& AddMember(Value&, Value&, Allocator& allocator)`
-* `Value& AddMember(const Ch*, Value&, Allocator&)`
-* `template <typename T> Value& AddMember(const Ch*, T value, Allocator&)`
+* `Value& AddMember(StringRefType, Value&, Allocator&)`
+* `template <typename T> Value& AddMember(StringRefType, T value, Allocator&)`
* `bool RemoveMember(const Ch*)`
Here is an example.
@@ -390,6 +426,22 @@ contact.AddMember("name", "Milo", document.GetAllocator());
contact.AddMember("married", true, document.GetAllocator());
~~~~~~~~~~
+The `StringRefType` used as name parameter assumes the same interface as the `SetString` function for string values. These overloads are used to avoid the need for copying the `name` string, as constant key names are very common in JSON objects.
+
+If you need to create a name from a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)), you need to create a string Value by using the copy-string API. To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place:
+
+~~~~~~~~~~cpp
+// in-place Value parameter
+contact.AddMember(Value("copy", document.GetAllocator()).Move(), // copy string
+ Value().Move(), // null value
+ document.GetAllocator());
+
+// explicit parameters
+Value key("key", document.GetAllocator()); // copy name string
+Value val(42); // some value
+contact.AddMember(key, val, document.GetAllocator());
+~~~~~~~~~~
+
## Deep Copy Value {#DeepCopyValue}
If we really need to copy a DOM tree, we can use two APIs for deep copy: constructor with allocator, and `CopyFrom()`.