mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-06 13:41:35 +01:00
Disambiguate GenericValue's [0] and ["string"]
This commit is contained in:
parent
0d90bcc709
commit
7303d92990
@ -72,12 +72,8 @@ int main(int, char*[]) {
|
||||
for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
|
||||
printf("a[%d] = %d\n", i, a[i].GetInt());
|
||||
|
||||
// Note:
|
||||
//int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type.
|
||||
int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work.
|
||||
int z = a[0u].GetInt(); // This works too.
|
||||
int y = a[0].GetInt();
|
||||
(void)y;
|
||||
(void)z;
|
||||
|
||||
// Iterating array with iterators
|
||||
printf("a = ");
|
||||
|
@ -795,6 +795,15 @@ public:
|
||||
//! Check whether the object is empty.
|
||||
bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
|
||||
|
||||
template <typename T>
|
||||
GenericValue& operator[](T t) {
|
||||
return DoIndex(t, internal::IsPointer<T>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const GenericValue& operator[](T t) const { return const_cast<GenericValue&>(*this)[t]; }
|
||||
|
||||
private:
|
||||
//! Get the value associated with the name.
|
||||
/*!
|
||||
\note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
|
||||
@ -803,12 +812,22 @@ public:
|
||||
A better approach is to use FindMember().
|
||||
\note Linear time complexity.
|
||||
*/
|
||||
GenericValue& operator[](const Ch* name) {
|
||||
|
||||
GenericValue& DoIndex(const Ch* name, internal::TrueType) {
|
||||
GenericValue n(StringRef(name));
|
||||
return (*this)[n];
|
||||
}
|
||||
const GenericValue& operator[](const Ch* name) const { return const_cast<GenericValue&>(*this)[name]; }
|
||||
|
||||
//! Get an element from array by index.
|
||||
/*! \param index Zero-based index of element.
|
||||
*/
|
||||
GenericValue& DoIndex(SizeType index, internal::FalseType) {
|
||||
RAPIDJSON_ASSERT(IsArray());
|
||||
RAPIDJSON_ASSERT(index < data_.a.size);
|
||||
return data_.a.elements[index];
|
||||
}
|
||||
|
||||
public:
|
||||
// This version is faster because it does not need a StrLen().
|
||||
// It can also handle string with null character.
|
||||
template <typename SourceAllocator>
|
||||
@ -1131,23 +1150,6 @@ public:
|
||||
data_.a.size = 0;
|
||||
}
|
||||
|
||||
//! Get an element from array by index.
|
||||
/*! \param index Zero-based index of element.
|
||||
\code
|
||||
Value a(kArrayType);
|
||||
a.PushBack(123);
|
||||
int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type.
|
||||
int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work.
|
||||
int z = a[0u].GetInt(); // This works too.
|
||||
\endcode
|
||||
*/
|
||||
GenericValue& operator[](SizeType index) {
|
||||
RAPIDJSON_ASSERT(IsArray());
|
||||
RAPIDJSON_ASSERT(index < data_.a.size);
|
||||
return data_.a.elements[index];
|
||||
}
|
||||
const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
|
||||
|
||||
//! Element iterator
|
||||
/*! \pre IsArray() == true */
|
||||
ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
|
||||
|
@ -218,7 +218,7 @@ TEST(Document, UTF16_Document) {
|
||||
json.Parse<kParseValidateEncodingFlag>(L"[{\"created_at\":\"Wed Oct 30 17:13:20 +0000 2012\"}]");
|
||||
|
||||
ASSERT_TRUE(json.IsArray());
|
||||
GenericValue< UTF16<> >& v = json[0u];
|
||||
GenericValue< UTF16<> >& v = json[0];
|
||||
ASSERT_TRUE(v.IsObject());
|
||||
|
||||
GenericValue< UTF16<> >& s = v[L"created_at"];
|
||||
|
@ -672,17 +672,17 @@ TEST(Value, Array) {
|
||||
EXPECT_FALSE(y.Empty());
|
||||
EXPECT_EQ(5u, y.Size());
|
||||
EXPECT_TRUE(x[SizeType(0)].IsNull());
|
||||
EXPECT_TRUE(x[1u].IsTrue());
|
||||
EXPECT_TRUE(x[2u].IsFalse());
|
||||
EXPECT_TRUE(x[3u].IsInt());
|
||||
EXPECT_EQ(123, x[3u].GetInt());
|
||||
EXPECT_TRUE(x[1].IsTrue());
|
||||
EXPECT_TRUE(x[2].IsFalse());
|
||||
EXPECT_TRUE(x[3].IsInt());
|
||||
EXPECT_EQ(123, x[3].GetInt());
|
||||
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
||||
EXPECT_TRUE(y[1u].IsTrue());
|
||||
EXPECT_TRUE(y[2u].IsFalse());
|
||||
EXPECT_TRUE(y[3u].IsInt());
|
||||
EXPECT_EQ(123, y[3u].GetInt());
|
||||
EXPECT_TRUE(y[4u].IsString());
|
||||
EXPECT_STREQ("foo", y[4u].GetString());
|
||||
EXPECT_TRUE(y[1].IsTrue());
|
||||
EXPECT_TRUE(y[2].IsFalse());
|
||||
EXPECT_TRUE(y[3].IsInt());
|
||||
EXPECT_EQ(123, y[3].GetInt());
|
||||
EXPECT_TRUE(y[4].IsString());
|
||||
EXPECT_STREQ("foo", y[4].GetString());
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
// PushBack(GenericValue&&, Allocator&);
|
||||
@ -691,11 +691,11 @@ TEST(Value, Array) {
|
||||
y.PushBack(Value(true), allocator);
|
||||
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
|
||||
EXPECT_EQ(2u, y.Size());
|
||||
EXPECT_TRUE(y[0u].IsTrue());
|
||||
EXPECT_TRUE(y[1u].IsArray());
|
||||
EXPECT_EQ(2u, y[1u].Size());
|
||||
EXPECT_TRUE(y[1u][0u].IsInt());
|
||||
EXPECT_TRUE(y[1u][1u].IsString());
|
||||
EXPECT_TRUE(y[0].IsTrue());
|
||||
EXPECT_TRUE(y[1].IsArray());
|
||||
EXPECT_EQ(2u, y[1].Size());
|
||||
EXPECT_TRUE(y[1][0].IsInt());
|
||||
EXPECT_TRUE(y[1][1].IsString());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -741,9 +741,9 @@ TEST(Value, Array) {
|
||||
x.PopBack();
|
||||
EXPECT_EQ(4u, x.Size());
|
||||
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
||||
EXPECT_TRUE(y[1u].IsTrue());
|
||||
EXPECT_TRUE(y[2u].IsFalse());
|
||||
EXPECT_TRUE(y[3u].IsInt());
|
||||
EXPECT_TRUE(y[1].IsTrue());
|
||||
EXPECT_TRUE(y[2].IsFalse());
|
||||
EXPECT_TRUE(y[3].IsInt());
|
||||
|
||||
// Clear()
|
||||
x.Clear();
|
||||
@ -764,23 +764,23 @@ TEST(Value, Array) {
|
||||
EXPECT_EQ(x.Begin(), itr);
|
||||
EXPECT_EQ(9u, x.Size());
|
||||
for (int i = 0; i < 9; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0u].GetInt());
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
|
||||
// Ease the last
|
||||
itr = x.Erase(x.End() - 1);
|
||||
EXPECT_EQ(x.End(), itr);
|
||||
EXPECT_EQ(8u, x.Size());
|
||||
for (int i = 0; i < 8; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0u].GetInt());
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
|
||||
// Erase the middle
|
||||
itr = x.Erase(x.Begin() + 4);
|
||||
EXPECT_EQ(x.Begin() + 4, itr);
|
||||
EXPECT_EQ(7u, x.Size());
|
||||
for (int i = 0; i < 4; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0u].GetInt());
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
for (int i = 4; i < 7; i++)
|
||||
EXPECT_EQ(i + 2, x[i][0u].GetInt());
|
||||
EXPECT_EQ(i + 2, x[i][0].GetInt());
|
||||
|
||||
// Erase(ValueIterator, ValueIterator)
|
||||
// Exhaustive test with all 0 <= first < n, first <= last <= n cases
|
||||
@ -800,9 +800,9 @@ TEST(Value, Array) {
|
||||
size_t removeCount = last - first;
|
||||
EXPECT_EQ(n - removeCount, x.Size());
|
||||
for (unsigned i = 0; i < first; i++)
|
||||
EXPECT_EQ(i, x[i][0u].GetUint());
|
||||
EXPECT_EQ(i, x[i][0].GetUint());
|
||||
for (unsigned i = first; i < n - removeCount; i++)
|
||||
EXPECT_EQ(i + removeCount, x[i][0u].GetUint());
|
||||
EXPECT_EQ(i + removeCount, x[i][0].GetUint());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,7 +1012,7 @@ TEST(Value, Object) {
|
||||
for (; itr != x.MemberEnd(); ++itr) {
|
||||
int i = (itr - x.MemberBegin()) + 1;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0u].GetInt());
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
|
||||
// Erase the last
|
||||
@ -1023,7 +1023,7 @@ TEST(Value, Object) {
|
||||
for (; itr != x.MemberEnd(); ++itr) {
|
||||
int i = (itr - x.MemberBegin()) + 1;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0u].GetInt());
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
|
||||
// Erase the middle
|
||||
@ -1035,7 +1035,7 @@ TEST(Value, Object) {
|
||||
int i = (itr - x.MemberBegin());
|
||||
i += (i<4) ? 1 : 2;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0u].GetInt());
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
|
||||
// EraseMember(ConstMemberIterator, ConstMemberIterator)
|
||||
@ -1056,9 +1056,9 @@ TEST(Value, Object) {
|
||||
size_t removeCount = last - first;
|
||||
EXPECT_EQ(n - removeCount, x.MemberCount());
|
||||
for (unsigned i = 0; i < first; i++)
|
||||
EXPECT_EQ(i, x[keys[i]][0u].GetUint());
|
||||
EXPECT_EQ(i, x[keys[i]][0].GetUint());
|
||||
for (unsigned i = first; i < n - removeCount; i++)
|
||||
EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0u].GetUint());
|
||||
EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user