Merge branch 'master' of https://github.com/Tencent/rapidjson
This commit is contained in:
commit
e54aca7006
@ -20,7 +20,7 @@ env:
|
|||||||
before_install:
|
before_install:
|
||||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -y cmake valgrind g++-multilib libc6-dbg:i386
|
- sudo apt-get install -y cmake valgrind g++-multilib libc6-dbg:i386 --allow-unauthenticated
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
@ -79,7 +79,7 @@ The following tables show the data layout of each type. The 32-bit/64-bit column
|
|||||||
| `unsigned u` | 32-bit unsigned integer |4 |4 |
|
| `unsigned u` | 32-bit unsigned integer |4 |4 |
|
||||||
| (zero padding) | 0 |4 |4 |
|
| (zero padding) | 0 |4 |4 |
|
||||||
| (unused) | |4 |8 |
|
| (unused) | |4 |8 |
|
||||||
| `unsigned flags_` | `kNumberType kNumberFlag kUIntFlag kUInt64Flag ...` |4 |4 |
|
| `unsigned flags_` | `kNumberType kNumberFlag kUintFlag kUint64Flag ...` |4 |4 |
|
||||||
|
|
||||||
| Number (Int64) | |32-bit|64-bit|
|
| Number (Int64) | |32-bit|64-bit|
|
||||||
|---------------------|-------------------------------------|:----:|:----:|
|
|---------------------|-------------------------------------|:----:|:----:|
|
||||||
|
@ -79,7 +79,7 @@ SAX 和 DOM API 都依赖于3个额外的概念:`Allocator`、`Encoding` 和 `
|
|||||||
| `unsigned u` | 32位无符号整数 |4 |4 |
|
| `unsigned u` | 32位无符号整数 |4 |4 |
|
||||||
| (零填充) | 0 |4 |4 |
|
| (零填充) | 0 |4 |4 |
|
||||||
| (未使用) | |4 |8 |
|
| (未使用) | |4 |8 |
|
||||||
| `unsigned flags_` | `kNumberType kNumberFlag kUIntFlag kUInt64Flag ...` |4 |4 |
|
| `unsigned flags_` | `kNumberType kNumberFlag kUintFlag kUint64Flag ...` |4 |4 |
|
||||||
|
|
||||||
| Number (Int64) | | 32位 | 64位 |
|
| Number (Int64) | | 32位 | 64位 |
|
||||||
|---------------------|-------------------------------------|:----:|:----:|
|
|---------------------|-------------------------------------|:----:|:----:|
|
||||||
@ -248,7 +248,7 @@ void SkipWhitespace(InputStream& is) {
|
|||||||
|
|
||||||
## 整数到字符串的转换 {#itoa}
|
## 整数到字符串的转换 {#itoa}
|
||||||
|
|
||||||
整数到字符串转换的朴素算法需要对每一个十进制位进行一次处罚。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
|
整数到字符串转换的朴素算法需要对每一个十进制位进行一次除法。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
|
||||||
|
|
||||||
虽然 SSE2 版本是最快的,但它和第二快的 `branchlut` 差距不大。而且 `branchlut` 是纯C++实现,所以我们在 RapidJSON 中使用了 `branchlut`。
|
虽然 SSE2 版本是最快的,但它和第二快的 `branchlut` 差距不大。而且 `branchlut` 是纯C++实现,所以我们在 RapidJSON 中使用了 `branchlut`。
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ Bool(false)
|
|||||||
Key("n", 1, true)
|
Key("n", 1, true)
|
||||||
Null()
|
Null()
|
||||||
Key("i")
|
Key("i")
|
||||||
UInt(123)
|
Uint(123)
|
||||||
Key("pi")
|
Key("pi")
|
||||||
Double(3.1416)
|
Double(3.1416)
|
||||||
Key("a")
|
Key("a")
|
||||||
|
@ -37,7 +37,7 @@ Bool(false)
|
|||||||
Key("n", 1, true)
|
Key("n", 1, true)
|
||||||
Null()
|
Null()
|
||||||
Key("i")
|
Key("i")
|
||||||
UInt(123)
|
Uint(123)
|
||||||
Key("pi")
|
Key("pi")
|
||||||
Double(3.1416)
|
Double(3.1416)
|
||||||
Key("a")
|
Key("a")
|
||||||
@ -91,7 +91,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类形,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
|
注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类型,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
|
||||||
|
|
||||||
## 处理器 {#Handler}
|
## 处理器 {#Handler}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ JSON number type represents all numeric values. However, C++ needs more specific
|
|||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
assert(document["i"].IsNumber());
|
assert(document["i"].IsNumber());
|
||||||
|
|
||||||
// In this case, IsUint()/IsInt64()/IsUInt64() also return true.
|
// In this case, IsUint()/IsInt64()/IsUint64() also return true.
|
||||||
assert(document["i"].IsInt());
|
assert(document["i"].IsInt());
|
||||||
printf("i = %d\n", document["i"].GetInt());
|
printf("i = %d\n", document["i"].GetInt());
|
||||||
// Alternative (int)document["i"]
|
// Alternative (int)document["i"]
|
||||||
|
@ -82,7 +82,7 @@ JSON Number 类型表示所有数值。然而,C++ 需要使用更专门的类
|
|||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
assert(document["i"].IsNumber());
|
assert(document["i"].IsNumber());
|
||||||
|
|
||||||
// 在此情况下,IsUint()/IsInt64()/IsUInt64() 也会返回 true
|
// 在此情况下,IsUint()/IsInt64()/IsUint64() 也会返回 true
|
||||||
assert(document["i"].IsInt());
|
assert(document["i"].IsInt());
|
||||||
printf("i = %d\n", document["i"].GetInt());
|
printf("i = %d\n", document["i"].GetInt());
|
||||||
// 另一种用法: (int)document["i"]
|
// 另一种用法: (int)document["i"]
|
||||||
@ -447,7 +447,7 @@ contact.PushBack(val, document.GetAllocator());
|
|||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
## 修改 Object {#ModifyObject}
|
## 修改 Object {#ModifyObject}
|
||||||
Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加城员:
|
Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加成员:
|
||||||
|
|
||||||
* `Value& AddMember(Value&, Value&, Allocator& allocator)`
|
* `Value& AddMember(Value&, Value&, Allocator& allocator)`
|
||||||
* `Value& AddMember(StringRefType, Value&, Allocator&)`
|
* `Value& AddMember(StringRefType, Value&, Allocator&)`
|
||||||
|
@ -57,7 +57,7 @@ int main(int, char*[]) {
|
|||||||
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
|
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
|
||||||
|
|
||||||
assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
|
assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
|
||||||
assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
|
assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUint64() also return true.
|
||||||
printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
|
printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
|
||||||
|
|
||||||
assert(document["pi"].IsNumber());
|
assert(document["pi"].IsNumber());
|
||||||
|
@ -63,15 +63,45 @@ class GenericDocument;
|
|||||||
https://code.google.com/p/rapidjson/issues/detail?id=64
|
https://code.google.com/p/rapidjson/issues/detail?id=64
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMember {
|
class GenericMember {
|
||||||
|
public:
|
||||||
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
||||||
GenericValue<Encoding, Allocator> value; //!< value of member.
|
GenericValue<Encoding, Allocator> value; //!< value of member.
|
||||||
|
|
||||||
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
|
//! Move constructor in C++11
|
||||||
|
GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
: name(std::move(rhs.name)),
|
||||||
|
value(std::move(rhs.value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Move assignment in C++11
|
||||||
|
GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
return *this = static_cast<GenericMember&>(rhs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Assignment with move semantics.
|
||||||
|
/*! \param rhs Source of the assignment. Its name and value will become a null value after assignment.
|
||||||
|
*/
|
||||||
|
GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||||
|
name = rhs.name;
|
||||||
|
value = rhs.value;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// swap() for std::sort() and other potential use in STL.
|
// swap() for std::sort() and other potential use in STL.
|
||||||
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
||||||
a.name.Swap(b.name);
|
a.name.Swap(b.name);
|
||||||
a.value.Swap(b.value);
|
a.value.Swap(b.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Copy constructor is not permitted.
|
||||||
|
GenericMember(const GenericMember& rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -102,7 +102,7 @@ class PrettyWriter;
|
|||||||
// document.h
|
// document.h
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMember;
|
class GenericMember;
|
||||||
|
|
||||||
template <bool Const, typename Encoding, typename Allocator>
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
class GenericMemberIterator;
|
class GenericMemberIterator;
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
@ -32,9 +31,6 @@ RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#if __GNUC__ >= 7
|
|
||||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||||
@ -291,6 +287,7 @@ private:
|
|||||||
if (!CharacterEscape(ds, &codepoint))
|
if (!CharacterEscape(ds, &codepoint))
|
||||||
return; // Unsupported escape character
|
return; // Unsupported escape character
|
||||||
// fall through to default
|
// fall through to default
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
default: // Pattern character
|
default: // Pattern character
|
||||||
PushOperand(operandStack, codepoint);
|
PushOperand(operandStack, codepoint);
|
||||||
@ -520,6 +517,7 @@ private:
|
|||||||
else if (!CharacterEscape(ds, &codepoint))
|
else if (!CharacterEscape(ds, &codepoint))
|
||||||
return false;
|
return false;
|
||||||
// fall through to default
|
// fall through to default
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
switch (step) {
|
switch (step) {
|
||||||
@ -529,6 +527,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fall through to step 0 for other characters
|
// fall through to step 0 for other characters
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
@ -488,10 +488,11 @@ public:
|
|||||||
v = &((*v)[t->index]);
|
v = &((*v)[t->index]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd()) {
|
if (m == v->MemberEnd()) {
|
||||||
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
|
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
|
||||||
v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
|
m = v->MemberEnd();
|
||||||
|
v = &(--m)->value; // Assumes AddMember() appends at the end
|
||||||
exist = false;
|
exist = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -543,7 +544,7 @@ public:
|
|||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType:
|
case kObjectType:
|
||||||
{
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
break;
|
break;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
@ -779,7 +780,7 @@ public:
|
|||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType:
|
case kObjectType:
|
||||||
{
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
return false;
|
return false;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
|
@ -597,6 +597,19 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
#endif
|
#endif
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++17 features
|
||||||
|
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
# if __has_cpp_attribute(fallthrough)
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
|
||||||
|
# else
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
||||||
|
#endif
|
||||||
|
|
||||||
//!@endcond
|
//!@endcond
|
||||||
|
|
||||||
//! Assertion (in non-throwing contexts).
|
//! Assertion (in non-throwing contexts).
|
||||||
|
@ -899,7 +899,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeType index;
|
SizeType index = 0;
|
||||||
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
||||||
if (context.patternPropertiesSchemaCount > 0) {
|
if (context.patternPropertiesSchemaCount > 0) {
|
||||||
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
||||||
|
@ -674,6 +674,9 @@ TEST(Pointer, Get) {
|
|||||||
EXPECT_EQ(2u, unresolvedTokenIndex);
|
EXPECT_EQ(2u, unresolvedTokenIndex);
|
||||||
EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
|
EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
|
||||||
EXPECT_EQ(2u, unresolvedTokenIndex);
|
EXPECT_EQ(2u, unresolvedTokenIndex);
|
||||||
|
|
||||||
|
Pointer::Token tokens[] = { { "foo ...", 3, kPointerInvalidIndex } };
|
||||||
|
EXPECT_EQ(&d["foo"], Pointer(tokens, 1).Get(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Pointer, GetWithDefault) {
|
TEST(Pointer, GetWithDefault) {
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
DOXYGEN_VER=doxygen-1.8.15
|
DOXYGEN_VER=1_8_16
|
||||||
DOXYGEN_TAR=${DOXYGEN_VER}.linux.bin.tar.gz
|
DOXYGEN_URL="https://codeload.github.com/doxygen/doxygen/tar.gz/Release_${DOXYGEN_VER}"
|
||||||
DOXYGEN_URL="http://doxygen.nl/files/${DOXYGEN_TAR}"
|
|
||||||
|
|
||||||
: ${GITHUB_REPO:="Tencent/rapidjson"}
|
: ${GITHUB_REPO:="Tencent/rapidjson"}
|
||||||
GITHUB_HOST="github.com"
|
GITHUB_HOST="github.com"
|
||||||
@ -47,9 +46,17 @@ abort() {
|
|||||||
# install doxygen binary distribution
|
# install doxygen binary distribution
|
||||||
doxygen_install()
|
doxygen_install()
|
||||||
{
|
{
|
||||||
wget -O - "${DOXYGEN_URL}" | \
|
cd ${TMPDIR-/tmp}
|
||||||
tar xz -C ${TMPDIR-/tmp} ${DOXYGEN_VER}/bin/doxygen
|
curl ${DOXYGEN_URL} -o doxygen.tar.gz
|
||||||
export PATH="${TMPDIR-/tmp}/${DOXYGEN_VER}/bin:$PATH"
|
tar zxvf doxygen.tar.gz
|
||||||
|
mkdir doxygen_build
|
||||||
|
cd doxygen_build
|
||||||
|
cmake ../doxygen-Release_${DOXYGEN_VER}/
|
||||||
|
make
|
||||||
|
|
||||||
|
export PATH="${TMPDIR-/tmp}/doxygen_build/bin:$PATH"
|
||||||
|
|
||||||
|
cd ../../
|
||||||
}
|
}
|
||||||
|
|
||||||
doxygen_run()
|
doxygen_run()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user