Merge pull request #497 from miloyip/issue473_warning

Fix #473 clang -Weverything
This commit is contained in:
Milo Yip 2015-12-30 09:21:39 +08:00
commit ecfdb0c0fe
44 changed files with 529 additions and 337 deletions

View File

@ -20,7 +20,7 @@ include_directories("../include/")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
endif() endif()

View File

@ -27,7 +27,7 @@ struct CapitalizeFilter {
bool String(const char* str, SizeType length, bool) { bool String(const char* str, SizeType length, bool) {
buffer_.clear(); buffer_.clear();
for (SizeType i = 0; i < length; i++) for (SizeType i = 0; i < length; i++)
buffer_.push_back(std::toupper(str[i])); buffer_.push_back(static_cast<char>(std::toupper(str[i])));
return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string
} }
bool StartObject() { return out_.StartObject(); } bool StartObject() { return out_.StartObject(); }
@ -58,7 +58,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
CapitalizeFilter<Writer<FileWriteStream> > filter(writer); CapitalizeFilter<Writer<FileWriteStream> > filter(writer);
if (!reader.Parse(is, filter)) { if (!reader.Parse(is, filter)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }

View File

@ -24,7 +24,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse(is, writer)) { if (!reader.Parse(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }

View File

@ -17,6 +17,11 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(switch-enum)
#endif
struct MessageHandler struct MessageHandler
: public BaseReaderHandler<UTF8<>, MessageHandler> { : public BaseReaderHandler<UTF8<>, MessageHandler> {
MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {} MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
@ -63,7 +68,11 @@ struct MessageHandler
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif
void ParseMessages(const char* json, MessageMap& messages) { #ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
static void ParseMessages(const char* json, MessageMap& messages) {
Reader reader; Reader reader;
MessageHandler handler; MessageHandler handler;
StringStream ss(json); StringStream ss(json);

View File

@ -22,7 +22,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }

View File

@ -48,7 +48,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
//if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { //if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode())); fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }

View File

@ -18,10 +18,10 @@ protected:
void Serialize(Writer& writer) const { void Serialize(Writer& writer) const {
// This base class just write out name-value pairs, without wrapping within an object. // This base class just write out name-value pairs, without wrapping within an object.
writer.String("name"); writer.String("name");
#ifdef RAPIDJSON_HAS_STDSTRING #if RAPIDJSON_HAS_STDSTRING
writer.String(name_); writer.String(name_);
#else #else
writer.String(name_.c_str(), (SizeType)name_.length()); // Supplying length of string is faster. writer.String(name_.c_str(), static_cast<SizeType>(name_.length())); // Supplying length of string is faster.
#endif #endif
writer.String("age"); writer.String("age");
writer.Uint(age_); writer.Uint(age_);
@ -44,10 +44,10 @@ public:
writer.StartObject(); writer.StartObject();
writer.String("school"); writer.String("school");
#ifdef RAPIDJSON_HAS_STDSTRING #if RAPIDJSON_HAS_STDSTRING
writer.String(school_); writer.String(school_);
#else #else
writer.String(school_.c_str(), (SizeType)school_.length()); writer.String(school_.c_str(), static_cast<SizeType>(school_.length()));
#endif #endif
writer.String("GPA"); writer.String("GPA");

View File

@ -121,17 +121,17 @@ int main(int, char*[]) {
// This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer. // This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
Value author; Value author;
{ {
char buffer[10]; char buffer2[10];
int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string. int len = sprintf(buffer2, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string.
author.SetString(buffer, static_cast<size_t>(len), document.GetAllocator()); author.SetString(buffer2, static_cast<SizeType>(len), document.GetAllocator());
// Shorter but slower version: // Shorter but slower version:
// document["hello"].SetString(buffer, document.GetAllocator()); // document["hello"].SetString(buffer, document.GetAllocator());
// Constructor version: // Constructor version:
// Value author(buffer, len, document.GetAllocator()); // Value author(buffer, len, document.GetAllocator());
// Value author(buffer, document.GetAllocator()); // Value author(buffer, document.GetAllocator());
memset(buffer, 0, sizeof(buffer)); // For demonstration purpose. memset(buffer2, 0, sizeof(buffer2)); // For demonstration purpose.
} }
// Variable 'buffer' is unusable now but 'author' has already made a copy. // Variable 'buffer' is unusable now but 'author' has already made a copy.
document.AddMember("author", author, document.GetAllocator()); document.AddMember("author", author, document.GetAllocator());

View File

@ -199,7 +199,7 @@ public:
return originalPtr; return originalPtr;
// Simply expand it if it is the last allocation and there is sufficient space // Simply expand it if it is the last allocation and there is sufficient space
if (originalPtr == (char *)(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
size_t increment = static_cast<size_t>(newSize - originalSize); size_t increment = static_cast<size_t>(newSize - originalSize);
increment = RAPIDJSON_ALIGN(increment); increment = RAPIDJSON_ALIGN(increment);
if (chunkHead_->size + increment <= chunkHead_->capacity) { if (chunkHead_->size + increment <= chunkHead_->capacity) {

View File

@ -25,36 +25,19 @@
#ifdef _MSC_VER #ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#elif defined(__GNUC__) #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
RAPIDJSON_DIAG_OFF(switch-enum)
#endif
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
#endif #endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_HAS_STDSTRING
#ifndef RAPIDJSON_HAS_STDSTRING
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
#else
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
#endif
/*! \def RAPIDJSON_HAS_STDSTRING
\ingroup RAPIDJSON_CONFIG
\brief Enable RapidJSON support for \c std::string
By defining this preprocessor symbol to \c 1, several convenience functions for using
\ref rapidjson::GenericValue with \c std::string are enabled, especially
for construction and comparison.
\hideinitializer
*/
#endif // !defined(RAPIDJSON_HAS_STDSTRING)
#if RAPIDJSON_HAS_STDSTRING
#include <string>
#endif // RAPIDJSON_HAS_STDSTRING
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
#include <iterator> // std::iterator, std::random_access_iterator_tag #include <iterator> // std::iterator, std::random_access_iterator_tag
#endif #endif
@ -260,6 +243,7 @@ struct GenericStringRef {
typedef CharType Ch; //!< character type of the string typedef CharType Ch; //!< character type of the string
//! Create string reference from \c const character array //! Create string reference from \c const character array
#ifndef __clang__ // -Wdocumentation
/*! /*!
This constructor implicitly creates a constant string reference from This constructor implicitly creates a constant string reference from
a \c const character array. It has better performance than a \c const character array. It has better performance than
@ -282,11 +266,13 @@ struct GenericStringRef {
In such cases, the referenced string should be \b copied to the In such cases, the referenced string should be \b copied to the
GenericValue instead. GenericValue instead.
*/ */
#endif
template<SizeType N> template<SizeType N>
GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
: s(str), length(N-1) {} : s(str), length(N-1) {}
//! Explicitly create string reference from \c const character pointer //! Explicitly create string reference from \c const character pointer
#ifndef __clang__ // -Wdocumentation
/*! /*!
This constructor can be used to \b explicitly create a reference to This constructor can be used to \b explicitly create a reference to
a constant string pointer. a constant string pointer.
@ -305,16 +291,19 @@ struct GenericStringRef {
In such cases, the referenced string should be \b copied to the In such cases, the referenced string should be \b copied to the
GenericValue instead. GenericValue instead.
*/ */
#endif
explicit GenericStringRef(const CharType* str) explicit GenericStringRef(const CharType* str)
: s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); } : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
//! Create constant string reference from pointer and length //! Create constant string reference from pointer and length
#ifndef __clang__ // -Wdocumentation
/*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
\param len length of the string, excluding the trailing NULL terminator \param len length of the string, excluding the trailing NULL terminator
\post \ref s == str && \ref length == len \post \ref s == str && \ref length == len
\note Constant complexity. \note Constant complexity.
*/ */
#endif
GenericStringRef(const CharType* str, SizeType len) GenericStringRef(const CharType* str, SizeType len)
: s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); } : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
@ -654,7 +643,7 @@ public:
*/ */
template <typename SourceAllocator> template <typename SourceAllocator>
GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
RAPIDJSON_ASSERT((void*)this != (void const*)&rhs); RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
this->~GenericValue(); this->~GenericValue();
new (this) GenericValue(rhs, allocator); new (this) GenericValue(rhs, allocator);
return *this; return *this;
@ -736,7 +725,7 @@ public:
else else
return data_.n.u64 == rhs.data_.n.u64; return data_.n.u64 == rhs.data_.n.u64;
default: // kTrueType, kFalseType, kNullType default:
return true; return true;
} }
} }
@ -864,8 +853,14 @@ public:
return member->value; return member->value;
else { else {
RAPIDJSON_ASSERT(false); // see above note RAPIDJSON_ASSERT(false); // see above note
static GenericValue NullValue;
return NullValue; // This will generate -Wexit-time-destructors in clang
// static GenericValue NullValue;
// return NullValue;
// Use static buffer and placement-new to prevent destruction
static char buffer[sizeof(GenericValue)];
return *new (buffer) GenericValue();
} }
} }
template <typename SourceAllocator> template <typename SourceAllocator>
@ -1235,8 +1230,8 @@ public:
MemberIterator pos = MemberBegin() + (first - MemberBegin()); MemberIterator pos = MemberBegin() + (first - MemberBegin());
for (MemberIterator itr = pos; itr != last; ++itr) for (MemberIterator itr = pos; itr != last; ++itr)
itr->~Member(); itr->~Member();
std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member)); std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
data_.o.size -= (last - first); data_.o.size -= static_cast<SizeType>(last - first);
return pos; return pos;
} }
@ -1328,7 +1323,7 @@ public:
GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
RAPIDJSON_ASSERT(IsArray()); RAPIDJSON_ASSERT(IsArray());
if (newCapacity > data_.a.capacity) { if (newCapacity > data_.a.capacity) {
data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); data_.a.elements = static_cast<GenericValue*>(allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)));
data_.a.capacity = newCapacity; data_.a.capacity = newCapacity;
} }
return *this; return *this;
@ -1435,8 +1430,8 @@ public:
ValueIterator pos = Begin() + (first - Begin()); ValueIterator pos = Begin() + (first - Begin());
for (ValueIterator itr = pos; itr != last; ++itr) for (ValueIterator itr = pos; itr != last; ++itr)
itr->~GenericValue(); itr->~GenericValue();
std::memmove(pos, last, (End() - last) * sizeof(GenericValue)); std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
data_.a.size -= (last - first); data_.a.size -= static_cast<SizeType>(last - first);
return pos; return pos;
} }
@ -1455,8 +1450,8 @@ public:
if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double
if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) if ((flags_ & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
} }
GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
@ -1628,9 +1623,9 @@ private:
enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
Ch str[MaxChars]; Ch str[MaxChars];
inline static bool Usable(SizeType len) { return (MaxSize >= len); } inline static bool Usable(SizeType len) { return (MaxSize >= len); }
inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); } inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); } inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
}; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
// By using proper binary layout, retrieval of different integer types do not need conversions. // By using proper binary layout, retrieval of different integer types do not need conversions.
@ -1683,7 +1678,7 @@ private:
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
flags_ = kArrayFlag; flags_ = kArrayFlag;
if (count) { if (count) {
data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue)); data_.a.elements = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
std::memcpy(data_.a.elements, values, count * sizeof(GenericValue)); std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
} }
else else
@ -1695,7 +1690,7 @@ private:
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
flags_ = kObjectFlag; flags_ = kObjectFlag;
if (count) { if (count) {
data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member)); data_.o.members = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
std::memcpy(data_.o.members, members, count * sizeof(Member)); std::memcpy(data_.o.members, members, count * sizeof(Member));
} }
else else
@ -1720,7 +1715,7 @@ private:
} else { } else {
flags_ = kCopyStringFlag; flags_ = kCopyStringFlag;
data_.s.length = s.length; data_.s.length = s.length;
str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch)); str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
data_.s.str = str; data_.s.str = str;
} }
std::memcpy(str, s, s.length * sizeof(Ch)); std::memcpy(str, s, s.length * sizeof(Ch));
@ -1847,7 +1842,7 @@ public:
//! Exchange the contents of this document with those of another. //! Exchange the contents of this document with those of another.
/*! /*!
\param other Another document. \param rhs Another document.
\note Constant complexity. \note Constant complexity.
\see GenericValue::Swap \see GenericValue::Swap
*/ */
@ -1987,6 +1982,7 @@ public:
size_t GetErrorOffset() const { return parseResult_.Offset(); } size_t GetErrorOffset() const { return parseResult_.Offset(); }
//! Implicit conversion to get the last parse result //! Implicit conversion to get the last parse result
#ifndef __clang // -Wdocumentation
/*! \return \ref ParseResult of the last parse operation /*! \return \ref ParseResult of the last parse operation
\code \code
@ -1996,6 +1992,7 @@ public:
printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
\endcode \endcode
*/ */
#endif
operator ParseResult() const { return parseResult_; } operator ParseResult() const { return parseResult_; }
//!@} //!@}
@ -2046,7 +2043,7 @@ private:
bool EndObject(SizeType memberCount) { bool EndObject(SizeType memberCount) {
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
return true; return true;
} }
@ -2109,7 +2106,7 @@ GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,Sourc
SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
} }
break; break;
default: // kNumberType, kTrueType, kFalseType, kNullType default:
flags_ = rhs.flags_; flags_ = rhs.flags_;
data_ = *reinterpret_cast<const Data*>(&rhs.data_); data_ = *reinterpret_cast<const Data*>(&rhs.data_);
break; break;
@ -2118,7 +2115,15 @@ GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,Sourc
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#if defined(_MSC_VER) || defined(__GNUC__) #ifdef _MSC_VER
RAPIDJSON_DIAG_POP
#endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#ifdef __GNUC__
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif

View File

@ -22,6 +22,11 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! Input byte stream wrapper with a statically bound encoding. //! Input byte stream wrapper with a statically bound encoding.
@ -60,7 +65,7 @@ private:
//! Output byte stream wrapper with statically bound encoding. //! Output byte stream wrapper with statically bound encoding.
/*! /*!
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
\tparam InputByteStream Type of input byte stream. For example, FileWriteStream. \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
*/ */
template <typename Encoding, typename OutputByteStream> template <typename Encoding, typename OutputByteStream>
class EncodedOutputStream { class EncodedOutputStream {
@ -142,7 +147,7 @@ private:
// FF FE UTF-16LE // FF FE UTF-16LE
// EF BB BF UTF-8 // EF BB BF UTF-8
const unsigned char* c = (const unsigned char *)is_->Peek4(); const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
if (!c) if (!c)
return; return;
@ -193,7 +198,7 @@ private:
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. //! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
/*! /*!
\tparam CharType Type of character for writing. \tparam CharType Type of character for writing.
\tparam InputByteStream type of output byte stream to be wrapped. \tparam OutputByteStream type of output byte stream to be wrapped.
*/ */
template <typename CharType, typename OutputByteStream> template <typename CharType, typename OutputByteStream>
class AutoUTFOutputStream { class AutoUTFOutputStream {
@ -254,6 +259,10 @@ private:
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#ifdef __GNUC__ #ifdef __GNUC__
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif

View File

@ -122,17 +122,17 @@ struct UTF8 {
template <typename InputStream> template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) { static bool Decode(InputStream& is, unsigned* codepoint) {
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu) #define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) #define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70) #define TAIL() COPY(); TRANS(0x70)
Ch c = is.Take(); typename InputStream::Ch c = is.Take();
if (!(c & 0x80)) { if (!(c & 0x80)) {
*codepoint = (unsigned char)c; *codepoint = static_cast<unsigned char>(c);
return true; return true;
} }
unsigned char type = GetRange((unsigned char)c); unsigned char type = GetRange(static_cast<unsigned char>(c));
*codepoint = (0xFF >> type) & (unsigned char)c; *codepoint = (0xFF >> type) & static_cast<unsigned char>(c);
bool result = true; bool result = true;
switch (type) { switch (type) {
case 2: TAIL(); return result; case 2: TAIL(); return result;
@ -152,7 +152,7 @@ struct UTF8 {
template <typename InputStream, typename OutputStream> template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) { static bool Validate(InputStream& is, OutputStream& os) {
#define COPY() os.Put(c = is.Take()) #define COPY() os.Put(c = is.Take())
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) #define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70) #define TAIL() COPY(); TRANS(0x70)
Ch c; Ch c;
COPY(); COPY();
@ -160,7 +160,7 @@ struct UTF8 {
return true; return true;
bool result = true; bool result = true;
switch (GetRange((unsigned char)c)) { switch (GetRange(static_cast<unsigned char>(c))) {
case 2: TAIL(); return result; case 2: TAIL(); return result;
case 3: TAIL(); TAIL(); return result; case 3: TAIL(); TAIL(); return result;
case 4: COPY(); TRANS(0x50); TAIL(); return result; case 4: COPY(); TRANS(0x50); TAIL(); return result;
@ -196,12 +196,12 @@ struct UTF8 {
template <typename InputByteStream> template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
Ch c = Take(is); typename InputByteStream::Ch c = Take(is);
if ((unsigned char)c != 0xEFu) return c; if (static_cast<unsigned char>(c) != 0xEFu) return c;
c = is.Take(); c = is.Take();
if ((unsigned char)c != 0xBBu) return c; if (static_cast<unsigned char>(c) != 0xBBu) return c;
c = is.Take(); c = is.Take();
if ((unsigned char)c != 0xBFu) return c; if (static_cast<unsigned char>(c) != 0xBFu) return c;
c = is.Take(); c = is.Take();
return c; return c;
} }
@ -209,13 +209,15 @@ struct UTF8 {
template <typename InputByteStream> template <typename InputByteStream>
static Ch Take(InputByteStream& is) { static Ch Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
return is.Take(); return static_cast<Ch>(is.Take());
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) { static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu); os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
} }
template <typename OutputByteStream> template <typename OutputByteStream>
@ -262,15 +264,15 @@ struct UTF16 {
template <typename InputStream> template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) { static bool Decode(InputStream& is, unsigned* codepoint) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
Ch c = is.Take(); typename InputStream::Ch c = is.Take();
if (c < 0xD800 || c > 0xDFFF) { if (c < 0xD800 || c > 0xDFFF) {
*codepoint = c; *codepoint = static_cast<unsigned>(c);
return true; return true;
} }
else if (c <= 0xDBFF) { else if (c <= 0xDBFF) {
*codepoint = (c & 0x3FF) << 10; *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
c = is.Take(); c = is.Take();
*codepoint |= (c & 0x3FF); *codepoint |= (static_cast<unsigned>(c) & 0x3FF);
*codepoint += 0x10000; *codepoint += 0x10000;
return c >= 0xDC00 && c <= 0xDFFF; return c >= 0xDC00 && c <= 0xDFFF;
} }
@ -281,8 +283,8 @@ struct UTF16 {
static bool Validate(InputStream& is, OutputStream& os) { static bool Validate(InputStream& is, OutputStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
Ch c; typename InputStream::Ch c;
os.Put(c = is.Take()); os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
if (c < 0xD800 || c > 0xDFFF) if (c < 0xD800 || c > 0xDFFF)
return true; return true;
else if (c <= 0xDBFF) { else if (c <= 0xDBFF) {
@ -300,28 +302,29 @@ struct UTF16LE : UTF16<CharType> {
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is); CharType c = Take(is);
return (unsigned short)c == 0xFEFFu ? Take(is) : c; return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
} }
template <typename InputByteStream> template <typename InputByteStream>
static CharType Take(InputByteStream& is) { static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take(); unsigned c = static_cast<uint8_t>(is.Take());
c |= (unsigned char)is.Take() << 8; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
return c; return static_cast<CharType>(c);
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) { static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFFu); os.Put(0xFEu); os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) { static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(c & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
os.Put((c >> 8) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
} }
}; };
@ -332,28 +335,29 @@ struct UTF16BE : UTF16<CharType> {
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is); CharType c = Take(is);
return (unsigned short)c == 0xFEFFu ? Take(is) : c; return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
} }
template <typename InputByteStream> template <typename InputByteStream>
static CharType Take(InputByteStream& is) { static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take() << 8; unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
c |= (unsigned char)is.Take(); c |= static_cast<uint8_t>(is.Take());
return c; return static_cast<CharType>(c);
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) { static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFEu); os.Put(0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) { static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put((c >> 8) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
os.Put(c & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
} }
}; };
@ -406,32 +410,35 @@ struct UTF32LE : UTF32<CharType> {
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is); CharType c = Take(is);
return (unsigned)c == 0x0000FEFFu ? Take(is) : c; return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
} }
template <typename InputByteStream> template <typename InputByteStream>
static CharType Take(InputByteStream& is) { static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take(); unsigned c = static_cast<uint8_t>(is.Take());
c |= (unsigned char)is.Take() << 8; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
c |= (unsigned char)is.Take() << 16; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
c |= (unsigned char)is.Take() << 24; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
return c; return static_cast<CharType>(c);
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) { static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u); os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) { static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(c & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
os.Put((c >> 8) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
os.Put((c >> 16) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
os.Put((c >> 24) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
} }
}; };
@ -442,32 +449,35 @@ struct UTF32BE : UTF32<CharType> {
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = Take(is); CharType c = Take(is);
return (unsigned)c == 0x0000FEFFu ? Take(is) : c; return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
} }
template <typename InputByteStream> template <typename InputByteStream>
static CharType Take(InputByteStream& is) { static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
CharType c = (unsigned char)is.Take() << 24; unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
c |= (unsigned char)is.Take() << 16; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
c |= (unsigned char)is.Take() << 8; c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
c |= (unsigned char)is.Take(); c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
return c; return static_cast<CharType>(c);
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void PutBOM(OutputByteStream& os) { static void PutBOM(OutputByteStream& os) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
} }
template <typename OutputByteStream> template <typename OutputByteStream>
static void Put(OutputByteStream& os, CharType c) { static void Put(OutputByteStream& os, CharType c) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
os.Put((c >> 24) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
os.Put((c >> 16) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
os.Put((c >> 8) & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
os.Put(c & 0xFFu); os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
} }
}; };
@ -493,29 +503,29 @@ struct ASCII {
template <typename InputStream> template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) { static bool Decode(InputStream& is, unsigned* codepoint) {
unsigned char c = static_cast<unsigned char>(is.Take()); uint8_t c = static_cast<uint8_t>(is.Take());
*codepoint = c; *codepoint = c;
return c <= 0X7F; return c <= 0X7F;
} }
template <typename InputStream, typename OutputStream> template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) { static bool Validate(InputStream& is, OutputStream& os) {
unsigned char c = is.Take(); uint8_t c = static_cast<uint8_t>(is.Take());
os.Put(c); os.Put(static_cast<typename OutputStream::Ch>(c));
return c <= 0x7F; return c <= 0x7F;
} }
template <typename InputByteStream> template <typename InputByteStream>
static CharType TakeBOM(InputByteStream& is) { static CharType TakeBOM(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
Ch c = Take(is); uint8_t c = static_cast<uint8_t>(Take(is));
return c; return static_cast<Ch>(c);
} }
template <typename InputByteStream> template <typename InputByteStream>
static Ch Take(InputByteStream& is) { static Ch Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
return is.Take(); return static_cast<Ch>(is.Take());
} }
template <typename OutputByteStream> template <typename OutputByteStream>

View File

@ -12,11 +12,17 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ERROR_EN_H__ #ifndef RAPIDJSON_ERROR_EN_H_
#define RAPIDJSON_ERROR_EN_H__ #define RAPIDJSON_ERROR_EN_H_
#include "error.h" #include "error.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(switch-enum)
RAPIDJSON_DIAG_OFF(covered-switch-default)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! Maps error code of parsing into error message. //! Maps error code of parsing into error message.
@ -55,11 +61,14 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
default: default: return RAPIDJSON_ERROR_STRING("Unknown error.");
return RAPIDJSON_ERROR_STRING("Unknown error.");
} }
} }
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ERROR_EN_H__ #ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_ERROR_EN_H_

View File

@ -12,11 +12,16 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ERROR_ERROR_H__ #ifndef RAPIDJSON_ERROR_ERROR_H_
#define RAPIDJSON_ERROR_ERROR_H__ #define RAPIDJSON_ERROR_ERROR_H_
#include "../rapidjson.h" #include "../rapidjson.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
#endif
/*! \file error.h */ /*! \file error.h */
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ /*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
@ -99,7 +104,7 @@ enum ParseErrorCode {
\see GenericReader::Parse, GenericDocument::Parse \see GenericReader::Parse, GenericDocument::Parse
*/ */
struct ParseResult { struct ParseResult {
public:
//! Default constructor, no error. //! Default constructor, no error.
ParseResult() : code_(kParseErrorNone), offset_(0) {} ParseResult() : code_(kParseErrorNone), offset_(0) {}
//! Constructor to set an error. //! Constructor to set an error.
@ -143,4 +148,8 @@ typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ERROR_ERROR_H__ #ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_ERROR_ERROR_H_

View File

@ -18,6 +18,13 @@
#include "rapidjson.h" #include "rapidjson.h"
#include <cstdio> #include <cstdio>
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
RAPIDJSON_DIAG_OFF(unreachable-code)
RAPIDJSON_DIAG_OFF(missing-noreturn)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! File byte stream for input using fread(). //! File byte stream for input using fread().
@ -85,4 +92,8 @@ private:
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_FILESTREAM_H_ #endif // RAPIDJSON_FILESTREAM_H_

View File

@ -18,6 +18,11 @@
#include "rapidjson.h" #include "rapidjson.h"
#include <cstdio> #include <cstdio>
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(unreachable-code)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! Wrapper of C file stream for input using fread(). //! Wrapper of C file stream for input using fread().
@ -92,4 +97,8 @@ inline void PutN(FileWriteStream& stream, char c, size_t n) {
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_FILESTREAM_H_ #endif // RAPIDJSON_FILESTREAM_H_

View File

@ -240,7 +240,7 @@ private:
uint64_t r = 0; uint64_t r = 0;
for (const char* p = begin; p != end; ++p) { for (const char* p = begin; p != end; ++p) {
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
r = r * 10u + (unsigned)(*p - '0'); r = r * 10u + static_cast<unsigned>(*p - '0');
} }
return r; return r;
} }

View File

@ -35,6 +35,11 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
#endif
struct DiyFp { struct DiyFp {
DiyFp() {} DiyFp() {}
@ -242,6 +247,11 @@ inline DiyFp GetCachedPower10(int exp, int *outExp) {
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
RAPIDJSON_DIAG_OFF(padded)
#endif
} // namespace internal } // namespace internal
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END

View File

@ -53,7 +53,7 @@ public:
else if (order <= -1074) else if (order <= -1074)
return 0; return 0;
else else
return (unsigned)order + 1074; return static_cast<unsigned>(order) + 1074;
} }
private: private:

View File

@ -132,7 +132,7 @@ public:
} }
template<typename T> template<typename T>
T* Bottom() { return (T*)stack_; } T* Bottom() { return reinterpret_cast<T*>(stack_); }
bool HasAllocator() const { bool HasAllocator() const {
return allocator_ != 0; return allocator_ != 0;
@ -168,7 +168,7 @@ private:
void Resize(size_t newCapacity) { void Resize(size_t newCapacity) {
const size_t size = GetSize(); // Backup the current size const size_t size = GetSize(); // Backup the current size
stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity); stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
stackTop_ = stack_ + size; stackTop_ = stack_ + size;
stackEnd_ = stack_ + newCapacity; stackEnd_ = stack_ + newCapacity;
} }

View File

@ -149,7 +149,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
v = v.Normalize(); v = v.Normalize();
error <<= -v.e; error <<= -v.e;
const int dExp = (int)decimalPosition - (int)i + exp; const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
int actualExp; int actualExp;
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
@ -206,7 +206,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
const BigInteger dInt(decimals, length); const BigInteger dInt(decimals, length);
const int dExp = (int)decimalPosition - (int)length + exp; const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
Double a(approx); Double a(approx);
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
if (cmp < 0) if (cmp < 0)
@ -246,8 +246,8 @@ inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t
// Trim right-most digits // Trim right-most digits
const int kMaxDecimalDigit = 780; const int kMaxDecimalDigit = 780;
if ((int)length > kMaxDecimalDigit) { if (static_cast<int>(length) > kMaxDecimalDigit) {
int delta = (int(length) - kMaxDecimalDigit); int delta = (static_cast<int>(length) - kMaxDecimalDigit);
exp += delta; exp += delta;
decimalPosition -= static_cast<unsigned>(delta); decimalPosition -= static_cast<unsigned>(delta);
length = kMaxDecimalDigit; length = kMaxDecimalDigit;

View File

@ -17,6 +17,12 @@
#include "rapidjson.h" #include "rapidjson.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(unreachable-code)
RAPIDJSON_DIAG_OFF(missing-noreturn)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! Represents an in-memory input byte stream. //! Represents an in-memory input byte stream.
@ -58,4 +64,8 @@ struct MemoryStream {
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_MEMORYBUFFER_H_ #endif // RAPIDJSON_MEMORYBUFFER_H_

View File

@ -18,6 +18,11 @@
#include "document.h" #include "document.h"
#include "internal/itoa.h" #include "internal/itoa.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(switch-enum)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
@ -71,7 +76,7 @@ template <typename ValueType, typename Allocator = CrtAllocator>
class GenericPointer { class GenericPointer {
public: public:
typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
typedef typename EncodingType::Ch Ch; //!< Character type from Value typedef typename ValueType::Ch Ch; //!< Character type from Value
//! A token is the basic units of internal representation. //! A token is the basic units of internal representation.
/*! /*!
@ -253,11 +258,12 @@ public:
*/ */
GenericPointer Append(SizeType index, Allocator* allocator = 0) const { GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
char buffer[21]; char buffer[21];
SizeType length = (sizeof(SizeType) == 4 ? internal::u32toa(index, buffer): internal::u64toa(index, buffer)) - buffer; char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
SizeType length = static_cast<SizeType>(end - buffer);
buffer[length] = '\0'; buffer[length] = '\0';
if (sizeof(Ch) == 1) { if (sizeof(Ch) == 1) {
Token token = { (Ch*)buffer, length, index }; Token token = { reinterpret_cast<Ch*>(buffer), length, index };
return Append(token, allocator); return Append(token, allocator);
} }
else { else {
@ -271,7 +277,7 @@ public:
//! Append a token by value, and return a new Pointer //! Append a token by value, and return a new Pointer
/*! /*!
\param value Value (either Uint or String) to be appended. \param token token to be appended.
\param allocator Allocator for the newly return Pointer. \param allocator Allocator for the newly return Pointer.
\return A new Pointer with appended token. \return A new Pointer with appended token.
*/ */
@ -435,7 +441,6 @@ public:
//! Creates a value in a document. //! Creates a value in a document.
/*! /*!
\param document A document to be resolved. \param document A document to be resolved.
\param allocator Allocator for creating the values if the specified value or its parents are not exist.
\param alreadyExist If non-null, it stores whether the resolved value is already exist. \param alreadyExist If non-null, it stores whether the resolved value is already exist.
\return The resolved newly created, or already exists value. \return The resolved newly created, or already exists value.
*/ */
@ -525,7 +530,7 @@ public:
//! Query a value in a subtree with default primitive value. //! Query a value in a subtree with default primitive value.
/*! /*!
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
*/ */
template <typename T> template <typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
@ -555,7 +560,7 @@ public:
//! Query a value in a document with default primitive value. //! Query a value in a document with default primitive value.
/*! /*!
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
*/ */
template <typename T, typename stackAllocator> template <typename T, typename stackAllocator>
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
@ -601,7 +606,7 @@ public:
//! Set a primitive value in a subtree. //! Set a primitive value in a subtree.
/*! /*!
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
*/ */
template <typename T> template <typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
@ -637,7 +642,7 @@ public:
//! Set a primitive value in a document. //! Set a primitive value in a document.
/*! /*!
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
*/ */
template <typename T, typename stackAllocator> template <typename T, typename stackAllocator>
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
@ -759,11 +764,13 @@ private:
} }
//! Parse a JSON String or its URI fragment representation into tokens. //! Parse a JSON String or its URI fragment representation into tokens.
#ifndef __clang__ // -Wdocumentation
/*! /*!
\param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
\param length Length of the source string. \param length Length of the source string.
\note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
*/ */
#endif
void Parse(const Ch* source, size_t length) { void Parse(const Ch* source, size_t length) {
RAPIDJSON_ASSERT(source != NULL); RAPIDJSON_ASSERT(source != NULL);
RAPIDJSON_ASSERT(nameBuffer_ == 0); RAPIDJSON_ASSERT(nameBuffer_ == 0);
@ -857,7 +864,7 @@ private:
*name++ = c; *name++ = c;
} }
token->length = name - token->name; token->length = static_cast<SizeType>(name - token->name);
if (token->length == 0) if (token->length == 0)
isNumber = false; isNumber = false;
*name++ = '\0'; // Null terminator *name++ = '\0'; // Null terminator
@ -944,6 +951,8 @@ private:
*/ */
class PercentDecodeStream { class PercentDecodeStream {
public: public:
typedef typename ValueType::Ch Ch;
//! Constructor //! Constructor
/*! /*!
\param source Start of the stream \param source Start of the stream
@ -973,7 +982,7 @@ private:
return c; return c;
} }
size_t Tell() const { return src_ - head_; } size_t Tell() const { return static_cast<size_t>(src_ - head_); }
bool IsValid() const { return valid_; } bool IsValid() const { return valid_; }
private: private:
@ -1310,4 +1319,8 @@ bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_POINTER_H_ #endif // RAPIDJSON_POINTER_H_

View File

@ -186,7 +186,7 @@ protected:
void WriteIndent() { void WriteIndent() {
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
PutN(*Base::os_, indentChar_, count); PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
} }
Ch indentChar_; Ch indentChar_;

View File

@ -119,6 +119,31 @@
#define RAPIDJSON_NAMESPACE_END } #define RAPIDJSON_NAMESPACE_END }
#endif #endif
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_HAS_STDSTRING
#ifndef RAPIDJSON_HAS_STDSTRING
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
#else
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
#endif
/*! \def RAPIDJSON_HAS_STDSTRING
\ingroup RAPIDJSON_CONFIG
\brief Enable RapidJSON support for \c std::string
By defining this preprocessor symbol to \c 1, several convenience functions for using
\ref rapidjson::GenericValue with \c std::string are enabled, especially
for construction and comparison.
\hideinitializer
*/
#endif // !defined(RAPIDJSON_HAS_STDSTRING)
#if RAPIDJSON_HAS_STDSTRING
#include <string>
#endif // RAPIDJSON_HAS_STDSTRING
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NO_INT64DEFINE // RAPIDJSON_NO_INT64DEFINE
@ -351,7 +376,9 @@ RAPIDJSON_NAMESPACE_END
// Adopt from boost // Adopt from boost
#ifndef RAPIDJSON_STATIC_ASSERT #ifndef RAPIDJSON_STATIC_ASSERT
#ifndef __clang__
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
template <bool x> struct STATIC_ASSERTION_FAILURE; template <bool x> struct STATIC_ASSERTION_FAILURE;
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
@ -367,7 +394,9 @@ RAPIDJSON_NAMESPACE_END
#else #else
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif #endif
#ifndef __clang__
//!@endcond //!@endcond
#endif
/*! \def RAPIDJSON_STATIC_ASSERT /*! \def RAPIDJSON_STATIC_ASSERT
\brief (Internal) macro to check for conditions at compile-time \brief (Internal) macro to check for conditions at compile-time

View File

@ -39,6 +39,12 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
RAPIDJSON_DIAG_OFF(4702) // unreachable code RAPIDJSON_DIAG_OFF(4702) // unreachable code
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
RAPIDJSON_DIAG_OFF(switch-enum)
#endif
#ifdef __GNUC__ #ifdef __GNUC__
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
@ -263,7 +269,7 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
return p; return p;
// 16-byte align to the next boundary // 16-byte align to the next boundary
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15); const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
while (p != nextAligned) while (p != nextAligned)
if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
++p; ++p;
@ -272,11 +278,11 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
// The rest of string using SIMD // The rest of string using SIMD
static const char whitespace[16] = " \n\r\t"; static const char whitespace[16] = " \n\r\t";
const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]); const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
for (;; p += 16) { for (;; p += 16) {
const __m128i s = _mm_load_si128((const __m128i *)p); const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
if (r != 0) { // some of characters is non-whitespace if (r != 0) { // some of characters is non-whitespace
#ifdef _MSC_VER // Find the index of first non-whitespace #ifdef _MSC_VER // Find the index of first non-whitespace
unsigned long offset; unsigned long offset;
@ -300,7 +306,7 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
return p; return p;
// 16-byte align to the next boundary // 16-byte align to the next boundary
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15); const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
while (p != nextAligned) while (p != nextAligned)
if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
++p; ++p;
@ -314,18 +320,18 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
for (;; p += 16) { for (;; p += 16) {
const __m128i s = _mm_load_si128((const __m128i *)p); const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
__m128i x = _mm_cmpeq_epi8(s, w0); __m128i x = _mm_cmpeq_epi8(s, w0);
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
unsigned short r = (unsigned short)~_mm_movemask_epi8(x); unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
if (r != 0) { // some of characters may be non-whitespace if (r != 0) { // some of characters may be non-whitespace
#ifdef _MSC_VER // Find the index of first non-whitespace #ifdef _MSC_VER // Find the index of first non-whitespace
unsigned long offset; unsigned long offset;
@ -698,7 +704,7 @@ private:
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
size_t length = s.PutEnd(head) - 1; size_t length = s.PutEnd(head) - 1;
RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head; const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
} }
else { else {
@ -737,9 +743,8 @@ private:
if (c == '\\') { // Escape if (c == '\\') { // Escape
is.Take(); is.Take();
Ch e = is.Take(); Ch e = is.Take();
if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) { if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[static_cast<unsigned char>(e)])
os.Put(escape[(unsigned char)e]); os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
}
else if (e == 'u') { // Unicode else if (e == 'u') { // Unicode
unsigned codepoint = ParseHex4(is); unsigned codepoint = ParseHex4(is);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
@ -765,7 +770,7 @@ private:
} }
else if (c == '\0') else if (c == '\0')
RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF else if (static_cast<unsigned>(c) < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
else { else {
if (parseFlags & kParseValidateEncodingFlag ? if (parseFlags & kParseValidateEncodingFlag ?
@ -806,7 +811,7 @@ private:
~NumberStream() {} ~NumberStream() {}
RAPIDJSON_FORCEINLINE Ch TakePush() { RAPIDJSON_FORCEINLINE Ch TakePush() {
stackStream.Put((char)Base::is.Peek()); stackStream.Put(static_cast<char>(Base::is.Peek()));
return Base::is.Take(); return Base::is.Take();
} }
@ -937,10 +942,10 @@ private:
} }
} }
d = (double)i64; d = static_cast<double>(i64);
#else #else
// Use double to store significand in 32-bit architecture // Use double to store significand in 32-bit architecture
d = use64bit ? (double)i64 : (double)i; d = static_cast<double>(use64bit ? i64 : i);
#endif #endif
useDouble = true; useDouble = true;
} }
@ -977,10 +982,10 @@ private:
} }
if (s.Peek() >= '0' && s.Peek() <= '9') { if (s.Peek() >= '0' && s.Peek() <= '9') {
exp = s.Take() - '0'; exp = static_cast<int>(s.Take() - '0');
if (expMinus) { if (expMinus) {
while (s.Peek() >= '0' && s.Peek() <= '9') { while (s.Peek() >= '0' && s.Peek() <= '9') {
exp = exp * 10 + (s.Take() - '0'); exp = exp * 10 + static_cast<int>(s.Take() - '0');
if (exp >= 214748364) { // Issue #313: prevent overflow exponent if (exp >= 214748364) { // Issue #313: prevent overflow exponent
while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent
s.Take(); s.Take();
@ -990,7 +995,7 @@ private:
else { // positive exp else { // positive exp
int maxExp = 308 - expFrac; int maxExp = 308 - expFrac;
while (s.Peek() >= '0' && s.Peek() <= '9') { while (s.Peek() >= '0' && s.Peek() <= '9') {
exp = exp * 10 + (s.Take() - '0'); exp = exp * 10 + static_cast<int>(s.Take() - '0');
if (exp > maxExp) if (exp > maxExp)
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
} }
@ -1075,11 +1080,11 @@ private:
IterativeParsingArrayFinishState, IterativeParsingArrayFinishState,
// Single value state // Single value state
IterativeParsingValueState, IterativeParsingValueState
cIterativeParsingStateCount
}; };
enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
// Tokens // Tokens
enum Token { enum Token {
LeftBracketToken = 0, LeftBracketToken = 0,
@ -1121,8 +1126,8 @@ private:
#undef N16 #undef N16
//!@endcond //!@endcond
if (sizeof(Ch) == 1 || unsigned(c) < 256) if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
return (Token)tokenMap[(unsigned char)c]; return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
else else
return NumberToken; return NumberToken;
} }
@ -1288,7 +1293,7 @@ private:
} }
}; // End of G }; // End of G
return (IterativeParsingState)G[state][token]; return static_cast<IterativeParsingState>(G[state][token]);
} }
// Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
@ -1499,6 +1504,11 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
RAPIDJSON_NAMESPACE_END RAPIDJSON_NAMESPACE_END
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#ifdef __GNUC__ #ifdef __GNUC__
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif

View File

@ -23,15 +23,16 @@
#include "stringbuffer.h" #include "stringbuffer.h"
#include <new> // placement new #include <new> // placement new
#if RAPIDJSON_HAS_STDSTRING
#include <string>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
#endif
RAPIDJSON_NAMESPACE_BEGIN RAPIDJSON_NAMESPACE_BEGIN
//! JSON writer //! JSON writer
@ -205,7 +206,7 @@ protected:
char buffer[11]; char buffer[11];
const char* end = internal::i32toa(i, buffer); const char* end = internal::i32toa(i, buffer);
for (const char* p = buffer; p != end; ++p) for (const char* p = buffer; p != end; ++p)
os_->Put(*p); os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
return true; return true;
} }
@ -213,7 +214,7 @@ protected:
char buffer[10]; char buffer[10];
const char* end = internal::u32toa(u, buffer); const char* end = internal::u32toa(u, buffer);
for (const char* p = buffer; p != end; ++p) for (const char* p = buffer; p != end; ++p)
os_->Put(*p); os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
return true; return true;
} }
@ -221,7 +222,7 @@ protected:
char buffer[21]; char buffer[21];
const char* end = internal::i64toa(i64, buffer); const char* end = internal::i64toa(i64, buffer);
for (const char* p = buffer; p != end; ++p) for (const char* p = buffer; p != end; ++p)
os_->Put(*p); os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
return true; return true;
} }
@ -229,7 +230,7 @@ protected:
char buffer[20]; char buffer[20];
char* end = internal::u64toa(u64, buffer); char* end = internal::u64toa(u64, buffer);
for (char* p = buffer; p != end; ++p) for (char* p = buffer; p != end; ++p)
os_->Put(*p); os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
return true; return true;
} }
@ -237,12 +238,12 @@ protected:
char buffer[25]; char buffer[25];
char* end = internal::dtoa(d, buffer); char* end = internal::dtoa(d, buffer);
for (char* p = buffer; p != end; ++p) for (char* p = buffer; p != end; ++p)
os_->Put(*p); os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
return true; return true;
} }
bool WriteString(const Ch* str, SizeType length) { bool WriteString(const Ch* str, SizeType length) {
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static const char escape[256] = { static const char escape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
//0 1 2 3 4 5 6 7 8 9 A B C D E F //0 1 2 3 4 5 6 7 8 9 A B C D E F
@ -259,7 +260,7 @@ protected:
GenericStringStream<SourceEncoding> is(str); GenericStringStream<SourceEncoding> is(str);
while (is.Tell() < length) { while (is.Tell() < length) {
const Ch c = is.Peek(); const Ch c = is.Peek();
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) { if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
// Unicode escaping // Unicode escaping
unsigned codepoint; unsigned codepoint;
if (!SourceEncoding::Decode(is, &codepoint)) if (!SourceEncoding::Decode(is, &codepoint))
@ -290,15 +291,15 @@ protected:
os_->Put(hexDigits[(trail ) & 15]); os_->Put(hexDigits[(trail ) & 15]);
} }
} }
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) { else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && escape[static_cast<unsigned char>(c)]) {
is.Take(); is.Take();
os_->Put('\\'); os_->Put('\\');
os_->Put(escape[(unsigned char)c]); os_->Put(static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));
if (escape[(unsigned char)c] == 'u') { if (escape[static_cast<unsigned char>(c)] == 'u') {
os_->Put('0'); os_->Put('0');
os_->Put('0'); os_->Put('0');
os_->Put(hexDigits[(unsigned char)c >> 4]); os_->Put(hexDigits[static_cast<unsigned char>(c) >> 4]);
os_->Put(hexDigits[(unsigned char)c & 0xF]); os_->Put(hexDigits[static_cast<unsigned char>(c) & 0xF]);
} }
} }
else else
@ -392,4 +393,8 @@ RAPIDJSON_NAMESPACE_END
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_RAPIDJSON_H_ #endif // RAPIDJSON_RAPIDJSON_H_

View File

@ -9,7 +9,7 @@ IF(GTESTSRC_FOUND)
endif() endif()
add_subdirectory(${GTEST_SOURCE_DIR} ${CMAKE_BINARY_DIR}/googletest) add_subdirectory(${GTEST_SOURCE_DIR} ${CMAKE_BINARY_DIR}/googletest)
include_directories(${GTEST_INCLUDE_DIR}) include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
set(TEST_LIBRARIES gtest gtest_main) set(TEST_LIBRARIES gtest gtest_main)

View File

@ -21,7 +21,7 @@ set(UNITTEST_SOURCES
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
endif() endif()

View File

@ -22,21 +22,21 @@ template <typename Allocator>
void TestAllocator(Allocator& a) { void TestAllocator(Allocator& a) {
EXPECT_TRUE(a.Malloc(0) == 0); EXPECT_TRUE(a.Malloc(0) == 0);
uint8_t* p = (uint8_t*)a.Malloc(100); uint8_t* p = static_cast<uint8_t*>(a.Malloc(100));
EXPECT_TRUE(p != 0); EXPECT_TRUE(p != 0);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
p[i] = (uint8_t)i; p[i] = static_cast<uint8_t>(i);
// Expand // Expand
uint8_t* q = (uint8_t*)a.Realloc(p, 100, 200); uint8_t* q = static_cast<uint8_t*>(a.Realloc(p, 100, 200));
EXPECT_TRUE(q != 0); EXPECT_TRUE(q != 0);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
EXPECT_EQ(i, q[i]); EXPECT_EQ(i, q[i]);
for (size_t i = 100; i < 200; i++) for (size_t i = 100; i < 200; i++)
q[i] = (uint8_t)i; q[i] = static_cast<uint8_t>(i);
// Shrink // Shrink
uint8_t *r = (uint8_t*)a.Realloc(q, 200, 150); uint8_t *r = static_cast<uint8_t*>(a.Realloc(q, 200, 150));
EXPECT_TRUE(r != 0); EXPECT_TRUE(r != 0);
for (size_t i = 0; i < 150; i++) for (size_t i = 0; i < 150; i++)
EXPECT_EQ(i, r[i]); EXPECT_EQ(i, r[i]);
@ -56,7 +56,7 @@ TEST(Allocator, MemoryPoolAllocator) {
MemoryPoolAllocator<> a; MemoryPoolAllocator<> a;
TestAllocator(a); TestAllocator(a);
for (int i = 1; i < 1000; i++) { for (size_t i = 1; i < 1000; i++) {
EXPECT_TRUE(a.Malloc(i) != 0); EXPECT_TRUE(a.Malloc(i) != 0);
EXPECT_LE(a.Size(), a.Capacity()); EXPECT_LE(a.Size(), a.Capacity());
} }

View File

@ -28,7 +28,7 @@ void ParseCheck(DocumentType& doc) {
typedef typename DocumentType::ValueType ValueType; typedef typename DocumentType::ValueType ValueType;
EXPECT_FALSE(doc.HasParseError()); EXPECT_FALSE(doc.HasParseError());
EXPECT_TRUE((ParseResult)doc); EXPECT_TRUE(static_cast<ParseResult>(doc));
EXPECT_TRUE(doc.IsObject()); EXPECT_TRUE(doc.IsObject());
@ -63,8 +63,8 @@ void ParseCheck(DocumentType& doc) {
const ValueType& a = doc["a"]; const ValueType& a = doc["a"];
EXPECT_TRUE(a.IsArray()); EXPECT_TRUE(a.IsArray());
EXPECT_EQ(4u, a.Size()); EXPECT_EQ(4u, a.Size());
for (SizeType i = 0; i < 4; i++) for (SizeType j = 0; j < 4; j++)
EXPECT_EQ(i + 1, a[i].GetUint()); EXPECT_EQ(j + 1, a[j].GetUint());
} }
template <typename Allocator, typename StackAllocator> template <typename Allocator, typename StackAllocator>
@ -118,15 +118,15 @@ TEST(Document, UnchangedOnParseError) {
static FILE* OpenEncodedFile(const char* filename) { static FILE* OpenEncodedFile(const char* filename) {
const char *paths[] = { const char *paths[] = {
"encodings/%s", "encodings",
"bin/encodings/%s", "bin/encodings",
"../bin/encodings/%s", "../bin/encodings",
"../../bin/encodings/%s", "../../bin/encodings",
"../../../bin/encodings/%s" "../../../bin/encodings"
}; };
char buffer[1024]; char buffer[1024];
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
sprintf(buffer, paths[i], filename); sprintf(buffer, "%s/%s", paths[i], filename);
FILE *fp = fopen(buffer, "rb"); FILE *fp = fopen(buffer, "rb");
if (fp) if (fp)
return fp; return fp;
@ -157,22 +157,22 @@ TEST(Document, ParseStream_EncodedInputStream) {
StringBuffer bos; StringBuffer bos;
typedef EncodedOutputStream<UTF8<>, StringBuffer> OutputStream; typedef EncodedOutputStream<UTF8<>, StringBuffer> OutputStream;
OutputStream eos(bos, false); // Not writing BOM OutputStream eos(bos, false); // Not writing BOM
Writer<OutputStream, UTF16<>, UTF8<> > writer(eos);
d.Accept(writer);
{ {
// Condense the original file and compare. Writer<OutputStream, UTF16<>, UTF8<> > writer(eos);
FILE *fp = OpenEncodedFile("utf8.json"); d.Accept(writer);
FileReadStream is(fp, buffer, sizeof(buffer));
Reader reader;
StringBuffer bos2;
Writer<StringBuffer> writer(bos2);
reader.Parse(is, writer);
fclose(fp);
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
} }
// Condense the original file and compare.
fp = OpenEncodedFile("utf8.json");
FileReadStream is(fp, buffer, sizeof(buffer));
Reader reader;
StringBuffer bos2;
Writer<StringBuffer> writer2(bos2);
reader.Parse(is, writer2);
fclose(fp);
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
} }
TEST(Document, ParseStream_AutoUTFInputStream) { TEST(Document, ParseStream_AutoUTFInputStream) {
@ -199,19 +199,17 @@ TEST(Document, ParseStream_AutoUTFInputStream) {
Writer<StringBuffer> writer(bos); Writer<StringBuffer> writer(bos);
d.Accept(writer); d.Accept(writer);
{ // Condense the original file and compare.
// Condense the original file and compare. fp = OpenEncodedFile("utf8.json");
FILE *fp = OpenEncodedFile("utf8.json"); FileReadStream is(fp, buffer, sizeof(buffer));
FileReadStream is(fp, buffer, sizeof(buffer)); Reader reader;
Reader reader; StringBuffer bos2;
StringBuffer bos2; Writer<StringBuffer> writer2(bos2);
Writer<StringBuffer> writer(bos2); reader.Parse(is, writer2);
reader.Parse(is, writer); fclose(fp);
fclose(fp);
EXPECT_EQ(bos.GetSize(), bos2.GetSize()); EXPECT_EQ(bos.GetSize(), bos2.GetSize());
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize())); EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
}
} }
TEST(Document, Swap) { TEST(Document, Swap) {
@ -263,12 +261,16 @@ TEST(Document, Swap) {
struct OutputStringStream : public std::ostringstream { struct OutputStringStream : public std::ostringstream {
typedef char Ch; typedef char Ch;
virtual ~OutputStringStream();
void Put(char c) { void Put(char c) {
put(c); put(c);
} }
void Flush() {} void Flush() {}
}; };
OutputStringStream::~OutputStringStream() {}
TEST(Document, AcceptWriter) { TEST(Document, AcceptWriter) {
Document doc; Document doc;
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "); doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");

View File

@ -25,6 +25,7 @@ using namespace rapidjson;
class EncodedStreamTest : public ::testing::Test { class EncodedStreamTest : public ::testing::Test {
public: public:
EncodedStreamTest() : json_(), length_() {} EncodedStreamTest() : json_(), length_() {}
virtual ~EncodedStreamTest();
virtual void SetUp() { virtual void SetUp() {
json_ = ReadFile("utf8.json", true, &length_); json_ = ReadFile("utf8.json", true, &length_);
@ -42,15 +43,15 @@ private:
protected: protected:
static FILE* Open(const char* filename) { static FILE* Open(const char* filename) {
const char *paths[] = { const char *paths[] = {
"encodings/%s", "encodings",
"bin/encodings/%s", "bin/encodings",
"../bin/encodings/%s", "../bin/encodings",
"../../bin/encodings/%s", "../../bin/encodings",
"../../../bin/encodings/%s" "../../../bin/encodings"
}; };
char buffer[1024]; char buffer[1024];
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
sprintf(buffer, paths[i], filename); sprintf(buffer, "%s/%s", paths[i], filename);
FILE *fp = fopen(buffer, "rb"); FILE *fp = fopen(buffer, "rb");
if (fp) if (fp)
return fp; return fp;
@ -67,9 +68,9 @@ protected:
} }
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
*outLength = (size_t)ftell(fp); *outLength = static_cast<size_t>(ftell(fp));
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
char* buffer = (char*)malloc(*outLength + 1); char* buffer = static_cast<char*>(malloc(*outLength + 1));
size_t readLength = fread(buffer, 1, *outLength, fp); size_t readLength = fread(buffer, 1, *outLength, fp);
buffer[readLength] = '\0'; buffer[readLength] = '\0';
fclose(fp); fclose(fp);
@ -248,6 +249,8 @@ protected:
size_t length_; size_t length_;
}; };
EncodedStreamTest::~EncodedStreamTest() {}
TEST_F(EncodedStreamTest, EncodedInputStream) { TEST_F(EncodedStreamTest, EncodedInputStream) {
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8.json"); TestEncodedInputStream<UTF8<>, UTF8<> >("utf8.json");
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8bom.json"); TestEncodedInputStream<UTF8<>, UTF8<> >("utf8bom.json");

View File

@ -240,7 +240,6 @@ static const unsigned kCodepointRanges[] = {
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
#define UTF8_ACCEPT 0u #define UTF8_ACCEPT 0u
#define UTF8_REJECT 12u
static const unsigned char utf8d[] = { static const unsigned char utf8d[] = {
// The first part of the table maps bytes to character classes that // The first part of the table maps bytes to character classes that
@ -298,7 +297,7 @@ TEST(EncodingsTest, UTF8) {
unsigned decodedCount = 0; unsigned decodedCount = 0;
for (const char* s = encodedStr; *s; ++s) for (const char* s = encodedStr; *s; ++s)
if (!decode(&state, &decodedCodepoint, (unsigned char)*s)) { if (!decode(&state, &decodedCodepoint, static_cast<unsigned char>(*s))) {
EXPECT_EQ(codepoint, decodedCodepoint); EXPECT_EQ(codepoint, decodedCodepoint);
decodedCount++; decodedCount++;
} }
@ -355,7 +354,7 @@ TEST(EncodingsTest, UTF16) {
unsigned state = 0; unsigned state = 0;
UTF16<>::Ch buffer[3], *p = &buffer[0]; UTF16<>::Ch buffer[3], *p = &buffer[0];
for (const char* s = utf8os.GetString(); *s; ++s) { for (const char* s = utf8os.GetString(); *s; ++s) {
if (!decode(&state, &decodedCodepoint, (unsigned char)*s)) if (!decode(&state, &decodedCodepoint, static_cast<unsigned char>(*s)))
break; break;
} }

View File

@ -22,6 +22,7 @@ using namespace rapidjson;
class FileStreamTest : public ::testing::Test { class FileStreamTest : public ::testing::Test {
public: public:
FileStreamTest() : filename_(), json_(), length_() {} FileStreamTest() : filename_(), json_(), length_() {}
virtual ~FileStreamTest();
virtual void SetUp() { virtual void SetUp() {
const char *paths[] = { const char *paths[] = {
@ -42,9 +43,9 @@ public:
ASSERT_TRUE(fp != 0); ASSERT_TRUE(fp != 0);
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
length_ = (size_t)ftell(fp); length_ = static_cast<size_t>(ftell(fp));
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
json_ = (char*)malloc(length_ + 1); json_ = static_cast<char*>(malloc(length_ + 1));
size_t readLength = fread(json_, 1, length_, fp); size_t readLength = fread(json_, 1, length_, fp);
json_[readLength] = '\0'; json_[readLength] = '\0';
fclose(fp); fclose(fp);
@ -65,6 +66,8 @@ protected:
size_t length_; size_t length_;
}; };
FileStreamTest::~FileStreamTest() {}
TEST_F(FileStreamTest, FileReadStream) { TEST_F(FileStreamTest, FileReadStream) {
FILE *fp = fopen(filename_, "rb"); FILE *fp = fopen(filename_, "rb");
ASSERT_TRUE(fp != 0); ASSERT_TRUE(fp != 0);

View File

@ -30,28 +30,28 @@ template <>
struct Traits<uint32_t> { struct Traits<uint32_t> {
enum { kBufferSize = 11 }; enum { kBufferSize = 11 };
enum { kMaxDigit = 10 }; enum { kMaxDigit = 10 };
static uint32_t Negate(uint32_t x) { return x; }; static uint32_t Negate(uint32_t x) { return x; }
}; };
template <> template <>
struct Traits<int32_t> { struct Traits<int32_t> {
enum { kBufferSize = 12 }; enum { kBufferSize = 12 };
enum { kMaxDigit = 10 }; enum { kMaxDigit = 10 };
static int32_t Negate(int32_t x) { return -x; }; static int32_t Negate(int32_t x) { return -x; }
}; };
template <> template <>
struct Traits<uint64_t> { struct Traits<uint64_t> {
enum { kBufferSize = 21 }; enum { kBufferSize = 21 };
enum { kMaxDigit = 20 }; enum { kMaxDigit = 20 };
static uint64_t Negate(uint64_t x) { return x; }; static uint64_t Negate(uint64_t x) { return x; }
}; };
template <> template <>
struct Traits<int64_t> { struct Traits<int64_t> {
enum { kBufferSize = 22 }; enum { kBufferSize = 22 };
enum { kMaxDigit = 20 }; enum { kMaxDigit = 20 };
static int64_t Negate(int64_t x) { return -x; }; static int64_t Negate(int64_t x) { return -x; }
}; };
template <typename T> template <typename T>

View File

@ -20,16 +20,16 @@ using namespace rapidjson;
static char* ReadFile(const char* filename, size_t& length) { static char* ReadFile(const char* filename, size_t& length) {
const char *paths[] = { const char *paths[] = {
"jsonchecker/%s", "jsonchecker",
"bin/jsonchecker/%s", "bin/jsonchecker",
"../bin/jsonchecker/%s", "../bin/jsonchecker",
"../../bin/jsonchecker/%s", "../../bin/jsonchecker",
"../../../bin/jsonchecker/%s" "../../../bin/jsonchecker"
}; };
char buffer[1024]; char buffer[1024];
FILE *fp = 0; FILE *fp = 0;
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
sprintf(buffer, paths[i], filename); sprintf(buffer, "%s/%s", paths[i], filename);
fp = fopen(buffer, "rb"); fp = fopen(buffer, "rb");
if (fp) if (fp)
break; break;
@ -39,9 +39,9 @@ static char* ReadFile(const char* filename, size_t& length) {
return 0; return 0;
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
length = (size_t)ftell(fp); length = static_cast<size_t>(ftell(fp));
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
char* json = (char*)malloc(length + 1); char* json = static_cast<char*>(malloc(length + 1));
size_t readLength = fread(json, 1, length, fp); size_t readLength = fread(json, 1, length, fp);
json[readLength] = '\0'; json[readLength] = '\0';
fclose(fp); fclose(fp);
@ -68,10 +68,10 @@ TEST(JsonChecker, Reader) {
} }
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
document.Parse((const char*)json); document.Parse(json);
EXPECT_TRUE(document.HasParseError()); EXPECT_TRUE(document.HasParseError());
document.Parse<kParseIterativeFlag>((const char*)json); document.Parse<kParseIterativeFlag>(json);
EXPECT_TRUE(document.HasParseError()); EXPECT_TRUE(document.HasParseError());
free(json); free(json);
@ -88,10 +88,10 @@ TEST(JsonChecker, Reader) {
} }
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
document.Parse((const char*)json); document.Parse(json);
EXPECT_FALSE(document.HasParseError()); EXPECT_FALSE(document.HasParseError());
document.Parse<kParseIterativeFlag>((const char*)json); document.Parse<kParseIterativeFlag>(json);
EXPECT_FALSE(document.HasParseError()); EXPECT_FALSE(document.HasParseError());
free(json); free(json);

View File

@ -306,7 +306,7 @@ TEST(Pointer, Parse_URIFragment) {
GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2"); GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
EXPECT_TRUE(p.IsValid()); EXPECT_TRUE(p.IsValid());
EXPECT_EQ(1u, p.GetTokenCount()); EXPECT_EQ(1u, p.GetTokenCount());
EXPECT_EQ((UTF16<>::Ch)0x00A2, p.GetTokens()[0].name[0]); EXPECT_EQ(static_cast<UTF16<>::Ch>(0x00A2), p.GetTokens()[0].name[0]);
EXPECT_EQ(1u, p.GetTokens()[0].length); EXPECT_EQ(1u, p.GetTokens()[0].length);
} }
@ -315,7 +315,7 @@ TEST(Pointer, Parse_URIFragment) {
GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC"); GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
EXPECT_TRUE(p.IsValid()); EXPECT_TRUE(p.IsValid());
EXPECT_EQ(1u, p.GetTokenCount()); EXPECT_EQ(1u, p.GetTokenCount());
EXPECT_EQ((UTF16<>::Ch)0x20AC, p.GetTokens()[0].name[0]); EXPECT_EQ(static_cast<UTF16<>::Ch>(0x20AC), p.GetTokens()[0].name[0]);
EXPECT_EQ(1u, p.GetTokens()[0].length); EXPECT_EQ(1u, p.GetTokens()[0].length);
} }
@ -1488,6 +1488,6 @@ TEST(Pointer, Issue483) {
std::string mystr, path; std::string mystr, path;
myjson::Document document; myjson::Document document;
myjson::Value value(rapidjson::kStringType); myjson::Value value(rapidjson::kStringType);
value.SetString(mystr.c_str(), mystr.length(), document.GetAllocator()); value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator()); myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
} }

View File

@ -149,13 +149,13 @@ TEST(PrettyWriter, FileWriteStream) {
fp = fopen(filename, "rb"); fp = fopen(filename, "rb");
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size_t size = (size_t)ftell(fp); size_t size = static_cast<size_t>(ftell(fp));
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
char* json = (char*)malloc(size + 1); char* json = static_cast<char*>(malloc(size + 1));
size_t readLength = fread(json, 1, size, fp); size_t readLength = fread(json, 1, size, fp);
json[readLength] = '\0'; json[readLength] = '\0';
fclose(fp); fclose(fp);
remove(filename); remove(filename);
EXPECT_STREQ(kPrettyJson, json); EXPECT_STREQ(kPrettyJson, json);
free(json); free(json);
} }

View File

@ -25,6 +25,12 @@ using namespace rapidjson;
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
RAPIDJSON_DIAG_OFF(float-equal) RAPIDJSON_DIAG_OFF(float-equal)
RAPIDJSON_DIAG_OFF(missing-noreturn)
#endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(variadic-macros)
#endif #endif
template<bool expect> template<bool expect>
@ -159,12 +165,12 @@ TEST(Reader, ParseNumber_Integer) {
u.u |= r(); u.u |= r();
char buffer[32]; char buffer[32];
if (u.u >= 4294967296ULL) { if (u.u > uint64_t(4294967295u)) {
*internal::u64toa(u.u, buffer) = '\0'; *internal::u64toa(u.u, buffer) = '\0';
TEST_INTEGER(ParseUint64Handler, buffer, u.u); TEST_INTEGER(ParseUint64Handler, buffer, u.u);
} }
if (u.i <= -2147483649LL) { if (u.i < -int64_t(2147483648u)) {
*internal::i64toa(u.i, buffer) = '\0'; *internal::i64toa(u.i, buffer) = '\0';
TEST_INTEGER(ParseInt64Handler, buffer, u.i); TEST_INTEGER(ParseInt64Handler, buffer, u.i);
} }
@ -456,7 +462,7 @@ struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encod
bool String(const typename Encoding::Ch* str, size_t length, bool copy) { bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
EXPECT_EQ(0, str_); EXPECT_EQ(0, str_);
if (copy) { if (copy) {
str_ = (typename Encoding::Ch*)malloc((length + 1) * sizeof(typename Encoding::Ch)); str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch)); memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
} }
else else
@ -639,11 +645,11 @@ TEST(Reader, ParseString_Error) {
{ {
char e[] = { '[', '\"', 0, '\"', ']', '\0' }; char e[] = { '[', '\"', 0, '\"', ']', '\0' };
for (unsigned char c = 0x80u; c <= 0xBFu; c++) { for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
e[2] = c; e[2] = static_cast<char>(c);
ParseErrorCode error = TestString<UTF8<> >(e); ParseErrorCode error = TestString<UTF8<> >(e);
EXPECT_EQ(kParseErrorStringInvalidEncoding, error); EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
if (error != kParseErrorStringInvalidEncoding) if (error != kParseErrorStringInvalidEncoding)
std::cout << (unsigned)(unsigned char)c << std::endl; std::cout << static_cast<unsigned>(c) << std::endl;
} }
} }
@ -651,7 +657,7 @@ TEST(Reader, ParseString_Error) {
{ {
char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' }; char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
for (unsigned c = 0xC0u; c <= 0xFFu; c++) { for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
e[2] = (char)c; e[2] = static_cast<char>(c);
TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e); TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e);
} }
} }
@ -771,7 +777,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
default: ADD_FAILURE(); return false; default: ADD_FAILURE(); return false;
} }
} }
bool Uint(unsigned i) { return Int(i); } bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; } bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
bool String(const char* str, size_t, bool) { bool String(const char* str, size_t, bool) {
switch(step_) { switch(step_) {
@ -1024,15 +1030,15 @@ public:
Ch Peek() const { Ch Peek() const {
int c = is_.peek(); int c = is_.peek();
return c == std::char_traits<char>::eof() ? '\0' : (Ch)c; return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
} }
Ch Take() { Ch Take() {
int c = is_.get(); int c = is_.get();
return c == std::char_traits<char>::eof() ? '\0' : (Ch)c; return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
} }
size_t Tell() const { return (size_t)is_.tellg(); } size_t Tell() const { return static_cast<size_t>(is_.tellg()); }
Ch* PutBegin() { assert(false); return 0; } Ch* PutBegin() { assert(false); return 0; }
void Put(Ch) { assert(false); } void Put(Ch) { assert(false); }
@ -1143,7 +1149,7 @@ struct IterativeParsingReaderHandler {
bool EndObject(SizeType c) { bool EndObject(SizeType c) {
RAPIDJSON_ASSERT(LogCount < LogCapacity); RAPIDJSON_ASSERT(LogCount < LogCapacity);
Logs[LogCount++] = LOG_ENDOBJECT; Logs[LogCount++] = LOG_ENDOBJECT;
Logs[LogCount++] = (int)c; Logs[LogCount++] = static_cast<int>(c);
return true; return true;
} }
@ -1152,7 +1158,7 @@ struct IterativeParsingReaderHandler {
bool EndArray(SizeType c) { bool EndArray(SizeType c) {
RAPIDJSON_ASSERT(LogCount < LogCapacity); RAPIDJSON_ASSERT(LogCount < LogCapacity);
Logs[LogCount++] = LOG_ENDARRAY; Logs[LogCount++] = LOG_ENDARRAY;
Logs[LogCount++] = (int)c; Logs[LogCount++] = static_cast<int>(c);
return true; return true;
} }
}; };
@ -1455,3 +1461,7 @@ TEST(Reader, IncompleteMultilineComment) {
#ifdef __GNUC__ #ifdef __GNUC__
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif

View File

@ -41,7 +41,7 @@ using namespace rapidjson_simd;
template <typename StreamType> template <typename StreamType>
void TestSkipWhitespace() { void TestSkipWhitespace() {
for (int step = 1; step < 32; step++) { for (size_t step = 1; step < 32; step++) {
char buffer[1025]; char buffer[1025];
for (size_t i = 0; i < 1024; i++) for (size_t i = 0; i < 1024; i++)
buffer[i] = " \t\r\n"[i % 4]; buffer[i] = " \t\r\n"[i % 4];

View File

@ -16,6 +16,11 @@
#include "rapidjson/internal/strtod.h" #include "rapidjson/internal/strtod.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(unreachable-code)
#endif
#define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1) #define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
using namespace rapidjson::internal; using namespace rapidjson::internal;
@ -99,13 +104,13 @@ TEST(Strtod, CheckApproximationCase) {
EXPECT_EQ(49, hS_Exp5); EXPECT_EQ(49, hS_Exp5);
BigInteger dS = BIGINTEGER_LITERAL(dInt); BigInteger dS = BIGINTEGER_LITERAL(dInt);
dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2; dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<size_t>(dS_Exp2);
BigInteger bS(bInt); BigInteger bS(bInt);
bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2; bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<size_t>(bS_Exp2);
BigInteger hS(1); BigInteger hS(1);
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2; hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<size_t>(hS_Exp2);
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994138521801764465966248930731085529088") == dS); EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994138521801764465966248930731085529088") == dS);
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994122305215569213032722473144531250000") == bS); EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994122305215569213032722473144531250000") == bS);
@ -121,3 +126,7 @@ TEST(Strtod, CheckApproximationCase) {
EXPECT_EQ(-1, delta.Compare(hS)); EXPECT_EQ(-1, delta.Compare(hS));
} }
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif

View File

@ -15,12 +15,14 @@
#include "unittest.h" #include "unittest.h"
#include "rapidjson/rapidjson.h" #include "rapidjson/rapidjson.h"
AssertException::~AssertException() throw() {}
int main(int argc, char **argv) { int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
std::cout << "RapidJSON v" << RAPIDJSON_VERSION_STRING << std::endl; std::cout << "RapidJSON v" << RAPIDJSON_VERSION_STRING << std::endl;
#if _MSC_VER #ifdef _MSC_VER
_CrtMemState memoryState = { 0 }; _CrtMemState memoryState = { 0 };
_CrtMemCheckpoint(&memoryState); _CrtMemCheckpoint(&memoryState);
//_CrtSetBreakAlloc(X); //_CrtSetBreakAlloc(X);
@ -29,7 +31,7 @@ int main(int argc, char **argv) {
int ret = RUN_ALL_TESTS(); int ret = RUN_ALL_TESTS();
#if _MSC_VER #ifdef _MSC_VER
// Current gtest constantly leak 2 blocks at exit // Current gtest constantly leak 2 blocks at exit
_CrtMemDumpAllObjectsSince(&memoryState); _CrtMemDumpAllObjectsSince(&memoryState);
#endif #endif

View File

@ -15,10 +15,20 @@
#ifndef UNITTEST_H_ #ifndef UNITTEST_H_
#define UNITTEST_H_ #define UNITTEST_H_
// gtest indirectly included inttypes.h, without __STDC_CONSTANT_MACROS. // gtest indirectly included inttypes.h, without __STDC_CONSTANT_MACROS.
#ifndef __STDC_CONSTANT_MACROS #ifndef __STDC_CONSTANT_MACROS
#ifdef __clang__
#pragma GCC diagnostic push
#if __has_warning("-Wreserved-id-macro")
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
#endif
#endif
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard # define __STDC_CONSTANT_MACROS 1 // required by C++ standard
#ifdef __clang__
#pragma GCC diagnostic pop
#endif
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
@ -41,6 +51,11 @@
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#ifdef __clang__
// All TEST() macro generated this warning, disable globally
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#endif
template <typename Ch> template <typename Ch>
inline unsigned StrLen(const Ch* s) { inline unsigned StrLen(const Ch* s) {
const Ch* p = s; const Ch* p = s;
@ -51,19 +66,19 @@ inline unsigned StrLen(const Ch* s) {
template<typename Ch> template<typename Ch>
inline int StrCmp(const Ch* s1, const Ch* s2) { inline int StrCmp(const Ch* s1, const Ch* s2) {
while(*s1 && (*s1 == *s2)) { s1++; s2++; } while(*s1 && (*s1 == *s2)) { s1++; s2++; }
return (unsigned)*s1 < (unsigned)*s2 ? -1 : (unsigned)*s1 > (unsigned)*s2; return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
} }
template <typename Ch> template <typename Ch>
inline Ch* StrDup(const Ch* str) { inline Ch* StrDup(const Ch* str) {
size_t bufferSize = sizeof(Ch) * (StrLen(str) + 1); size_t bufferSize = sizeof(Ch) * (StrLen(str) + 1);
Ch* buffer = (Ch*)malloc(bufferSize); Ch* buffer = static_cast<Ch*>(malloc(bufferSize));
memcpy(buffer, str, bufferSize); memcpy(buffer, str, bufferSize);
return buffer; return buffer;
} }
inline FILE* TempFile(char *filename) { inline FILE* TempFile(char *filename) {
#if _MSC_VER #ifdef _MSC_VER
filename = tmpnam(filename); filename = tmpnam(filename);
// For Visual Studio, tmpnam() adds a backslash in front. Remove it. // For Visual Studio, tmpnam() adds a backslash in front. Remove it.
@ -80,13 +95,14 @@ inline FILE* TempFile(char *filename) {
} }
// Use exception for catching assert // Use exception for catching assert
#if _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4127) #pragma warning(disable : 4127)
#endif #endif
class AssertException : public std::logic_error { class AssertException : public std::logic_error {
public: public:
AssertException(const char* w) : std::logic_error(w) {} AssertException(const char* w) : std::logic_error(w) {}
virtual ~AssertException() throw();
}; };
#define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x)) #define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x))

View File

@ -448,7 +448,7 @@ TEST(Value, Uint) {
TEST(Value, Int64) { TEST(Value, Int64) {
// Constructor with int // Constructor with int
Value x(int64_t(1234LL)); Value x(int64_t(1234));
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt()); EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
@ -469,7 +469,7 @@ TEST(Value, Int64) {
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
Value nx(int64_t(-1234LL)); Value nx(int64_t(-1234));
EXPECT_EQ(-1234, nx.GetInt()); EXPECT_EQ(-1234, nx.GetInt());
EXPECT_EQ(-1234, nx.GetInt64()); EXPECT_EQ(-1234, nx.GetInt64());
EXPECT_TRUE(nx.IsInt()); EXPECT_TRUE(nx.IsInt());
@ -482,17 +482,17 @@ TEST(Value, Int64) {
z.SetInt64(1234); z.SetInt64(1234);
EXPECT_EQ(1234, z.GetInt64()); EXPECT_EQ(1234, z.GetInt64());
z.SetInt64(2147483648LL); // 2^31, cannot cast as int z.SetInt64(2147483648u); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint()); EXPECT_TRUE(z.IsUint());
EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0); EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
z.SetInt64(4294967296LL); // 2^32, cannot cast as uint z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint()); EXPECT_FALSE(z.IsUint());
EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0); EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
z.SetInt64(-2147483649LL); // -2^31-1, cannot cast as int z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0); EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
@ -502,7 +502,7 @@ TEST(Value, Int64) {
TEST(Value, Uint64) { TEST(Value, Uint64) {
// Constructor with int // Constructor with int
Value x(uint64_t(1234LL)); Value x(uint64_t(1234));
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt()); EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
@ -528,19 +528,19 @@ TEST(Value, Uint64) {
z.SetUint64(1234); z.SetUint64(1234);
EXPECT_EQ(1234u, z.GetUint64()); EXPECT_EQ(1234u, z.GetUint64());
z.SetUint64(2147483648LL); // 2^31, cannot cast as int z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint()); EXPECT_TRUE(z.IsUint());
EXPECT_TRUE(z.IsInt64()); EXPECT_TRUE(z.IsInt64());
z.SetUint64(4294967296LL); // 2^32, cannot cast as uint z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint()); EXPECT_FALSE(z.IsUint());
EXPECT_TRUE(z.IsInt64()); EXPECT_TRUE(z.IsInt64());
z.SetUint64(9223372036854775808uLL); // 2^63 cannot cast as int64 z.SetUint64(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)); // 2^63 cannot cast as int64
EXPECT_FALSE(z.IsInt64()); EXPECT_FALSE(z.IsInt64());
EXPECT_EQ(9223372036854775808uLL, z.GetUint64()); // Issue 48 EXPECT_EQ(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000), z.GetUint64()); // Issue 48
EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble()); EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
} }
@ -662,7 +662,7 @@ TEST(Value, String) {
// SetString() // SetString()
char s[] = "World"; char s[] = "World";
Value w; Value w;
w.SetString(s, (SizeType)strlen(s), allocator); w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
s[0] = '\0'; s[0] = '\0';
EXPECT_STREQ("World", w.GetString()); EXPECT_STREQ("World", w.GetString());
EXPECT_EQ(5u, w.GetStringLength()); EXPECT_EQ(5u, w.GetStringLength());
@ -841,23 +841,23 @@ TEST(Value, Array) {
EXPECT_EQ(x.Begin(), itr); EXPECT_EQ(x.Begin(), itr);
EXPECT_EQ(9u, x.Size()); EXPECT_EQ(9u, x.Size());
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Ease the last // Ease the last
itr = x.Erase(x.End() - 1); itr = x.Erase(x.End() - 1);
EXPECT_EQ(x.End(), itr); EXPECT_EQ(x.End(), itr);
EXPECT_EQ(8u, x.Size()); EXPECT_EQ(8u, x.Size());
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Erase the middle // Erase the middle
itr = x.Erase(x.Begin() + 4); itr = x.Erase(x.Begin() + 4);
EXPECT_EQ(x.Begin() + 4, itr); EXPECT_EQ(x.Begin() + 4, itr);
EXPECT_EQ(7u, x.Size()); EXPECT_EQ(7u, x.Size());
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
for (int i = 4; i < 7; i++) for (int i = 4; i < 7; i++)
EXPECT_EQ(i + 2, x[i][0].GetInt()); EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
// Erase(ValueIterator, ValueIterator) // Erase(ValueIterator, ValueIterator)
// Exhaustive test with all 0 <= first < n, first <= last <= n cases // Exhaustive test with all 0 <= first < n, first <= last <= n cases
@ -879,7 +879,7 @@ TEST(Value, Array) {
for (unsigned i = 0; i < first; i++) for (unsigned i = 0; i < first; i++)
EXPECT_EQ(i, x[i][0].GetUint()); EXPECT_EQ(i, x[i][0].GetUint());
for (unsigned i = first; i < n - removeCount; i++) for (unsigned i = first; i < n - removeCount; i++)
EXPECT_EQ(i + removeCount, x[i][0].GetUint()); EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
} }
} }
@ -896,7 +896,7 @@ TEST(Value, Array) {
x.Erase(std::remove(x.Begin(), x.End(), null), x.End()); x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
EXPECT_EQ(5u, x.Size()); EXPECT_EQ(5u, x.Size());
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
EXPECT_EQ(i * 2, x[i]); EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
// SetArray() // SetArray()
Value z; Value z;
@ -935,8 +935,8 @@ TEST(Value, Object) {
o.AddMember("false", false, allocator); o.AddMember("false", false, allocator);
o.AddMember("int", -1, allocator); o.AddMember("int", -1, allocator);
o.AddMember("uint", 1u, allocator); o.AddMember("uint", 1u, allocator);
o.AddMember("int64", INT64_C(-4294967296), allocator); o.AddMember("int64", int64_t(-4294967296), allocator);
o.AddMember("uint64", UINT64_C(4294967296), allocator); o.AddMember("uint64", uint64_t(4294967296), allocator);
o.AddMember("double", 3.14, allocator); o.AddMember("double", 3.14, allocator);
o.AddMember("string", "Jelly", allocator); o.AddMember("string", "Jelly", allocator);
@ -944,8 +944,8 @@ TEST(Value, Object) {
EXPECT_FALSE(o["false"].GetBool()); EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt()); EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint()); EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(INT64_C(-4294967296), o["int64"].GetInt64()); EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
EXPECT_EQ(UINT64_C(4294967296), o["uint64"].GetUint64()); EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
EXPECT_STREQ("Jelly",o["string"].GetString()); EXPECT_STREQ("Jelly",o["string"].GetString());
EXPECT_EQ(8u, o.MemberCount()); EXPECT_EQ(8u, o.MemberCount());
} }
@ -1125,7 +1125,7 @@ TEST(Value, Object) {
EXPECT_EQ(x.MemberBegin(), itr); EXPECT_EQ(x.MemberBegin(), itr);
EXPECT_EQ(9u, x.MemberCount()); EXPECT_EQ(9u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()) + 1; size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
@ -1136,7 +1136,7 @@ TEST(Value, Object) {
EXPECT_EQ(x.MemberEnd(), itr); EXPECT_EQ(x.MemberEnd(), itr);
EXPECT_EQ(8u, x.MemberCount()); EXPECT_EQ(8u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()) + 1; size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
@ -1147,8 +1147,8 @@ TEST(Value, Object) {
EXPECT_EQ(x.MemberBegin() + 4, itr); EXPECT_EQ(x.MemberBegin() + 4, itr);
EXPECT_EQ(7u, x.MemberCount()); EXPECT_EQ(7u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()); size_t i = static_cast<size_t>(itr - x.MemberBegin());
i += (i<4) ? 1 : 2; i += (i < 4) ? 1 : 2;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
@ -1162,11 +1162,11 @@ TEST(Value, Object) {
for (unsigned i = 0; i < n; i++) for (unsigned i = 0; i < n; i++)
x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator); x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
itr = x.EraseMember(x.MemberBegin() + first, x.MemberBegin() + last); itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
if (last == n) if (last == n)
EXPECT_EQ(x.MemberEnd(), itr); EXPECT_EQ(x.MemberEnd(), itr);
else else
EXPECT_EQ(x.MemberBegin() + first, itr); EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
size_t removeCount = last - first; size_t removeCount = last - first;
EXPECT_EQ(n - removeCount, x.MemberCount()); EXPECT_EQ(n - removeCount, x.MemberCount());
@ -1214,7 +1214,7 @@ TEST(Value, BigNestedArray) {
for (SizeType i = 0; i < n; i++) { for (SizeType i = 0; i < n; i++) {
Value y(kArrayType); Value y(kArrayType);
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
Value number((int)(i * n + j)); Value number(static_cast<int>(i * n + j));
y.PushBack(number, allocator); y.PushBack(number, allocator);
} }
x.PushBack(y, allocator); x.PushBack(y, allocator);
@ -1223,7 +1223,7 @@ TEST(Value, BigNestedArray) {
for (SizeType i = 0; i < n; i++) for (SizeType i = 0; i < n; i++)
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
EXPECT_TRUE(x[i][j].IsInt()); EXPECT_TRUE(x[i][j].IsInt());
EXPECT_EQ((int)(i * n + j), x[i][j].GetInt()); EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
} }
} }
@ -1237,16 +1237,16 @@ TEST(Value, BigNestedObject) {
sprintf(name1, "%d", i); sprintf(name1, "%d", i);
// Value name(name1); // should not compile // Value name(name1); // should not compile
Value name(name1, (SizeType)strlen(name1), allocator); Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
Value object(kObjectType); Value object(kObjectType);
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
char name2[10]; char name2[10];
sprintf(name2, "%d", j); sprintf(name2, "%d", j);
Value name(name2, (SizeType)strlen(name2), allocator); Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
Value number((int)(i * n + j)); Value number(static_cast<int>(i * n + j));
object.AddMember(name, number, allocator); object.AddMember(name3, number, allocator);
} }
// x.AddMember(name1, object, allocator); // should not compile // x.AddMember(name1, object, allocator); // should not compile
@ -1261,7 +1261,7 @@ TEST(Value, BigNestedObject) {
char name2[10]; char name2[10];
sprintf(name2, "%d", j); sprintf(name2, "%d", j);
x[name1]; x[name1];
EXPECT_EQ((int)(i * n + j), x[name1][name2].GetInt()); EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
} }
} }
} }
@ -1293,7 +1293,7 @@ TEST(Document, CrtAllocator) {
} }
static void TestShortStringOptimization(const char* str) { static void TestShortStringOptimization(const char* str) {
const rapidjson::SizeType len = (rapidjson::SizeType)strlen(str); const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
rapidjson::Document doc; rapidjson::Document doc;
rapidjson::Value val; rapidjson::Value val;