Commit 43737ef3 authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

GenericValue::FindMember: return MemberEnd, if member doesn't exist

parent 17a8804c
...@@ -420,7 +420,8 @@ public: ...@@ -420,7 +420,8 @@ public:
A better approach is to use the now public FindMember(). A better approach is to use the now public FindMember().
*/ */
GenericValue& operator[](const Ch* name) { GenericValue& operator[](const Ch* name) {
if (MemberIterator member = FindMember(name)) MemberIterator member = FindMember(name);
if (member != MemberEnd())
return member->value; return member->value;
else { else {
RAPIDJSON_ASSERT(false); // see above note RAPIDJSON_ASSERT(false); // see above note
...@@ -433,7 +434,8 @@ public: ...@@ -433,7 +434,8 @@ 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.
GenericValue& operator[](const GenericValue& name) { GenericValue& operator[](const GenericValue& name) {
if (Member* member = FindMember(name)) MemberIterator member = FindMember(name);
if (member != MemberEnd())
return member->value; return member->value;
else { else {
RAPIDJSON_ASSERT(false); // see above note RAPIDJSON_ASSERT(false); // see above note
...@@ -443,37 +445,51 @@ public: ...@@ -443,37 +445,51 @@ public:
} }
const GenericValue& operator[](const GenericValue& name) const { return const_cast<GenericValue&>(*this)[name]; } const GenericValue& operator[](const GenericValue& name) const { return const_cast<GenericValue&>(*this)[name]; }
//! Member iterators. //! Const member iterator
ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } /*! \pre IsObject() == true */
ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } //! Const \em past-the-end member iterator
MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } /*! \pre IsObject() == true */
ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); }
//! Member iterator
/*! \pre IsObject() == true */
MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); }
//! \em Past-the-end member iterator
/*! \pre IsObject() == true */
MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); }
//! Check whether a member exists in the object. //! Check whether a member exists in the object.
/*! /*!
\note It is better to use FindMember() directly if you need the obtain the value as well. \note It is better to use FindMember() directly if you need the obtain the value as well.
*/ */
bool HasMember(const Ch* name) const { return FindMember(name) != 0; } bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
// 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.
bool HasMember(const GenericValue& name) const { return FindMember(name) != 0; } bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); }
//! Find member by name. //! Find member by name.
/*! /*!
\return Return the member if exists. Otherwise returns null pointer. \pre IsObject() == true
\return Iterator to member, if it exists.
Otherwise returns \ref MemberEnd().
\note Earlier versions of Rapidjson returned a \c NULL pointer, in case
the requested member doesn't exist. For consistency with e.g.
\c std::map, this has been changed to MemberEnd() now.
*/ */
MemberIterator FindMember(const Ch* name) { MemberIterator FindMember(const Ch* name) {
RAPIDJSON_ASSERT(name); RAPIDJSON_ASSERT(name);
RAPIDJSON_ASSERT(IsObject()); RAPIDJSON_ASSERT(IsObject());
SizeType len = internal::StrLen(name); SizeType len = internal::StrLen(name);
for (MemberIterator member = MemberBegin(); member != MemberEnd(); ++member) MemberIterator member = MemberBegin();
for (; member != MemberEnd(); ++member)
if (member->name.data_.s.length == len && memcmp(member->name.data_.s.str, name, len * sizeof(Ch)) == 0) if (member->name.data_.s.length == len && memcmp(member->name.data_.s.str, name, len * sizeof(Ch)) == 0)
break;
return member; return member;
return 0;
} }
ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
// This version is faster because it does not need a StrLen(). // This version is faster because it does not need a StrLen().
...@@ -482,11 +498,11 @@ public: ...@@ -482,11 +498,11 @@ public:
RAPIDJSON_ASSERT(IsObject()); RAPIDJSON_ASSERT(IsObject());
RAPIDJSON_ASSERT(name.IsString()); RAPIDJSON_ASSERT(name.IsString());
SizeType len = name.data_.s.length; SizeType len = name.data_.s.length;
for (MemberIterator member = MemberBegin(); member != MemberEnd(); ++member) MemberIterator member = MemberBegin();
for ( ; member != MemberEnd(); ++member)
if (member->name.data_.s.length == len && memcmp(member->name.data_.s.str, name.data_.s.str, len * sizeof(Ch)) == 0) if (member->name.data_.s.length == len && memcmp(member->name.data_.s.str, name.data_.s.str, len * sizeof(Ch)) == 0)
break;
return member; return member;
return 0;
} }
ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast<GenericValue&>(*this).FindMember(name); } ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
...@@ -543,7 +559,7 @@ public: ...@@ -543,7 +559,7 @@ public:
*/ */
bool RemoveMember(const Ch* name) { bool RemoveMember(const Ch* name) {
MemberIterator m = FindMember(name); MemberIterator m = FindMember(name);
if (m) { if (m != MemberEnd()) {
RemoveMember(m); RemoveMember(m);
return true; return true;
} }
...@@ -553,7 +569,7 @@ public: ...@@ -553,7 +569,7 @@ public:
bool RemoveMember(const GenericValue& name) { bool RemoveMember(const GenericValue& name) {
MemberIterator m = FindMember(name); MemberIterator m = FindMember(name);
if (m) { if (m != MemberEnd()) {
RemoveMember(m); RemoveMember(m);
return true; return true;
} }
...@@ -572,7 +588,7 @@ public: ...@@ -572,7 +588,7 @@ public:
RAPIDJSON_ASSERT(data_.o.members != 0); RAPIDJSON_ASSERT(data_.o.members != 0);
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
MemberIterator last = data_.o.members + (data_.o.size - 1); MemberIterator last(data_.o.members + (data_.o.size - 1));
if (data_.o.size > 1 && m != last) { if (data_.o.size > 1 && m != last) {
// Move the last one to this place // Move the last one to this place
m->name = last->name; m->name = last->name;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment