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