Merge pull request #1502 from ylavic/compilation_fixes

Compilation fixes
diff --git a/.travis.yml b/.travis.yml
index df821a7..783c052 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,7 +20,7 @@
 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:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0275672..3b9ac51 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,13 +9,18 @@
 
 SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
 
-PROJECT(RapidJSON CXX)
-
 set(LIB_MAJOR_VERSION "1")
 set(LIB_MINOR_VERSION "1")
 set(LIB_PATCH_VERSION "0")
 set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}")
 
+if (CMAKE_VERSION VERSION_LESS 3.0)
+    PROJECT(RapidJSON CXX)
+else()
+    cmake_policy(SET CMP0048 NEW)
+    PROJECT(RapidJSON VERSION "${LIB_VERSION_STRING}" LANGUAGES CXX)
+endif()
+
 # compile in release with debug info mode by default
 if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
diff --git a/doc/internals.md b/doc/internals.md
index 706f98c..81fe9c1 100644
--- a/doc/internals.md
+++ b/doc/internals.md
@@ -79,7 +79,7 @@
 | `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|
 |---------------------|-------------------------------------|:----:|:----:|
diff --git a/doc/internals.zh-cn.md b/doc/internals.zh-cn.md
index ca3d297..d414fc1 100644
--- a/doc/internals.zh-cn.md
+++ b/doc/internals.zh-cn.md
@@ -79,7 +79,7 @@
 | `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 @@
 
 ## 整数到字符串的转换 {#itoa}
 
-整数到字符串转换的朴素算法需要对每一个十进制位进行一次处罚。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
+整数到字符串转换的朴素算法需要对每一个十进制位进行一次除法。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
 
 虽然 SSE2 版本是最快的,但它和第二快的 `branchlut` 差距不大。而且 `branchlut` 是纯C++实现,所以我们在 RapidJSON 中使用了 `branchlut`。
 
diff --git a/doc/sax.md b/doc/sax.md
index 874361f..d42d043 100644
--- a/doc/sax.md
+++ b/doc/sax.md
@@ -37,7 +37,7 @@
 Key("n", 1, true)
 Null()
 Key("i")
-UInt(123)
+Uint(123)
 Key("pi")
 Double(3.1416)
 Key("a")
diff --git a/doc/sax.zh-cn.md b/doc/sax.zh-cn.md
index 740c339..9b11e76 100644
--- a/doc/sax.zh-cn.md
+++ b/doc/sax.zh-cn.md
@@ -37,7 +37,7 @@
 Key("n", 1, true)
 Null()
 Key("i")
-UInt(123)
+Uint(123)
 Key("pi")
 Double(3.1416)
 Key("a")
@@ -91,7 +91,7 @@
 }
 ~~~~~~~~~~
 
-注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类形,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
+注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类型,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
 
 ## 处理器 {#Handler}
 
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 3fa63c9..4bde2fa 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -82,7 +82,7 @@
 ~~~~~~~~~~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"]
diff --git a/doc/tutorial.zh-cn.md b/doc/tutorial.zh-cn.md
index 3bacfb0..8b24ff1 100644
--- a/doc/tutorial.zh-cn.md
+++ b/doc/tutorial.zh-cn.md
@@ -82,7 +82,7 @@
 ~~~~~~~~~~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 @@
 ~~~~~~~~~~
 
 ## 修改 Object {#ModifyObject}
-Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加城员:
+Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加成员:
 
 * `Value& AddMember(Value&, Value&, Allocator& allocator)`
 * `Value& AddMember(StringRefType, Value&, Allocator&)`
diff --git a/example/tutorial/tutorial.cpp b/example/tutorial/tutorial.cpp
index c8bfcc1..d6021c6 100644
--- a/example/tutorial/tutorial.cpp
+++ b/example/tutorial/tutorial.cpp
@@ -57,7 +57,7 @@
     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());
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index d1b90eb..f070234 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -63,15 +63,45 @@
     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);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -205,17 +235,17 @@
 // class-based member iterator implementation disabled, use plain pointers
 
 template <bool Const, typename Encoding, typename Allocator>
-struct GenericMemberIterator;
+class GenericMemberIterator;
 
 //! non-const GenericMemberIterator
 template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<false,Encoding,Allocator> {
+class GenericMemberIterator<false,Encoding,Allocator> {
     //! use plain pointer as iterator type
     typedef GenericMember<Encoding,Allocator>* Iterator;
 };
 //! const GenericMemberIterator
 template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<true,Encoding,Allocator> {
+class GenericMemberIterator<true,Encoding,Allocator> {
     //! use plain const pointer as iterator type
     typedef const GenericMember<Encoding,Allocator>* Iterator;
 };
diff --git a/include/rapidjson/fwd.h b/include/rapidjson/fwd.h
index e8104e8..b74a2b8 100644
--- a/include/rapidjson/fwd.h
+++ b/include/rapidjson/fwd.h
@@ -102,7 +102,7 @@
 // document.h
 
 template <typename Encoding, typename Allocator> 
-struct GenericMember;
+class GenericMember;
 
 template <bool Const, typename Encoding, typename Allocator>
 class GenericMemberIterator;
diff --git a/include/rapidjson/internal/clzll.h b/include/rapidjson/internal/clzll.h
new file mode 100644
index 0000000..abe44df
--- /dev/null
+++ b/include/rapidjson/internal/clzll.h
@@ -0,0 +1,72 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_CLZLL_H_
+#define RAPIDJSON_CLZLL_H_
+
+#include "../rapidjson.h"
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#if defined(_WIN64)
+#pragma intrinsic(_BitScanReverse64)
+#else
+#pragma intrinsic(_BitScanReverse)
+#endif
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+namespace internal {
+
+#if (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
+#define RAPIDJSON_CLZLL __builtin_clzll
+#else
+
+inline uint32_t clzll(uint64_t x) {
+    // Passing 0 to __builtin_clzll is UB in GCC and results in an
+    // infinite loop in the software implementation.
+    RAPIDJSON_ASSERT(x != 0);
+
+#if defined(_MSC_VER)
+    unsigned long r = 0;
+#if defined(_WIN64)
+    _BitScanReverse64(&r, x);
+#else
+    // Scan the high 32 bits.
+    if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
+        return 63 - (r + 32);
+
+    // Scan the low 32 bits.
+    _BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF));
+#endif // _WIN64
+
+    return 63 - r;
+#else
+    uint32_t r;
+    while (!(x & (static_cast<uint64_t>(1) << 63))) {
+        x <<= 1;
+        ++r;
+    }
+
+    return r;
+#endif // _MSC_VER
+}
+
+#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
+#endif // (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
+
+} // namespace internal
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_CLZLL_H_
\ No newline at end of file
diff --git a/include/rapidjson/internal/diyfp.h b/include/rapidjson/internal/diyfp.h
index b6c2cf5..f46059a 100644
--- a/include/rapidjson/internal/diyfp.h
+++ b/include/rapidjson/internal/diyfp.h
@@ -20,11 +20,11 @@
 #define RAPIDJSON_DIYFP_H_
 
 #include "../rapidjson.h"
+#include "clzll.h"
 #include <limits>
 
 #if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
 #include <intrin.h>
-#pragma intrinsic(_BitScanReverse64)
 #pragma intrinsic(_umul128)
 #endif
 
@@ -100,22 +100,8 @@
     }
 
     DiyFp Normalize() const {
-        RAPIDJSON_ASSERT(f != 0); // https://stackoverflow.com/a/26809183/291737
-#if defined(_MSC_VER) && defined(_M_AMD64)
-        unsigned long index;
-        _BitScanReverse64(&index, f);
-        return DiyFp(f << (63 - index), e - (63 - index));
-#elif defined(__GNUC__) && __GNUC__ >= 4
-        int s = __builtin_clzll(f);
+        int s = static_cast<int>(RAPIDJSON_CLZLL(f));
         return DiyFp(f << s, e - s);
-#else
-        DiyFp res = *this;
-        while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
-            res.f <<= 1;
-            res.e--;
-        }
-        return res;
-#endif
     }
 
     DiyFp NormalizeBoundary() const {
diff --git a/include/rapidjson/internal/regex.h b/include/rapidjson/internal/regex.h
index 16e3559..af7e06d 100644
--- a/include/rapidjson/internal/regex.h
+++ b/include/rapidjson/internal/regex.h
@@ -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 @@
 #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 @@
                     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 @@
                 else if (!CharacterEscape(ds, &codepoint))
                     return false;
                 // fall through to default
+                RAPIDJSON_DELIBERATE_FALLTHROUGH;
 
             default:
                 switch (step) {
@@ -529,6 +527,7 @@
                         break;
                     }
                     // fall through to step 0 for other characters
+                    RAPIDJSON_DELIBERATE_FALLTHROUGH;
 
                 case 0:
                     {
diff --git a/include/rapidjson/pointer.h b/include/rapidjson/pointer.h
index 063abab..b8143b6 100644
--- a/include/rapidjson/pointer.h
+++ b/include/rapidjson/pointer.h
@@ -488,10 +488,11 @@
                     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 @@
             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 @@
             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;
diff --git a/include/rapidjson/rapidjson.h b/include/rapidjson/rapidjson.h
index 330803e..329ce92 100644
--- a/include/rapidjson/rapidjson.h
+++ b/include/rapidjson/rapidjson.h
@@ -490,6 +490,12 @@
 #define RAPIDJSON_VERSION_CODE(x,y,z) \
   (((x)*100000) + ((y)*100) + (z))
 
+#if defined(__has_builtin)
+#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#define RAPIDJSON_HAS_BUILTIN(x) 0
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
 
@@ -591,6 +597,19 @@
 #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).
diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h
index 44a6bcd..13d27c2 100644
--- a/include/rapidjson/reader.h
+++ b/include/rapidjson/reader.h
@@ -20,6 +20,7 @@
 #include "allocators.h"
 #include "stream.h"
 #include "encodedstream.h"
+#include "internal/clzll.h"
 #include "internal/meta.h"
 #include "internal/stack.h"
 #include "internal/strtod.h"
@@ -443,16 +444,16 @@
 
         x = vmvnq_u8(x);                       // Negate
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
         if (low == 0) {
             if (high != 0) {
-                int lz =__builtin_clzll(high);;
+                uint32_t lz = RAPIDJSON_CLZLL(high);
                 return p + 8 + (lz >> 3);
             }
         } else {
-            int lz = __builtin_clzll(low);;
+            uint32_t lz = RAPIDJSON_CLZLL(low);
             return p + (lz >> 3);
         }
     }
@@ -479,16 +480,16 @@
 
         x = vmvnq_u8(x);                       // Negate
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
         if (low == 0) {
             if (high != 0) {
-                int lz = __builtin_clzll(high);
+                uint32_t lz = RAPIDJSON_CLZLL(high);
                 return p + 8 + (lz >> 3);
             }
         } else {
-            int lz = __builtin_clzll(low);
+            uint32_t lz = RAPIDJSON_CLZLL(low);
             return p + (lz >> 3);
         }
     }
@@ -1244,19 +1245,19 @@
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
             SizeType length = 0;
             bool escaped = false;
             if (low == 0) {
                 if (high != 0) {
-                    unsigned lz = (unsigned)__builtin_clzll(high);;
+                    uint32_t lz = RAPIDJSON_CLZLL(high);
                     length = 8 + (lz >> 3);
                     escaped = true;
                 }
             } else {
-                unsigned lz = (unsigned)__builtin_clzll(low);;
+                uint32_t lz = RAPIDJSON_CLZLL(low);
                 length = lz >> 3;
                 escaped = true;
             }
@@ -1314,19 +1315,19 @@
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
             SizeType length = 0;
             bool escaped = false;
             if (low == 0) {
                 if (high != 0) {
-                    unsigned lz = (unsigned)__builtin_clzll(high);
+                    uint32_t lz = RAPIDJSON_CLZLL(high);
                     length = 8 + (lz >> 3);
                     escaped = true;
                 }
             } else {
-                unsigned lz = (unsigned)__builtin_clzll(low);
+                uint32_t lz = RAPIDJSON_CLZLL(low);
                 length = lz >> 3;
                 escaped = true;
             }
@@ -1370,17 +1371,17 @@
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
             if (low == 0) {
                 if (high != 0) {
-                    int lz = __builtin_clzll(high);
+                    uint32_t lz = RAPIDJSON_CLZLL(high);
                     p += 8 + (lz >> 3);
                     break;
                 }
             } else {
-                int lz = __builtin_clzll(low);
+                uint32_t lz = RAPIDJSON_CLZLL(low);
                 p += lz >> 3;
                 break;
             }
@@ -1403,7 +1404,7 @@
         RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
         RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
         RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
-		  RAPIDJSON_FORCEINLINE void Push(char) {}
+        RAPIDJSON_FORCEINLINE void Push(char) {}
 
         size_t Tell() { return is.Tell(); }
         size_t Length() { return 0; }
diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h
index 5b622f7..fc39d06 100644
--- a/include/rapidjson/schema.h
+++ b/include/rapidjson/schema.h
@@ -443,7 +443,6 @@
         exclusiveMaximum_(false),
         defaultValueLength_(0)
     {
-        typedef typename SchemaDocumentType::ValueType ValueType;
         typedef typename ValueType::ConstValueIterator ConstValueIterator;
         typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
 
@@ -899,7 +898,7 @@
                 }
         }
 
-        SizeType index;
+        SizeType index  = 0;
         if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
             if (context.patternPropertiesSchemaCount > 0) {
                 context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
@@ -1149,7 +1148,7 @@
 #elif RAPIDJSON_SCHEMA_USE_STDREGEX
     template <typename ValueType>
     RegexType* CreatePattern(const ValueType& value) {
-        if (value.IsString())
+        if (value.IsString()) {
             RegexType *r = static_cast<RegexType*>(allocator_->Malloc(sizeof(RegexType)));
             try {
                 return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
@@ -1157,6 +1156,7 @@
             catch (const std::regex_error&) {
                 AllocatorType::Free(r);
             }
+        }
         return 0;
     }
 
diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h
index 6f5b690..ce39e76 100644
--- a/include/rapidjson/writer.h
+++ b/include/rapidjson/writer.h
@@ -16,6 +16,7 @@
 #define RAPIDJSON_WRITER_H_
 
 #include "stream.h"
+#include "internal/clzll.h"
 #include "internal/meta.h"
 #include "internal/stack.h"
 #include "internal/strfunc.h"
@@ -226,7 +227,7 @@
       return Key(str.data(), SizeType(str.size()));
     }
 #endif
-	
+
     bool EndObject(SizeType memberCount = 0) {
         (void)memberCount;
         RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
@@ -668,19 +669,19 @@
         x = vorrq_u8(x, vcltq_u8(s, s3));
 
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
         SizeType len = 0;
         bool escaped = false;
         if (low == 0) {
             if (high != 0) {
-                unsigned lz = (unsigned)__builtin_clzll(high);
+                uint32_t lz = RAPIDJSON_CLZLL(high);
                 len = 8 + (lz >> 3);
                 escaped = true;
             }
         } else {
-            unsigned lz = (unsigned)__builtin_clzll(low);
+            uint32_t lz = RAPIDJSON_CLZLL(low);
             len = lz >> 3;
             escaped = true;
         }
diff --git a/readme.md b/readme.md
index 78c9540..fc325ee 100644
--- a/readme.md
+++ b/readme.md
@@ -158,3 +158,50 @@
   * [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
   * [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
   * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
+
+## Contributing
+
+RapidJSON welcomes contributions. When contributing, please follow the code below.
+
+### Issues
+
+Feel free to submit issues and enhancement requests.
+
+Please help us by providing **minimal reproducible examples**, because source code is easier to let other people understand what happens.
+For crash problems on certain platforms, please bring stack dump content with the detail of the OS, compiler, etc.
+
+Please try breakpoint debugging first, tell us what you found, see if we can start exploring based on more information been prepared.
+
+### Workflow
+
+In general, we follow the "fork-and-pull" Git workflow.
+
+ 1. **Fork** the repo on GitHub
+ 2. **Clone** the project to your own machine
+ 3. **Checkout** a new branch on your fork, start developing on the branch
+ 4. **Test** the change before commit, Make sure the changes pass all the tests, including `unittest` and `preftest`, please add test case for each new feature or bug-fix if needed.
+ 5. **Commit** changes to your own branch
+ 6. **Push** your work back up to your fork
+ 7. Submit a **Pull request** so that we can review your changes
+
+NOTE: Be sure to merge the latest from "upstream" before making a pull request!
+
+### Copyright and Licensing
+
+You can copy and paste the license summary from below.
+
+```
+Tencent is pleased to support the open source community by making RapidJSON available.
+
+Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+
+Licensed under the MIT License (the "License"); you may not use this file except
+in compliance with the License. You may obtain a copy of the License at
+
+http://opensource.org/licenses/MIT
+
+Unless required by applicable law or agreed to in writing, software distributed 
+under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+specific language governing permissions and limitations under the License.
+```
\ No newline at end of file
diff --git a/test/unittest/pointertest.cpp b/test/unittest/pointertest.cpp
index 858fd2a..4629f76 100644
--- a/test/unittest/pointertest.cpp
+++ b/test/unittest/pointertest.cpp
@@ -674,6 +674,9 @@
     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) {
diff --git a/travis-doxygen.sh b/travis-doxygen.sh
index 38e4eb6..cf18dc3 100755
--- a/travis-doxygen.sh
+++ b/travis-doxygen.sh
@@ -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 @@
 # 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()