Merge topic 'update-jsoncpp'
af65a5d98b Merge branch 'upstream-jsoncpp' into update-jsoncpp
6a4aca62f6 jsoncpp 2024-09-09 (89e2973c)
3dec83ae8c jsoncpp: Update script to get jsoncpp 1.9.6
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !10379
diff --git a/Utilities/Scripts/update-jsoncpp.bash b/Utilities/Scripts/update-jsoncpp.bash
index a05dcb8..5e97f9e 100755
--- a/Utilities/Scripts/update-jsoncpp.bash
+++ b/Utilities/Scripts/update-jsoncpp.bash
@@ -8,7 +8,7 @@
readonly ownership="JsonCpp Upstream <kwrobot@kitware.com>"
readonly subtree="Utilities/cmjsoncpp"
readonly repo="https://github.com/open-source-parsers/jsoncpp.git"
-readonly tag="42e892d96e47b1f6e29844cc705e148ec4856448"
+readonly tag="1.9.6"
readonly shortlog=false
readonly paths="
LICENSE
diff --git a/Utilities/cmjsoncpp/include/json/allocator.h b/Utilities/cmjsoncpp/include/json/allocator.h
index 3718df1..eda2677 100644
--- a/Utilities/cmjsoncpp/include/json/allocator.h
+++ b/Utilities/cmjsoncpp/include/json/allocator.h
@@ -71,7 +71,9 @@
// Boilerplate
SecureAllocator() {}
template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
- template <typename U> struct rebind { using other = SecureAllocator<U>; };
+ template <typename U> struct rebind {
+ using other = SecureAllocator<U>;
+ };
};
template <typename T, typename U>
diff --git a/Utilities/cmjsoncpp/include/json/reader.h b/Utilities/cmjsoncpp/include/json/reader.h
index 0d444ad..a79d0ea 100644
--- a/Utilities/cmjsoncpp/include/json/reader.h
+++ b/Utilities/cmjsoncpp/include/json/reader.h
@@ -53,12 +53,12 @@
};
/** \brief Constructs a Reader allowing all features for parsing.
- * deprecated Use CharReader and CharReaderBuilder.
+ * deprecated Use CharReader and CharReaderBuilder.
*/
Reader();
/** \brief Constructs a Reader allowing the specified feature set for parsing.
- * deprecated Use CharReader and CharReaderBuilder.
+ * deprecated Use CharReader and CharReaderBuilder.
*/
Reader(const Features& features);
@@ -192,6 +192,7 @@
using Errors = std::deque<ErrorInfo>;
bool readToken(Token& token);
+ bool readTokenSkippingComments(Token& token);
void skipSpaces();
bool match(const Char* pattern, int patternLength);
bool readComment();
@@ -223,7 +224,6 @@
int& column) const;
String getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
- void skipCommentTokens(Token& token);
static bool containsNewLine(Location begin, Location end);
static String normalizeEOL(Location begin, Location end);
@@ -246,6 +246,12 @@
*/
class JSON_API CharReader {
public:
+ struct JSON_API StructuredError {
+ ptrdiff_t offset_start;
+ ptrdiff_t offset_limit;
+ String message;
+ };
+
virtual ~CharReader() = default;
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document. The document must be a UTF-8 encoded string containing the
@@ -264,7 +270,12 @@
* error occurred.
*/
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
- String* errs) = 0;
+ String* errs);
+
+ /** \brief Returns a vector of structured errors encountered while parsing.
+ * Each parse call resets the stored list of errors.
+ */
+ std::vector<StructuredError> getStructuredErrors() const;
class JSON_API Factory {
public:
@@ -274,7 +285,21 @@
*/
virtual CharReader* newCharReader() const = 0;
}; // Factory
-}; // CharReader
+
+protected:
+ class Impl {
+ public:
+ virtual ~Impl() = default;
+ virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
+ String* errs) = 0;
+ virtual std::vector<StructuredError> getStructuredErrors() const = 0;
+ };
+
+ explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}
+
+private:
+ std::unique_ptr<Impl> _impl;
+}; // CharReader
/** \brief Build a CharReader implementation.
*
@@ -362,6 +387,12 @@
* snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
*/
static void strictMode(Json::Value* settings);
+ /** ECMA-404 mode.
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode
+ */
+ static void ecma404Mode(Json::Value* settings);
};
/** Consume entire stream and use its begin/end.
diff --git a/Utilities/cmjsoncpp/include/json/value.h b/Utilities/cmjsoncpp/include/json/value.h
index 421fef8..da78869 100644
--- a/Utilities/cmjsoncpp/include/json/value.h
+++ b/Utilities/cmjsoncpp/include/json/value.h
@@ -3,8 +3,8 @@
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-#ifndef JSON_H_INCLUDED
-#define JSON_H_INCLUDED
+#ifndef JSON_VALUE_H_INCLUDED
+#define JSON_VALUE_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
@@ -443,7 +443,7 @@
/// \post type() is arrayValue
void resize(ArrayIndex newSize);
- //@{
+ ///@{
/// Access an array element (zero based index). If the array contains less
/// than index element, then null value are inserted in the array so that
/// its size is index+1.
@@ -451,15 +451,15 @@
/// this from the operator[] which takes a string.)
Value& operator[](ArrayIndex index);
Value& operator[](int index);
- //@}
+ ///@}
- //@{
+ ///@{
/// Access an array element (zero based index).
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
- //@}
+ ///@}
/// If the array contains at least index+1 elements, returns the element
/// value, otherwise returns defaultValue.
@@ -519,6 +519,9 @@
/// and operator[]const
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
Value const* find(char const* begin, char const* end) const;
+ /// Most general and efficient version of isMember()const, get()const,
+ /// and operator[]const
+ Value const* find(const String& key) const;
/// Most general and efficient version of object-mutators.
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
/// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
@@ -591,6 +594,26 @@
iterator begin();
iterator end();
+ /// \brief Returns a reference to the first element in the `Value`.
+ /// Requires that this value holds an array or json object, with at least one
+ /// element.
+ const Value& front() const;
+
+ /// \brief Returns a reference to the first element in the `Value`.
+ /// Requires that this value holds an array or json object, with at least one
+ /// element.
+ Value& front();
+
+ /// \brief Returns a reference to the last element in the `Value`.
+ /// Requires that value holds an array or json object, with at least one
+ /// element.
+ const Value& back() const;
+
+ /// \brief Returns a reference to the last element in the `Value`.
+ /// Requires that this value holds an array or json object, with at least one
+ /// element.
+ Value& back();
+
// Accessors for the [start, limit) range of bytes within the JSON text from
// which this value was parsed, if any.
void setOffsetStart(ptrdiff_t start);
@@ -931,6 +954,14 @@
inline void swap(Value& a, Value& b) { a.swap(b); }
+inline const Value& Value::front() const { return *begin(); }
+
+inline Value& Value::front() { return *begin(); }
+
+inline const Value& Value::back() const { return *(--end()); }
+
+inline Value& Value::back() { return *(--end()); }
+
} // namespace Json
#if !defined(__SUNPRO_CC)
diff --git a/Utilities/cmjsoncpp/include/json/version.h b/Utilities/cmjsoncpp/include/json/version.h
index e931d03..38faedf 100644
--- a/Utilities/cmjsoncpp/include/json/version.h
+++ b/Utilities/cmjsoncpp/include/json/version.h
@@ -9,19 +9,18 @@
// 3. /CMakeLists.txt
// IMPORTANT: also update the SOVERSION!!
-#define JSONCPP_VERSION_STRING "1.9.5"
+#define JSONCPP_VERSION_STRING "1.9.6"
#define JSONCPP_VERSION_MAJOR 1
#define JSONCPP_VERSION_MINOR 9
-#define JSONCPP_VERSION_PATCH 5
+#define JSONCPP_VERSION_PATCH 6
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
-#ifdef JSONCPP_USING_SECURE_MEMORY
-#undef JSONCPP_USING_SECURE_MEMORY
-#endif
+#if !defined(JSONCPP_USE_SECURE_MEMORY)
#define JSONCPP_USING_SECURE_MEMORY 0
+#endif
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
diff --git a/Utilities/cmjsoncpp/include/json/writer.h b/Utilities/cmjsoncpp/include/json/writer.h
index 2a47d5e..fac86c7 100644
--- a/Utilities/cmjsoncpp/include/json/writer.h
+++ b/Utilities/cmjsoncpp/include/json/writer.h
@@ -66,7 +66,7 @@
*/
virtual StreamWriter* newStreamWriter() const = 0;
}; // Factory
-}; // StreamWriter
+}; // StreamWriter
/** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted.
@@ -170,8 +170,7 @@
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSON_API FastWriter
- : public Writer {
+class JSON_API FastWriter : public Writer {
public:
FastWriter();
~FastWriter() override = default;
@@ -230,8 +229,7 @@
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSON_API
- StyledWriter : public Writer {
+class JSON_API StyledWriter : public Writer {
public:
StyledWriter();
~StyledWriter() override = default;
@@ -299,8 +297,7 @@
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSON_API
- StyledStreamWriter {
+class JSON_API StyledStreamWriter {
public:
/**
* \param indentation Each level will be indented by this amount extra.
@@ -356,6 +353,7 @@
PrecisionType precisionType = PrecisionType::significantDigits);
String JSON_API valueToString(bool value);
String JSON_API valueToQuotedString(const char* value);
+String JSON_API valueToQuotedString(const char* value, size_t length);
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
index 5cc718d..c504bfb 100644
--- a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
+++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
@@ -129,7 +129,7 @@
bool successful = readValue();
Token token;
- skipCommentTokens(token);
+ readTokenSkippingComments(token);
if (collectComments_ && !commentsBefore_.empty())
root.setComment(commentsBefore_, commentAfter);
if (features_.strictRoot_) {
@@ -157,7 +157,7 @@
throwRuntimeError("Exceeded stackLimit in readValue().");
Token token;
- skipCommentTokens(token);
+ readTokenSkippingComments(token);
bool successful = true;
if (collectComments_ && !commentsBefore_.empty()) {
@@ -225,14 +225,14 @@
return successful;
}
-void Reader::skipCommentTokens(Token& token) {
+bool Reader::readTokenSkippingComments(Token& token) {
+ bool success = readToken(token);
if (features_.allowComments_) {
- do {
- readToken(token);
- } while (token.type_ == tokenComment);
- } else {
- readToken(token);
+ while (success && token.type_ == tokenComment) {
+ success = readToken(token);
+ }
}
+ return success;
}
bool Reader::readToken(Token& token) {
@@ -446,12 +446,7 @@
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(token.start_ - begin_);
- while (readToken(tokenName)) {
- bool initialTokenOk = true;
- while (tokenName.type_ == tokenComment && initialTokenOk)
- initialTokenOk = readToken(tokenName);
- if (!initialTokenOk)
- break;
+ while (readTokenSkippingComments(tokenName)) {
if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
return true;
name.clear();
@@ -480,15 +475,11 @@
return recoverFromError(tokenObjectEnd);
Token comma;
- if (!readToken(comma) ||
- (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
- comma.type_ != tokenComment)) {
+ if (!readTokenSkippingComments(comma) ||
+ (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
return addErrorAndRecover("Missing ',' or '}' in object declaration",
comma, tokenObjectEnd);
}
- bool finalizeTokenOk = true;
- while (comma.type_ == tokenComment && finalizeTokenOk)
- finalizeTokenOk = readToken(comma);
if (comma.type_ == tokenObjectEnd)
return true;
}
@@ -518,10 +509,7 @@
Token currentToken;
// Accept Comment after last item in the array.
- ok = readToken(currentToken);
- while (currentToken.type_ == tokenComment && ok) {
- ok = readToken(currentToken);
- }
+ ok = readTokenSkippingComments(currentToken);
bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
currentToken.type_ != tokenArrayEnd);
if (!ok || badTokenType) {
@@ -599,8 +587,7 @@
bool Reader::decodeDouble(Token& token, Value& decoded) {
double value = 0;
- String buffer(token.start_, token.end_);
- IStringStream is(buffer);
+ IStringStream is(String(token.start_, token.end_));
if (!(is >> value)) {
if (value == std::numeric_limits<double>::max())
value = std::numeric_limits<double>::infinity();
@@ -608,7 +595,7 @@
value = -std::numeric_limits<double>::infinity();
else if (!std::isinf(value))
return addError(
- "'" + String(token.start_, token.end_) + "' is not a number.", token);
+ "'" + String(token.start_, token.end_) + "' is not a number.", token);
}
decoded = value;
return true;
@@ -773,7 +760,7 @@
while (current < location && current != end_) {
Char c = *current++;
if (c == '\r') {
- if (*current == '\n')
+ if (current != end_ && *current == '\n')
++current;
lastLineStart = current;
++line;
@@ -890,17 +877,12 @@
public:
using Char = char;
using Location = const Char*;
- struct StructuredError {
- ptrdiff_t offset_start;
- ptrdiff_t offset_limit;
- String message;
- };
explicit OurReader(OurFeatures const& features);
bool parse(const char* beginDoc, const char* endDoc, Value& root,
bool collectComments = true);
String getFormattedErrorMessages() const;
- std::vector<StructuredError> getStructuredErrors() const;
+ std::vector<CharReader::StructuredError> getStructuredErrors() const;
private:
OurReader(OurReader const&); // no impl
@@ -943,6 +925,7 @@
using Errors = std::deque<ErrorInfo>;
bool readToken(Token& token);
+ bool readTokenSkippingComments(Token& token);
void skipSpaces();
void skipBom(bool skipBom);
bool match(const Char* pattern, int patternLength);
@@ -976,7 +959,6 @@
int& column) const;
String getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
- void skipCommentTokens(Token& token);
static String normalizeEOL(Location begin, Location end);
static bool containsNewLine(Location begin, Location end);
@@ -1030,7 +1012,7 @@
bool successful = readValue();
nodes_.pop();
Token token;
- skipCommentTokens(token);
+ readTokenSkippingComments(token);
if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) {
addError("Extra non-whitespace after JSON value.", token);
return false;
@@ -1058,7 +1040,7 @@
if (nodes_.size() > features_.stackLimit_)
throwRuntimeError("Exceeded stackLimit in readValue().");
Token token;
- skipCommentTokens(token);
+ readTokenSkippingComments(token);
bool successful = true;
if (collectComments_ && !commentsBefore_.empty()) {
@@ -1145,14 +1127,14 @@
return successful;
}
-void OurReader::skipCommentTokens(Token& token) {
+bool OurReader::readTokenSkippingComments(Token& token) {
+ bool success = readToken(token);
if (features_.allowComments_) {
- do {
- readToken(token);
- } while (token.type_ == tokenComment);
- } else {
- readToken(token);
+ while (success && token.type_ == tokenComment) {
+ success = readToken(token);
+ }
}
+ return success;
}
bool OurReader::readToken(Token& token) {
@@ -1449,12 +1431,7 @@
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(token.start_ - begin_);
- while (readToken(tokenName)) {
- bool initialTokenOk = true;
- while (tokenName.type_ == tokenComment && initialTokenOk)
- initialTokenOk = readToken(tokenName);
- if (!initialTokenOk)
- break;
+ while (readTokenSkippingComments(tokenName)) {
if (tokenName.type_ == tokenObjectEnd &&
(name.empty() ||
features_.allowTrailingCommas_)) // empty object or trailing comma
@@ -1491,15 +1468,11 @@
return recoverFromError(tokenObjectEnd);
Token comma;
- if (!readToken(comma) ||
- (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
- comma.type_ != tokenComment)) {
+ if (!readTokenSkippingComments(comma) ||
+ (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
return addErrorAndRecover("Missing ',' or '}' in object declaration",
comma, tokenObjectEnd);
}
- bool finalizeTokenOk = true;
- while (comma.type_ == tokenComment && finalizeTokenOk)
- finalizeTokenOk = readToken(comma);
if (comma.type_ == tokenObjectEnd)
return true;
}
@@ -1533,10 +1506,7 @@
Token currentToken;
// Accept Comment after last item in the array.
- ok = readToken(currentToken);
- while (currentToken.type_ == tokenComment && ok) {
- ok = readToken(currentToken);
- }
+ ok = readTokenSkippingComments(currentToken);
bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
currentToken.type_ != tokenArrayEnd);
if (!ok || badTokenType) {
@@ -1651,8 +1621,7 @@
bool OurReader::decodeDouble(Token& token, Value& decoded) {
double value = 0;
- const String buffer(token.start_, token.end_);
- IStringStream is(buffer);
+ IStringStream is(String(token.start_, token.end_));
if (!(is >> value)) {
if (value == std::numeric_limits<double>::max())
value = std::numeric_limits<double>::infinity();
@@ -1660,7 +1629,7 @@
value = -std::numeric_limits<double>::infinity();
else if (!std::isinf(value))
return addError(
- "'" + String(token.start_, token.end_) + "' is not a number.", token);
+ "'" + String(token.start_, token.end_) + "' is not a number.", token);
}
decoded = value;
return true;
@@ -1826,7 +1795,7 @@
while (current < location && current != end_) {
Char c = *current++;
if (c == '\r') {
- if (*current == '\n')
+ if (current != end_ && *current == '\n')
++current;
lastLineStart = current;
++line;
@@ -1861,10 +1830,11 @@
return formattedMessage;
}
-std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
- std::vector<OurReader::StructuredError> allErrors;
+std::vector<CharReader::StructuredError>
+OurReader::getStructuredErrors() const {
+ std::vector<CharReader::StructuredError> allErrors;
for (const auto& error : errors_) {
- OurReader::StructuredError structured;
+ CharReader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
structured.offset_limit = error.token_.end_ - begin_;
structured.message = error.message_;
@@ -1874,20 +1844,36 @@
}
class OurCharReader : public CharReader {
- bool const collectComments_;
- OurReader reader_;
public:
OurCharReader(bool collectComments, OurFeatures const& features)
- : collectComments_(collectComments), reader_(features) {}
- bool parse(char const* beginDoc, char const* endDoc, Value* root,
- String* errs) override {
- bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
- if (errs) {
- *errs = reader_.getFormattedErrorMessages();
+ : CharReader(
+ std::unique_ptr<OurImpl>(new OurImpl(collectComments, features))) {}
+
+protected:
+ class OurImpl : public Impl {
+ public:
+ OurImpl(bool collectComments, OurFeatures const& features)
+ : collectComments_(collectComments), reader_(features) {}
+
+ bool parse(char const* beginDoc, char const* endDoc, Value* root,
+ String* errs) override {
+ bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
+ if (errs) {
+ *errs = reader_.getFormattedErrorMessages();
+ }
+ return ok;
}
- return ok;
- }
+
+ std::vector<CharReader::StructuredError>
+ getStructuredErrors() const override {
+ return reader_.getStructuredErrors();
+ }
+
+ private:
+ bool const collectComments_;
+ OurReader reader_;
+ };
};
CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
@@ -1976,6 +1962,32 @@
(*settings)["skipBom"] = true;
//! [CharReaderBuilderDefaults]
}
+// static
+void CharReaderBuilder::ecma404Mode(Json::Value* settings) {
+ //! [CharReaderBuilderECMA404Mode]
+ (*settings)["allowComments"] = false;
+ (*settings)["allowTrailingCommas"] = false;
+ (*settings)["strictRoot"] = false;
+ (*settings)["allowDroppedNullPlaceholders"] = false;
+ (*settings)["allowNumericKeys"] = false;
+ (*settings)["allowSingleQuotes"] = false;
+ (*settings)["stackLimit"] = 1000;
+ (*settings)["failIfExtra"] = true;
+ (*settings)["rejectDupKeys"] = false;
+ (*settings)["allowSpecialFloats"] = false;
+ (*settings)["skipBom"] = false;
+ //! [CharReaderBuilderECMA404Mode]
+}
+
+std::vector<CharReader::StructuredError>
+CharReader::getStructuredErrors() const {
+ return _impl->getStructuredErrors();
+}
+
+bool CharReader::parse(char const* beginDoc, char const* endDoc, Value* root,
+ String* errs) {
+ return _impl->parse(beginDoc, endDoc, root, errs);
+}
//////////////////////////////////
// global functions
@@ -1984,7 +1996,7 @@
String* errs) {
OStringStream ssin;
ssin << sin.rdbuf();
- String doc = ssin.str();
+ String doc = std::move(ssin).str();
char const* begin = doc.data();
char const* end = begin + doc.size();
// Note that we do not actually need a null-terminator.
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
index b496ddf..ec7ae70 100644
--- a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
+++ b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
@@ -1092,6 +1092,9 @@
return nullptr;
return &(*it).second;
}
+Value const* Value::find(const String& key) const {
+ return find(key.data(), key.data() + key.length());
+}
Value* Value::demand(char const* begin, char const* end) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
"in Json::Value::demand(begin, end): requires "
@@ -1105,7 +1108,7 @@
return *found;
}
Value const& Value::operator[](const String& key) const {
- Value const* found = find(key.data(), key.data() + key.length());
+ Value const* found = find(key);
if (!found)
return nullSingleton();
return *found;
@@ -1205,7 +1208,7 @@
return false;
}
if (removed)
- *removed = it->second;
+ *removed = std::move(it->second);
ArrayIndex oldSize = size();
// shift left all items left, into the place of the "removed"
for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
@@ -1410,9 +1413,8 @@
// Always discard trailing newline, to aid indentation.
comment.pop_back();
}
- JSON_ASSERT(!comment.empty());
JSON_ASSERT_MESSAGE(
- comment[0] == '\0' || comment[0] == '/',
+ comment.empty() || comment[0] == '/',
"in Json::Value::setComment(): Comments must start with /");
comments_.set(placement, std::move(comment));
}
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
index 0dd160e..ee45c43 100644
--- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
+++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
@@ -132,8 +132,9 @@
if (!isfinite(value)) {
static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"},
{"null", "-1e+9999", "1e+9999"}};
- return reps[useSpecialFloats ? 0 : 1]
- [isnan(value) ? 0 : (value < 0) ? 1 : 2];
+ return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0
+ : (value < 0) ? 1
+ : 2];
}
String buffer(size_t(36), '\0');
@@ -353,6 +354,10 @@
return valueToQuotedStringN(value, strlen(value));
}
+String valueToQuotedString(const char* value, size_t length) {
+ return valueToQuotedStringN(value, length);
+}
+
// Class Writer
// //////////////////////////////////////////////////////////////////
Writer::~Writer() = default;
@@ -490,7 +495,7 @@
const String& name = *it;
const Value& childValue = value[name];
writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedString(name.c_str()));
+ writeWithIndent(valueToQuotedString(name.c_str(), name.size()));
document_ += " : ";
writeValue(childValue);
if (++it == members.end()) {
@@ -708,7 +713,7 @@
const String& name = *it;
const Value& childValue = value[name];
writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedString(name.c_str()));
+ writeWithIndent(valueToQuotedString(name.c_str(), name.size()));
*document_ << " : ";
writeValue(childValue);
if (++it == members.end()) {
@@ -1246,7 +1251,7 @@
OStringStream sout;
StreamWriterPtr const writer(factory.newStreamWriter());
writer->write(root, &sout);
- return sout.str();
+ return std::move(sout).str();
}
OStream& operator<<(OStream& sout, Value const& root) {