summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJsonCpp Upstream <kwrobot@kitware.com>2022-01-12 21:27:16 (GMT)
committerBrad King <brad.king@kitware.com>2022-01-12 22:04:04 (GMT)
commit7a72ab3388c5f439070167fbcefd1cbdd776be9f (patch)
treefc850608b0ff8c8f7c165c2f4756f67c7bc47fc5
parent0b9765051855ece984fa83154d063b7cc7b62c1d (diff)
downloadCMake-7a72ab3388c5f439070167fbcefd1cbdd776be9f.zip
CMake-7a72ab3388c5f439070167fbcefd1cbdd776be9f.tar.gz
CMake-7a72ab3388c5f439070167fbcefd1cbdd776be9f.tar.bz2
jsoncpp 2022-01-12 (42e892d9)
Code extracted from: https://github.com/open-source-parsers/jsoncpp.git at commit 42e892d96e47b1f6e29844cc705e148ec4856448 (42e892d96e47b1f6e29844cc705e148ec4856448).
-rw-r--r--LICENSE14
-rw-r--r--include/json/allocator.h10
-rw-r--r--include/json/json_features.h3
-rw-r--r--include/json/reader.h13
-rw-r--r--include/json/value.h21
-rw-r--r--include/json/version.h4
-rw-r--r--include/json/writer.h17
-rw-r--r--src/lib_json/json_reader.cpp25
-rw-r--r--src/lib_json/json_tool.h10
-rw-r--r--src/lib_json/json_value.cpp26
-rw-r--r--src/lib_json/json_writer.cpp43
11 files changed, 105 insertions, 81 deletions
diff --git a/LICENSE b/LICENSE
index 89280a6..c41a1d1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,25 +1,25 @@
-The JsonCpp library's source code, including accompanying documentation,
+The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
-jurisdictions which recognize such a disclaimer. In such jurisdictions,
+Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-In jurisdictions which recognize Public Domain property, the user of this
-software may choose to accept it either as 1) Public Domain, 2) under the
-conditions of the MIT License (see below), or 3) under the terms of dual
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
Public Domain/MIT License conditions described here, as they choose.
The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:
http://en.wikipedia.org/wiki/MIT_License
-
+
The full text of the MIT License follows:
========================================================================
diff --git a/include/json/allocator.h b/include/json/allocator.h
index 0f5c224..7540642 100644
--- a/include/json/allocator.h
+++ b/include/json/allocator.h
@@ -9,7 +9,8 @@
#include <cstring>
#include <memory>
-#pragma pack(push, 8)
+#pragma pack(push)
+#pragma pack()
namespace Json {
template <typename T> class SecureAllocator {
@@ -35,11 +36,10 @@ public:
* Release memory which was allocated for N items at pointer P.
*
* The memory block is filled with zeroes before being released.
- * The pointer argument is tagged as "volatile" to prevent the
- * compiler optimizing out this critical step.
*/
- void deallocate(volatile pointer p, size_type n) {
- std::memset(p, 0, n * sizeof(T));
+ void deallocate(pointer p, size_type n) {
+ // memset_s is used because memset may be optimized away by the compiler
+ memset_s(p, n * sizeof(T), 0, n * sizeof(T));
// free using "global operator delete"
::operator delete(p);
}
diff --git a/include/json/json_features.h b/include/json/json_features.h
index 7c7e9f5..e4a61d6 100644
--- a/include/json/json_features.h
+++ b/include/json/json_features.h
@@ -10,7 +10,8 @@
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
-#pragma pack(push, 8)
+#pragma pack(push)
+#pragma pack()
namespace Json {
diff --git a/include/json/reader.h b/include/json/reader.h
index 9175466..46975d8 100644
--- a/include/json/reader.h
+++ b/include/json/reader.h
@@ -23,7 +23,8 @@
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma pack(push, 8)
+#pragma pack(push)
+#pragma pack()
namespace Json {
@@ -33,8 +34,7 @@ namespace Json {
* \deprecated Use CharReader and CharReaderBuilder.
*/
-class JSONCPP_DEPRECATED(
- "Use CharReader and CharReaderBuilder instead.") JSON_API Reader {
+class JSON_API Reader {
public:
using Char = char;
using Location = const Char*;
@@ -51,13 +51,13 @@ public:
};
/** \brief Constructs a Reader allowing all features for parsing.
+ * \deprecated Use CharReader and CharReaderBuilder.
*/
- JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
Reader();
/** \brief Constructs a Reader allowing the specified feature set for parsing.
+ * \deprecated Use CharReader and CharReaderBuilder.
*/
- JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
Reader(const Features& features);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
@@ -324,6 +324,9 @@ public:
* - `"allowSpecialFloats": false or true`
* - If true, special float values (NaNs and infinities) are allowed and
* their values are lossfree restorable.
+ * - `"skipBom": false or true`
+ * - If true, if the input starts with the Unicode byte order mark (BOM),
+ * it is skipped.
*
* You can examine 'settings_` yourself to see the defaults. You can also
* write and read them just like any JSON Value.
diff --git a/include/json/value.h b/include/json/value.h
index df1eba6..57ecb13 100644
--- a/include/json/value.h
+++ b/include/json/value.h
@@ -50,10 +50,11 @@
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
-#pragma warning(disable : 4251)
+#pragma warning(disable : 4251 4275)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma pack(push, 8)
+#pragma pack(push)
+#pragma pack()
/** \brief JSON (JavaScript Object Notation).
*/
@@ -263,10 +264,10 @@ private:
CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
- CZString(CZString&& other);
+ CZString(CZString&& other) noexcept;
~CZString();
CZString& operator=(const CZString& other);
- CZString& operator=(CZString&& other);
+ CZString& operator=(CZString&& other) noexcept;
bool operator<(CZString const& other) const;
bool operator==(CZString const& other) const;
@@ -344,13 +345,13 @@ public:
Value(bool value);
Value(std::nullptr_t ptr) = delete;
Value(const Value& other);
- Value(Value&& other);
+ Value(Value&& other) noexcept;
~Value();
/// \note Overwrite existing comments. To preserve comments, use
/// #swapPayload().
Value& operator=(const Value& other);
- Value& operator=(Value&& other);
+ Value& operator=(Value&& other) noexcept;
/// Swap everything.
void swap(Value& other);
@@ -635,9 +636,9 @@ private:
public:
Comments() = default;
Comments(const Comments& that);
- Comments(Comments&& that);
+ Comments(Comments&& that) noexcept;
Comments& operator=(const Comments& that);
- Comments& operator=(Comments&& that);
+ Comments& operator=(Comments&& that) noexcept;
bool has(CommentPlacement slot) const;
String get(CommentPlacement slot) const;
void set(CommentPlacement slot, String comment);
@@ -918,8 +919,8 @@ public:
* because the returned references/pointers can be used
* to change state of the base class.
*/
- reference operator*() { return deref(); }
- pointer operator->() { return &deref(); }
+ reference operator*() const { return const_cast<reference>(deref()); }
+ pointer operator->() const { return const_cast<pointer>(&deref()); }
};
inline void swap(Value& a, Value& b) { a.swap(b); }
diff --git a/include/json/version.h b/include/json/version.h
index 5b9783d..e931d03 100644
--- a/include/json/version.h
+++ b/include/json/version.h
@@ -9,10 +9,10 @@
// 3. /CMakeLists.txt
// IMPORTANT: also update the SOVERSION!!
-#define JSONCPP_VERSION_STRING "1.9.4"
+#define JSONCPP_VERSION_STRING "1.9.5"
#define JSONCPP_VERSION_MAJOR 1
#define JSONCPP_VERSION_MINOR 9
-#define JSONCPP_VERSION_PATCH 3
+#define JSONCPP_VERSION_PATCH 5
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
diff --git a/include/json/writer.h b/include/json/writer.h
index fb0852a..7d8cf4d 100644
--- a/include/json/writer.h
+++ b/include/json/writer.h
@@ -20,7 +20,8 @@
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma pack(push, 8)
+#pragma pack(push)
+#pragma pack()
namespace Json {
@@ -110,6 +111,8 @@ public:
* - Number of precision digits for formatting of real values.
* - "precisionType": "significant"(default) or "decimal"
* - Type of precision for formatting of real values.
+ * - "emitUTF8": false or true
+ * - If true, outputs raw UTF8 strings instead of escaping them.
* You can examine 'settings_` yourself
* to see the defaults. You can also write and read them just like any
@@ -145,7 +148,7 @@ public:
/** \brief Abstract class for writers.
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/
-class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
+class JSON_API Writer {
public:
virtual ~Writer();
@@ -165,7 +168,7 @@ public:
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
+class JSON_API FastWriter
: public Writer {
public:
FastWriter();
@@ -215,7 +218,7 @@ private:
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
- * If the Value have comments then they are outputed according to their
+ * If the Value have comments then they are outputted according to their
*#CommentPlacement.
*
* \sa Reader, Value, Value::setComment()
@@ -225,7 +228,7 @@ private:
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
+class JSON_API
StyledWriter : public Writer {
public:
StyledWriter();
@@ -284,7 +287,7 @@ private:
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
- * If the Value have comments then they are outputed according to their
+ * If the Value have comments then they are outputted according to their
#CommentPlacement.
*
* \sa Reader, Value, Value::setComment()
@@ -294,7 +297,7 @@ private:
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
+class JSON_API
StyledStreamWriter {
public:
/**
diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp
index 19922a8..1ac5e81 100644
--- a/src/lib_json/json_reader.cpp
+++ b/src/lib_json/json_reader.cpp
@@ -12,6 +12,7 @@
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <algorithm>
#include <cassert>
+#include <cmath>
#include <cstring>
#include <iostream>
#include <istream>
@@ -104,8 +105,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) {
// Since String is reference-counted, this at least does not
// create an extra copy.
- String doc;
- std::getline(is, doc, static_cast<char> EOF);
+ String doc(std::istreambuf_iterator<char>(is), {});
return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
}
@@ -601,9 +601,15 @@ bool Reader::decodeDouble(Token& token, Value& decoded) {
double value = 0;
String buffer(token.start_, token.end_);
IStringStream is(buffer);
- if (!(is >> value))
- return addError(
+ if (!(is >> value)) {
+ if (value == std::numeric_limits<double>::max())
+ value = std::numeric_limits<double>::infinity();
+ else if (value == std::numeric_limits<double>::lowest())
+ value = -std::numeric_limits<double>::infinity();
+ else if (!std::isinf(value))
+ return addError(
"'" + String(token.start_, token.end_) + "' is not a number.", token);
+ }
decoded = value;
return true;
}
@@ -1608,7 +1614,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
const auto digit(static_cast<Value::UInt>(c - '0'));
if (value >= threshold) {
// We've hit or exceeded the max value divided by 10 (rounded down). If
- // a) we've only just touched the limit, meaing value == threshold,
+ // a) we've only just touched the limit, meaning value == threshold,
// b) this is the last digit, or
// c) it's small enough to fit in that rounding delta, we're okay.
// Otherwise treat this number as a double to avoid overflow.
@@ -1648,7 +1654,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) {
const String buffer(token.start_, token.end_);
IStringStream is(buffer);
if (!(is >> value)) {
- return addError(
+ if (value == std::numeric_limits<double>::max())
+ value = std::numeric_limits<double>::infinity();
+ else if (value == std::numeric_limits<double>::lowest())
+ value = -std::numeric_limits<double>::infinity();
+ else if (!std::isinf(value))
+ return addError(
"'" + String(token.start_, token.end_) + "' is not a number.", token);
}
decoded = value;
@@ -1921,7 +1932,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const {
if (valid_keys.count(key))
continue;
if (invalid)
- (*invalid)[std::move(key)] = *si;
+ (*invalid)[key] = *si;
else
return false;
}
diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h
index 2d7b7d9..b952c19 100644
--- a/src/lib_json/json_tool.h
+++ b/src/lib_json/json_tool.h
@@ -116,14 +116,18 @@ template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
* Return iterator that would be the new end of the range [begin,end), if we
* were to delete zeros in the end of string, but not the last zero before '.'.
*/
-template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
+template <typename Iter>
+Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
for (; begin != end; --end) {
if (*(end - 1) != '0') {
return end;
}
// Don't delete the last zero before the decimal point.
- if (begin != (end - 1) && *(end - 2) == '.') {
- return end;
+ if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') {
+ if (precision) {
+ return end;
+ }
+ return end - 2;
}
}
return end;
diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp
index 0872ff5..aa2b744 100644
--- a/src/lib_json/json_value.cpp
+++ b/src/lib_json/json_value.cpp
@@ -259,7 +259,7 @@ Value::CZString::CZString(const CZString& other) {
storage_.length_ = other.storage_.length_;
}
-Value::CZString::CZString(CZString&& other)
+Value::CZString::CZString(CZString&& other) noexcept
: cstr_(other.cstr_), index_(other.index_) {
other.cstr_ = nullptr;
}
@@ -285,7 +285,7 @@ Value::CZString& Value::CZString::operator=(const CZString& other) {
return *this;
}
-Value::CZString& Value::CZString::operator=(CZString&& other) {
+Value::CZString& Value::CZString::operator=(CZString&& other) noexcept {
cstr_ = other.cstr_;
index_ = other.index_;
other.cstr_ = nullptr;
@@ -433,7 +433,7 @@ Value::Value(const Value& other) {
dupMeta(other);
}
-Value::Value(Value&& other) {
+Value::Value(Value&& other) noexcept {
initBasic(nullValue);
swap(other);
}
@@ -448,7 +448,7 @@ Value& Value::operator=(const Value& other) {
return *this;
}
-Value& Value::operator=(Value&& other) {
+Value& Value::operator=(Value&& other) noexcept {
other.swap(*this);
return *this;
}
@@ -912,7 +912,8 @@ void Value::resize(ArrayIndex newSize) {
if (newSize == 0)
clear();
else if (newSize > oldSize)
- this->operator[](newSize - 1);
+ for (ArrayIndex i = oldSize; i < newSize; ++i)
+ (*this)[i];
else {
for (ArrayIndex index = newSize; index < oldSize; ++index) {
value_.map_->erase(index);
@@ -1373,14 +1374,15 @@ bool Value::isObject() const { return type() == objectValue; }
Value::Comments::Comments(const Comments& that)
: ptr_{cloneUnique(that.ptr_)} {}
-Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {}
+Value::Comments::Comments(Comments&& that) noexcept
+ : ptr_{std::move(that.ptr_)} {}
Value::Comments& Value::Comments::operator=(const Comments& that) {
ptr_ = cloneUnique(that.ptr_);
return *this;
}
-Value::Comments& Value::Comments::operator=(Comments&& that) {
+Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
ptr_ = std::move(that.ptr_);
return *this;
}
@@ -1396,13 +1398,11 @@ String Value::Comments::get(CommentPlacement slot) const {
}
void Value::Comments::set(CommentPlacement slot, String comment) {
- if (!ptr_) {
+ if (slot >= CommentPlacement::numberOfCommentPlacement)
+ return;
+ if (!ptr_)
ptr_ = std::unique_ptr<Array>(new Array());
- }
- // check comments array boundry.
- if (slot < CommentPlacement::numberOfCommentPlacement) {
- (*ptr_)[slot] = std::move(comment);
- }
+ (*ptr_)[slot] = std::move(comment);
}
void Value::setComment(String comment, CommentPlacement placement) {
diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp
index 8bf02db..0dd160e 100644
--- a/src/lib_json/json_writer.cpp
+++ b/src/lib_json/json_writer.cpp
@@ -68,7 +68,7 @@
#if !defined(isnan)
// IEEE standard states that NaN values will not compare to themselves
-#define isnan(x) (x != x)
+#define isnan(x) ((x) != (x))
#endif
#if !defined(__APPLE__)
@@ -154,16 +154,18 @@ String valueToString(double value, bool useSpecialFloats,
buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
- // strip the zero padding from the right
- if (precisionType == PrecisionType::decimalPlaces) {
- buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
- }
-
// try to ensure we preserve the fact that this was given to us as a double on
// input
if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
buffer += ".0";
}
+
+ // strip the zero padding from the right
+ if (precisionType == PrecisionType::decimalPlaces) {
+ buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision),
+ buffer.end());
+ }
+
return buffer;
}
} // namespace
@@ -270,7 +272,7 @@ static void appendHex(String& result, unsigned ch) {
result.append("\\u").append(toHex16Bit(ch));
}
-static String valueToQuotedStringN(const char* value, unsigned length,
+static String valueToQuotedStringN(const char* value, size_t length,
bool emitUTF8 = false) {
if (value == nullptr)
return "";
@@ -348,7 +350,7 @@ static String valueToQuotedStringN(const char* value, unsigned length,
}
String valueToQuotedString(const char* value) {
- return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value)));
+ return valueToQuotedStringN(value, strlen(value));
}
// Class Writer
@@ -397,7 +399,7 @@ void FastWriter::writeValue(const Value& value) {
char const* end;
bool ok = value.getString(&str, &end);
if (ok)
- document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));
+ document_ += valueToQuotedStringN(str, static_cast<size_t>(end - str));
break;
}
case booleanValue:
@@ -420,8 +422,7 @@ void FastWriter::writeValue(const Value& value) {
const String& name = *it;
if (it != members.begin())
document_ += ',';
- document_ += valueToQuotedStringN(name.data(),
- static_cast<unsigned>(name.length()));
+ document_ += valueToQuotedStringN(name.data(), name.length());
document_ += yamlCompatibilityEnabled_ ? ": " : ":";
writeValue(value[name]);
}
@@ -466,7 +467,7 @@ void StyledWriter::writeValue(const Value& value) {
char const* end;
bool ok = value.getString(&str, &end);
if (ok)
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
+ pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str)));
else
pushValue("");
break;
@@ -507,7 +508,7 @@ void StyledWriter::writeValue(const Value& value) {
}
void StyledWriter::writeArrayValue(const Value& value) {
- unsigned size = value.size();
+ size_t size = value.size();
if (size == 0)
pushValue("[]");
else {
@@ -516,7 +517,7 @@ void StyledWriter::writeArrayValue(const Value& value) {
writeWithIndent("[");
indent();
bool hasChildValue = !childValues_.empty();
- unsigned index = 0;
+ ArrayIndex index = 0;
for (;;) {
const Value& childValue = value[index];
writeCommentBeforeValue(childValue);
@@ -539,7 +540,7 @@ void StyledWriter::writeArrayValue(const Value& value) {
{
assert(childValues_.size() == size);
document_ += "[ ";
- for (unsigned index = 0; index < size; ++index) {
+ for (size_t index = 0; index < size; ++index) {
if (index > 0)
document_ += ", ";
document_ += childValues_[index];
@@ -684,7 +685,7 @@ void StyledStreamWriter::writeValue(const Value& value) {
char const* end;
bool ok = value.getString(&str, &end);
if (ok)
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
+ pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str)));
else
pushValue("");
break;
@@ -958,8 +959,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
char const* end;
bool ok = value.getString(&str, &end);
if (ok)
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str),
- emitUTF8_));
+ pushValue(
+ valueToQuotedStringN(str, static_cast<size_t>(end - str), emitUTF8_));
else
pushValue("");
break;
@@ -982,8 +983,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
String const& name = *it;
Value const& childValue = value[name];
writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedStringN(
- name.data(), static_cast<unsigned>(name.length()), emitUTF8_));
+ writeWithIndent(
+ valueToQuotedStringN(name.data(), name.length(), emitUTF8_));
*sout_ << colonSymbol_;
writeValue(childValue);
if (++it == members.end()) {
@@ -1217,7 +1218,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const {
if (valid_keys.count(key))
continue;
if (invalid)
- (*invalid)[std::move(key)] = *si;
+ (*invalid)[key] = *si;
else
return false;
}