Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
9b6af555
Commit
9b6af555
authored
Oct 17, 2016
by
Milo Yip
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into issue728_threadsafe
parents
769185d6
23632279
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
132 additions
and
22 deletions
+132
-22
dom.zh-cn.md
doc/dom.zh-cn.md
+1
-1
faq.zh-cn.md
doc/faq.zh-cn.md
+2
-2
schema.md
doc/schema.md
+3
-3
schema.zh-cn.md
doc/schema.zh-cn.md
+3
-3
tutorial.zh-cn.md
doc/tutorial.zh-cn.md
+10
-10
document.h
include/rapidjson/document.h
+4
-1
prettywriter.h
include/rapidjson/prettywriter.h
+14
-0
reader.h
include/rapidjson/reader.h
+1
-1
stringbuffer.h
include/rapidjson/stringbuffer.h
+4
-0
writer.h
include/rapidjson/writer.h
+8
-0
prettywritertest.cpp
test/unittest/prettywritertest.cpp
+32
-0
stringbuffertest.cpp
test/unittest/stringbuffertest.cpp
+23
-1
writertest.cpp
test/unittest/writertest.cpp
+27
-0
No files found.
doc/dom.zh-cn.md
View file @
9b6af555
...
...
@@ -128,7 +128,7 @@ GenericDocument& GenericDocument::Parse(const Ch* str);
## 解析错误 {#ParseError}
当解析过程顺利完成,
`Document`
便会含有解析结果。当过程出现错误,原来的 DOM 会
* 维持不便
*
。可使用
`bool HasParseError()`
、
`ParseErrorCode GetParseError()`
及
`size_t GetParseOffset()`
获取解析的错误状态。
当解析过程顺利完成,
`Document`
便会含有解析结果。当过程出现错误,原来的 DOM 会
*维持不变
*
。可使用
`bool HasParseError()`
、
`ParseErrorCode GetParseError()`
及
`size_t GetParseOffset()`
获取解析的错误状态。
解析错误代号 | 描述
--------------------------------------------|---------------------------------------------------
...
...
doc/faq.zh-cn.md
View file @
9b6af555
...
...
@@ -163,9 +163,9 @@
## Document/Value (DOM)
1.
什么是转移语
意
?为什么?
1.
什么是转移语
义
?为什么?
`Value`
不用复制语
意,而使用了转移语意
。这是指,当把来源值赋值于目标值时,来源值的所有权会转移至目标值。
`Value`
不用复制语
义,而使用了转移语义
。这是指,当把来源值赋值于目标值时,来源值的所有权会转移至目标值。
由于转移快于复制,此设计决定强迫使用者注意到复制的消耗。
...
...
doc/schema.md
View file @
9b6af555
...
...
@@ -157,7 +157,7 @@ As `SchemaDocument` does not know how to resolve such URI, it needs a user-provi
~~~
class MyRemoteSchemaDocumentProvider : public IRemoteSchemaDocumentProvider {
public:
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeTyp length) {
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeTyp
e
length) {
// Resolve the uri and returns a pointer to that schema.
}
};
...
...
@@ -185,7 +185,7 @@ RapidJSON implemented a simple NFA regular expression engine, which is used by d
|Syntax|Description|
|------|-----------|
|
`ab`
| Concatenation |
|
`a|b`
| Alternation |
|
<code>
a
|
b
</code>
| Alternation |
|
`a?`
| Zero or one |
|
`a*`
| Zero or more |
|
`a+`
| One or more |
...
...
@@ -202,7 +202,7 @@ RapidJSON implemented a simple NFA regular expression engine, which is used by d
|
`[^abc]`
| Negated character classes |
|
`[^a-c]`
| Negated character class range |
|
`[\b]`
| Backspace (U+0008) |
|
`\|`
,
`\\`
, ... | Escape characters |
|
<code>
\\
|
</code>
,
`\\`
, ... | Escape characters |
|
`\f`
| Form feed (U+000C) |
|
`\n`
| Line feed (U+000A) |
|
`\r`
| Carriage return (U+000D) |
...
...
doc/schema.zh-cn.md
View file @
9b6af555
...
...
@@ -157,7 +157,7 @@ JSON Schema 支持 [`$ref` 关键字](http://spacetelescope.github.io/understand
~~~
class MyRemoteSchemaDocumentProvider : public IRemoteSchemaDocumentProvider {
public:
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeTyp length) {
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeTyp
e
length) {
// Resolve the uri and returns a pointer to that schema.
}
};
...
...
@@ -185,7 +185,7 @@ RapidJSON 实现了一个简单的 NFA 正则表达式引擎,并预设使用
|语法|描述|
|------|-----------|
|
`ab`
| 串联 |
|
`a|b`
| 交替 |
|
<code>
a
|
b
</code>
| 交替 |
|
`a?`
| 零或一次 |
|
`a*`
| 零或多次 |
|
`a+`
| 一或多次 |
...
...
@@ -202,7 +202,7 @@ RapidJSON 实现了一个简单的 NFA 正则表达式引擎,并预设使用
|
`[^abc]`
| 字符组取反 |
|
`[^a-c]`
| 字符组范围取反 |
|
`[\b]`
| 退格符 (U+0008) |
|
`\|`
,
`\\`
, ... | 转义字符 |
|
<code>
\\
|
</code>
,
`\\`
, ... | 转义字符 |
|
`\f`
| 馈页 (U+000C) |
|
`\n`
| 馈行 (U+000A) |
|
`\r`
| 回车 (U+000D) |
...
...
doc/tutorial.zh-cn.md
View file @
9b6af555
...
...
@@ -292,7 +292,7 @@ Value o(kObjectType);
Value a(kArrayType);
~~~
~~~~~~~
## 转移语
意
(Move Semantics) {#MoveSemantics}
## 转移语
义
(Move Semantics) {#MoveSemantics}
在设计 RapidJSON 时有一个非常特别的决定,就是 Value 赋值并不是把来源 Value 复制至目的 Value,而是把把来源 Value 转移(move)至目的 Value。例如:
...
...
@@ -302,13 +302,13 @@ Value b(456);
b = a; // a 变成 Null,b 变成数字 123。
~~~
~~~~~~~
![
使用移动语
意
赋值。
](
diagram/move1.png
)
![
使用移动语
义
赋值。
](
diagram/move1.png
)
为什么?此语
意
有何优点?
为什么?此语
义
有何优点?
最简单的答案就是性能。对于固定大小的 JSON 类型(Number、True、False、Null),复制它们是简单快捷。然而,对于可变大小的 JSON 类型(String、Array、Object),复制它们会产生大量开销,而且这些开销常常不被察觉。尤其是当我们需要创建临时 Object,把它复制至另一变量,然后再析构它。
例如,若使用正常
* 复制 *
语
意
:
例如,若使用正常
* 复制 *
语
义
:
~~~
~~~~~~~cpp
Value o(kObjectType);
...
...
@@ -321,15 +321,15 @@ Value o(kObjectType);
}
~~~
~~~~~~~
![
复制语
意
产生大量的复制操作。
](
diagram/move2.png
)
![
复制语
义
产生大量的复制操作。
](
diagram/move2.png
)
那个
`o`
Object 需要分配一个和 contacts 相同大小的缓冲区,对 conacts 做深度复制,并最终要析构 contacts。这样会产生大量无必要的内存分配/释放,以及内存复制。
有一些方案可避免实质地复制这些数据,例如引用计数(reference counting)、垃圾回收(garbage collection, GC)。
为了使 RapidJSON 简单及快速,我们选择了对赋值采用
* 转移 *
语
意
。这方法与
`std::auto_ptr`
相似,都是在赋值时转移拥有权。转移快得多简单得多,只需要析构原来的 Value,把来源
`memcpy()`
至目标,最后把来源设置为 Null 类型。
为了使 RapidJSON 简单及快速,我们选择了对赋值采用
* 转移 *
语
义
。这方法与
`std::auto_ptr`
相似,都是在赋值时转移拥有权。转移快得多简单得多,只需要析构原来的 Value,把来源
`memcpy()`
至目标,最后把来源设置为 Null 类型。
因此,使用转移语
意
后,上面的例子变成:
因此,使用转移语
义
后,上面的例子变成:
~~~
~~~~~~~cpp
Value o(kObjectType);
...
...
@@ -341,11 +341,11 @@ Value o(kObjectType);
}
~~~
~~~~~~~
![
转移语
意
不需复制。
](
diagram/move3.png
)
![
转移语
义
不需复制。
](
diagram/move3.png
)
在 C++11 中这称为转移赋值操作(move assignment operator)。由于 RapidJSON 支持 C++03,它在赋值操作采用转移语
意,其它修改形函数如
`AddMember()`
,
`PushBack()`
也采用转移语意
。
在 C++11 中这称为转移赋值操作(move assignment operator)。由于 RapidJSON 支持 C++03,它在赋值操作采用转移语
义,其它修改形函数如
`AddMember()`
,
`PushBack()`
也采用转移语义
。
### 转移语
意
及临时值 {#TemporaryValues}
### 转移语
义
及临时值 {#TemporaryValues}
有时候,我们想直接构造一个 Value 并传递给一个“转移”函数(如
`PushBack()`
、
`AddMember()`
)。由于临时对象是不能转换为正常的 Value 引用,我们加入了一个方便的
`Move()`
函数:
...
...
include/rapidjson/document.h
View file @
9b6af555
...
...
@@ -672,6 +672,9 @@ public:
//! Constructor for double value.
explicit
GenericValue
(
double
d
)
RAPIDJSON_NOEXCEPT
:
data_
()
{
data_
.
n
.
d
=
d
;
data_
.
f
.
flags
=
kNumberDoubleFlag
;
}
//! Constructor for float value.
explicit
GenericValue
(
float
f
)
RAPIDJSON_NOEXCEPT
:
data_
()
{
data_
.
n
.
d
=
static_cast
<
double
>
(
f
);
data_
.
f
.
flags
=
kNumberDoubleFlag
;
}
//! Constructor for constant string (i.e. do not make a copy of string)
GenericValue
(
const
Ch
*
s
,
SizeType
length
)
RAPIDJSON_NOEXCEPT
:
data_
()
{
SetStringRaw
(
StringRef
(
s
,
length
));
}
...
...
@@ -1671,7 +1674,7 @@ public:
GenericValue
&
SetInt64
(
int64_t
i64
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
i64
);
return
*
this
;
}
GenericValue
&
SetUint64
(
uint64_t
u64
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
u64
);
return
*
this
;
}
GenericValue
&
SetDouble
(
double
d
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
d
);
return
*
this
;
}
GenericValue
&
SetFloat
(
float
f
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
f
);
return
*
this
;
}
GenericValue
&
SetFloat
(
float
f
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
static_cast
<
double
>
(
f
));
return
*
this
;
}
//@}
...
...
include/rapidjson/prettywriter.h
View file @
9b6af555
...
...
@@ -22,6 +22,11 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
effc
++
)
#endif
#if defined(__clang__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
c
++
98
-
compat
)
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! Combination of PrettyWriter format flags.
...
...
@@ -57,6 +62,11 @@ public:
explicit
PrettyWriter
(
StackAllocator
*
allocator
=
0
,
size_t
levelDepth
=
Base
::
kDefaultLevelDepth
)
:
Base
(
allocator
,
levelDepth
),
indentChar_
(
' '
),
indentCharCount_
(
4
)
{}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
PrettyWriter
(
PrettyWriter
&&
rhs
)
:
Base
(
std
::
forward
<
PrettyWriter
>
(
rhs
)),
indentChar_
(
rhs
.
indentChar_
),
indentCharCount_
(
rhs
.
indentCharCount_
),
formatOptions_
(
rhs
.
formatOptions_
)
{}
#endif
//! Set custom indentation.
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
\param indentCharCount Number of indent characters for each indentation level.
...
...
@@ -254,6 +264,10 @@ private:
RAPIDJSON_NAMESPACE_END
#if defined(__clang__)
RAPIDJSON_DIAG_POP
#endif
#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
...
...
include/rapidjson/reader.h
View file @
9b6af555
...
...
@@ -575,7 +575,7 @@ private:
}
}
else
if
(
RAPIDJSON_LIKELY
(
Consume
(
is
,
'/'
)))
while
(
is
.
Peek
()
!=
'\0'
&&
is
.
Take
()
!=
'\n'
)
;
while
(
is
.
Peek
()
!=
'\0'
&&
is
.
Take
()
!=
'\n'
)
{}
else
RAPIDJSON_PARSE_ERROR
(
kParseErrorUnspecificSyntaxError
,
is
.
Tell
());
...
...
include/rapidjson/stringbuffer.h
View file @
9b6af555
...
...
@@ -78,8 +78,12 @@ public:
return
stack_
.
template
Bottom
<
Ch
>
();
}
//! Get the size of string in bytes in the string buffer.
size_t
GetSize
()
const
{
return
stack_
.
GetSize
();
}
//! Get the length of string in Ch in the string buffer.
size_t
GetLength
()
const
{
return
stack_
.
GetSize
()
/
sizeof
(
Ch
);
}
static
const
size_t
kDefaultCapacity
=
256
;
mutable
internal
::
Stack
<
Allocator
>
stack_
;
...
...
include/rapidjson/writer.h
View file @
9b6af555
...
...
@@ -42,6 +42,7 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
padded
)
RAPIDJSON_DIAG_OFF
(
unreachable
-
code
)
RAPIDJSON_DIAG_OFF
(
c
++
98
-
compat
)
#endif
RAPIDJSON_NAMESPACE_BEGIN
...
...
@@ -103,6 +104,13 @@ public:
Writer
(
StackAllocator
*
allocator
=
0
,
size_t
levelDepth
=
kDefaultLevelDepth
)
:
os_
(
0
),
level_stack_
(
allocator
,
levelDepth
*
sizeof
(
Level
)),
maxDecimalPlaces_
(
kDefaultMaxDecimalPlaces
),
hasRoot_
(
false
)
{}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
Writer
(
Writer
&&
rhs
)
:
os_
(
rhs
.
os_
),
level_stack_
(
std
::
move
(
rhs
.
level_stack_
)),
maxDecimalPlaces_
(
rhs
.
maxDecimalPlaces_
),
hasRoot_
(
rhs
.
hasRoot_
)
{
rhs
.
os_
=
0
;
}
#endif
//! Reset the writer with a new stream.
/*!
This function reset the writer with a new stream and default settings,
...
...
test/unittest/prettywritertest.cpp
View file @
9b6af555
...
...
@@ -18,6 +18,11 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/filewritestream.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
c
++
98
-
compat
)
#endif
using
namespace
rapidjson
;
static
const
char
kJson
[]
=
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3,-1],
\"
u64
\"
:1234567890123456789,
\"
i64
\"
:-1234567890123456789}"
;
...
...
@@ -201,3 +206,30 @@ TEST(PrettyWriter, RawValue) {
"}"
,
buffer
.
GetString
());
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
static
PrettyWriter
<
StringBuffer
>
WriterGen
(
StringBuffer
&
target
)
{
PrettyWriter
<
StringBuffer
>
writer
(
target
);
writer
.
StartObject
();
writer
.
Key
(
"a"
);
writer
.
Int
(
1
);
return
writer
;
}
TEST
(
PrettyWriter
,
MoveCtor
)
{
StringBuffer
buffer
;
PrettyWriter
<
StringBuffer
>
writer
(
WriterGen
(
buffer
));
writer
.
EndObject
();
EXPECT_TRUE
(
writer
.
IsComplete
());
EXPECT_STREQ
(
"{
\n
"
"
\"
a
\"
: 1
\n
"
"}"
,
buffer
.
GetString
());
}
#endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
test/unittest/stringbuffertest.cpp
View file @
9b6af555
...
...
@@ -26,6 +26,7 @@ using namespace rapidjson;
TEST
(
StringBuffer
,
InitialSize
)
{
StringBuffer
buffer
;
EXPECT_EQ
(
0u
,
buffer
.
GetSize
());
EXPECT_EQ
(
0u
,
buffer
.
GetLength
());
EXPECT_STREQ
(
""
,
buffer
.
GetString
());
}
...
...
@@ -34,14 +35,17 @@ TEST(StringBuffer, Put) {
buffer
.
Put
(
'A'
);
EXPECT_EQ
(
1u
,
buffer
.
GetSize
());
EXPECT_EQ
(
1u
,
buffer
.
GetLength
());
EXPECT_STREQ
(
"A"
,
buffer
.
GetString
());
}
TEST
(
StringBuffer
,
PutN_Issue672
)
{
GenericStringBuffer
<
UTF8
<>
,
MemoryPoolAllocator
<>
>
buffer
;
EXPECT_EQ
(
0
,
buffer
.
GetSize
());
EXPECT_EQ
(
0
,
buffer
.
GetLength
());
rapidjson
::
PutN
(
buffer
,
' '
,
1
);
EXPECT_EQ
(
1
,
buffer
.
GetSize
());
EXPECT_EQ
(
1
,
buffer
.
GetLength
());
}
TEST
(
StringBuffer
,
Clear
)
{
...
...
@@ -52,6 +56,7 @@ TEST(StringBuffer, Clear) {
buffer
.
Clear
();
EXPECT_EQ
(
0u
,
buffer
.
GetSize
());
EXPECT_EQ
(
0u
,
buffer
.
GetLength
());
EXPECT_STREQ
(
""
,
buffer
.
GetString
());
}
...
...
@@ -60,6 +65,7 @@ TEST(StringBuffer, Push) {
buffer
.
Push
(
5
);
EXPECT_EQ
(
5u
,
buffer
.
GetSize
());
EXPECT_EQ
(
5u
,
buffer
.
GetLength
());
// Causes sudden expansion to make the stack's capacity equal to size
buffer
.
Push
(
65536u
);
...
...
@@ -76,9 +82,19 @@ TEST(StringBuffer, Pop) {
buffer
.
Pop
(
3
);
EXPECT_EQ
(
2u
,
buffer
.
GetSize
());
EXPECT_EQ
(
2u
,
buffer
.
GetLength
());
EXPECT_STREQ
(
"AB"
,
buffer
.
GetString
());
}
TEST
(
StringBuffer
,
GetLength_Issue744
)
{
GenericStringBuffer
<
UTF16
<
wchar_t
>
>
buffer
;
buffer
.
Put
(
'A'
);
buffer
.
Put
(
'B'
);
buffer
.
Put
(
'C'
);
EXPECT_EQ
(
3u
*
sizeof
(
wchar_t
),
buffer
.
GetSize
());
EXPECT_EQ
(
3u
,
buffer
.
GetLength
());
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if 0 // Many old compiler does not support these. Turn it off temporaily.
...
...
@@ -130,18 +146,23 @@ TEST(StringBuffer, MoveConstructor) {
x
.
Put
(
'D'
);
EXPECT_EQ
(
4u
,
x
.
GetSize
());
EXPECT_EQ
(
4u
,
x
.
GetLength
());
EXPECT_STREQ
(
"ABCD"
,
x
.
GetString
());
// StringBuffer y(x); // does not compile (!is_copy_constructible)
StringBuffer
y
(
std
::
move
(
x
));
EXPECT_EQ
(
0u
,
x
.
GetSize
());
EXPECT_EQ
(
0u
,
x
.
GetLength
());
EXPECT_EQ
(
4u
,
y
.
GetSize
());
EXPECT_EQ
(
4u
,
y
.
GetLength
());
EXPECT_STREQ
(
"ABCD"
,
y
.
GetString
());
// StringBuffer z = y; // does not compile (!is_copy_assignable)
StringBuffer
z
=
std
::
move
(
y
);
EXPECT_EQ
(
0u
,
y
.
GetSize
());
EXPECT_EQ
(
0u
,
y
.
GetLength
());
EXPECT_EQ
(
4u
,
z
.
GetSize
());
EXPECT_EQ
(
4u
,
z
.
GetLength
());
EXPECT_STREQ
(
"ABCD"
,
z
.
GetString
());
}
...
...
@@ -153,13 +174,14 @@ TEST(StringBuffer, MoveAssignment) {
x
.
Put
(
'D'
);
EXPECT_EQ
(
4u
,
x
.
GetSize
());
EXPECT_EQ
(
4u
,
x
.
GetLength
());
EXPECT_STREQ
(
"ABCD"
,
x
.
GetString
());
StringBuffer
y
;
// y = x; // does not compile (!is_copy_assignable)
y
=
std
::
move
(
x
);
EXPECT_EQ
(
0u
,
x
.
GetSize
());
EXPECT_EQ
(
4u
,
y
.
Get
Size
());
EXPECT_EQ
(
4u
,
y
.
Get
Length
());
EXPECT_STREQ
(
"ABCD"
,
y
.
GetString
());
}
...
...
test/unittest/writertest.cpp
View file @
9b6af555
...
...
@@ -20,6 +20,11 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/memorybuffer.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
c
++
98
-
compat
)
#endif
using
namespace
rapidjson
;
TEST
(
Writer
,
Compact
)
{
...
...
@@ -495,3 +500,25 @@ TEST(Writer, RawValue) {
EXPECT_TRUE
(
writer
.
IsComplete
());
EXPECT_STREQ
(
"{
\"
a
\"
:1,
\"
raw
\"
:[
\"
Hello
\\
nWorld
\"
, 123.456]}"
,
buffer
.
GetString
());
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
static
Writer
<
StringBuffer
>
WriterGen
(
StringBuffer
&
target
)
{
Writer
<
StringBuffer
>
writer
(
target
);
writer
.
StartObject
();
writer
.
Key
(
"a"
);
writer
.
Int
(
1
);
return
writer
;
}
TEST
(
Writer
,
MoveCtor
)
{
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
WriterGen
(
buffer
));
writer
.
EndObject
();
EXPECT_TRUE
(
writer
.
IsComplete
());
EXPECT_STREQ
(
"{
\"
a
\"
:1}"
,
buffer
.
GetString
());
}
#endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment