Merge pull request #170 from lichray/disambi_indexing
Disambiguate GenericValue's [0] and ["string"]
This commit is contained in:
commit
a6b444dec4
@ -72,12 +72,8 @@ int main(int, char*[]) {
|
|||||||
for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
|
for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
|
||||||
printf("a[%d] = %d\n", i, a[i].GetInt());
|
printf("a[%d] = %d\n", i, a[i].GetInt());
|
||||||
|
|
||||||
// Note:
|
int y = a[0].GetInt();
|
||||||
//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.
|
|
||||||
(void)y;
|
(void)y;
|
||||||
(void)z;
|
|
||||||
|
|
||||||
// Iterating array with iterators
|
// Iterating array with iterators
|
||||||
printf("a = ");
|
printf("a = ");
|
||||||
|
@ -451,7 +451,7 @@ public:
|
|||||||
\param type Type of the value.
|
\param type Type of the value.
|
||||||
\note Default content for number is zero.
|
\note Default content for number is zero.
|
||||||
*/
|
*/
|
||||||
GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
|
explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
|
||||||
static const unsigned defaultFlags[7] = {
|
static const unsigned defaultFlags[7] = {
|
||||||
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
|
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
|
||||||
kNumberAnyFlag
|
kNumberAnyFlag
|
||||||
@ -795,6 +795,15 @@ public:
|
|||||||
//! Check whether the object is empty.
|
//! Check whether the object is empty.
|
||||||
bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
|
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.
|
//! 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.
|
\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().
|
A better approach is to use FindMember().
|
||||||
\note Linear time complexity.
|
\note Linear time complexity.
|
||||||
*/
|
*/
|
||||||
GenericValue& operator[](const Ch* name) {
|
|
||||||
|
GenericValue& DoIndex(const Ch* name, internal::TrueType) {
|
||||||
GenericValue n(StringRef(name));
|
GenericValue n(StringRef(name));
|
||||||
return (*this)[n];
|
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().
|
// This version is faster because it does not need a StrLen().
|
||||||
// It can also handle string with null character.
|
// It can also handle string with null character.
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator>
|
||||||
@ -1131,23 +1150,6 @@ public:
|
|||||||
data_.a.size = 0;
|
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
|
//! Element iterator
|
||||||
/*! \pre IsArray() == true */
|
/*! \pre IsArray() == true */
|
||||||
ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
|
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\"}]");
|
json.Parse<kParseValidateEncodingFlag>(L"[{\"created_at\":\"Wed Oct 30 17:13:20 +0000 2012\"}]");
|
||||||
|
|
||||||
ASSERT_TRUE(json.IsArray());
|
ASSERT_TRUE(json.IsArray());
|
||||||
GenericValue< UTF16<> >& v = json[0u];
|
GenericValue< UTF16<> >& v = json[0];
|
||||||
ASSERT_TRUE(v.IsObject());
|
ASSERT_TRUE(v.IsObject());
|
||||||
|
|
||||||
GenericValue< UTF16<> >& s = v[L"created_at"];
|
GenericValue< UTF16<> >& s = v[L"created_at"];
|
||||||
|
@ -672,17 +672,17 @@ TEST(Value, Array) {
|
|||||||
EXPECT_FALSE(y.Empty());
|
EXPECT_FALSE(y.Empty());
|
||||||
EXPECT_EQ(5u, y.Size());
|
EXPECT_EQ(5u, y.Size());
|
||||||
EXPECT_TRUE(x[SizeType(0)].IsNull());
|
EXPECT_TRUE(x[SizeType(0)].IsNull());
|
||||||
EXPECT_TRUE(x[1u].IsTrue());
|
EXPECT_TRUE(x[1].IsTrue());
|
||||||
EXPECT_TRUE(x[2u].IsFalse());
|
EXPECT_TRUE(x[2].IsFalse());
|
||||||
EXPECT_TRUE(x[3u].IsInt());
|
EXPECT_TRUE(x[3].IsInt());
|
||||||
EXPECT_EQ(123, x[3u].GetInt());
|
EXPECT_EQ(123, x[3].GetInt());
|
||||||
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
||||||
EXPECT_TRUE(y[1u].IsTrue());
|
EXPECT_TRUE(y[1].IsTrue());
|
||||||
EXPECT_TRUE(y[2u].IsFalse());
|
EXPECT_TRUE(y[2].IsFalse());
|
||||||
EXPECT_TRUE(y[3u].IsInt());
|
EXPECT_TRUE(y[3].IsInt());
|
||||||
EXPECT_EQ(123, y[3u].GetInt());
|
EXPECT_EQ(123, y[3].GetInt());
|
||||||
EXPECT_TRUE(y[4u].IsString());
|
EXPECT_TRUE(y[4].IsString());
|
||||||
EXPECT_STREQ("foo", y[4u].GetString());
|
EXPECT_STREQ("foo", y[4].GetString());
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
// PushBack(GenericValue&&, Allocator&);
|
// PushBack(GenericValue&&, Allocator&);
|
||||||
@ -691,11 +691,11 @@ TEST(Value, Array) {
|
|||||||
y.PushBack(Value(true), allocator);
|
y.PushBack(Value(true), allocator);
|
||||||
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
|
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
|
||||||
EXPECT_EQ(2u, y.Size());
|
EXPECT_EQ(2u, y.Size());
|
||||||
EXPECT_TRUE(y[0u].IsTrue());
|
EXPECT_TRUE(y[0].IsTrue());
|
||||||
EXPECT_TRUE(y[1u].IsArray());
|
EXPECT_TRUE(y[1].IsArray());
|
||||||
EXPECT_EQ(2u, y[1u].Size());
|
EXPECT_EQ(2u, y[1].Size());
|
||||||
EXPECT_TRUE(y[1u][0u].IsInt());
|
EXPECT_TRUE(y[1][0].IsInt());
|
||||||
EXPECT_TRUE(y[1u][1u].IsString());
|
EXPECT_TRUE(y[1][1].IsString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -741,9 +741,9 @@ TEST(Value, Array) {
|
|||||||
x.PopBack();
|
x.PopBack();
|
||||||
EXPECT_EQ(4u, x.Size());
|
EXPECT_EQ(4u, x.Size());
|
||||||
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
EXPECT_TRUE(y[SizeType(0)].IsNull());
|
||||||
EXPECT_TRUE(y[1u].IsTrue());
|
EXPECT_TRUE(y[1].IsTrue());
|
||||||
EXPECT_TRUE(y[2u].IsFalse());
|
EXPECT_TRUE(y[2].IsFalse());
|
||||||
EXPECT_TRUE(y[3u].IsInt());
|
EXPECT_TRUE(y[3].IsInt());
|
||||||
|
|
||||||
// Clear()
|
// Clear()
|
||||||
x.Clear();
|
x.Clear();
|
||||||
@ -764,23 +764,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][0u].GetInt());
|
EXPECT_EQ(i + 1, x[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][0u].GetInt());
|
EXPECT_EQ(i + 1, x[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][0u].GetInt());
|
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||||
for (int i = 4; i < 7; i++)
|
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)
|
// 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
|
||||||
@ -800,9 +800,9 @@ TEST(Value, Array) {
|
|||||||
size_t removeCount = last - first;
|
size_t removeCount = last - first;
|
||||||
EXPECT_EQ(n - removeCount, x.Size());
|
EXPECT_EQ(n - removeCount, x.Size());
|
||||||
for (unsigned i = 0; i < first; i++)
|
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++)
|
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) {
|
for (; itr != x.MemberEnd(); ++itr) {
|
||||||
int i = (itr - x.MemberBegin()) + 1;
|
int i = (itr - x.MemberBegin()) + 1;
|
||||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||||
EXPECT_EQ(i, itr->value[0u].GetInt());
|
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase the last
|
// Erase the last
|
||||||
@ -1023,7 +1023,7 @@ TEST(Value, Object) {
|
|||||||
for (; itr != x.MemberEnd(); ++itr) {
|
for (; itr != x.MemberEnd(); ++itr) {
|
||||||
int i = (itr - x.MemberBegin()) + 1;
|
int i = (itr - x.MemberBegin()) + 1;
|
||||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||||
EXPECT_EQ(i, itr->value[0u].GetInt());
|
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase the middle
|
// Erase the middle
|
||||||
@ -1035,7 +1035,7 @@ TEST(Value, Object) {
|
|||||||
int i = (itr - x.MemberBegin());
|
int i = (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[0u].GetInt());
|
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// EraseMember(ConstMemberIterator, ConstMemberIterator)
|
// EraseMember(ConstMemberIterator, ConstMemberIterator)
|
||||||
@ -1056,9 +1056,9 @@ TEST(Value, Object) {
|
|||||||
size_t removeCount = last - first;
|
size_t removeCount = last - first;
|
||||||
EXPECT_EQ(n - removeCount, x.MemberCount());
|
EXPECT_EQ(n - removeCount, x.MemberCount());
|
||||||
for (unsigned i = 0; i < first; i++)
|
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++)
|
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