Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Value::XXXMember(...) overloads for std::string #335

Merged
merged 1 commit into from
May 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions include/rapidjson/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,12 @@ class GenericValue {
template <typename SourceAllocator>
const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }

#if RAPIDJSON_HAS_STDSTRING
//! Get a value from an object associated with name (string object).
GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
#endif

//! Const member iterator
/*! \pre IsObject() == true */
ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
Expand All @@ -867,6 +873,18 @@ class GenericValue {
*/
bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }

#if RAPIDJSON_HAS_STDSTRING
//! Check whether a member exists in the object with string object.
/*!
\param name Member name to be searched.
\pre IsObject() == true
\return Whether a member with that name exists.
\note It is better to use FindMember() directly if you need the obtain the value as well.
\note Linear time complexity.
*/
bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
#endif

//! Check whether a member exists in the object with GenericValue name.
/*!
This version is faster because it does not need a StrLen(). It can also handle string with null character.
Expand Down Expand Up @@ -923,6 +941,18 @@ class GenericValue {
}
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }

#if RAPIDJSON_HAS_STDSTRING
//! Find member by string object name.
/*!
\param name Member name to be searched.
\pre IsObject() == true
\return Iterator to member, if it exists.
Otherwise returns \ref MemberEnd().
*/
MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); }
ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); }
#endif

//! Add a member (name-value pair) to the object.
/*! \param name A string value as name of member.
\param value Value of any type.
Expand Down Expand Up @@ -969,6 +999,22 @@ class GenericValue {
return AddMember(name, v, allocator);
}

#if RAPIDJSON_HAS_STDSTRING
//! Add a string object as member (name-value pair) to the object.
/*! \param name A string value as name of member.
\param value constant string reference as value of member.
\param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
\return The value itself for fluent API.
\pre IsObject()
\note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
\note Amortized Constant time complexity.
*/
GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
GenericValue v(value, allocator);
return AddMember(name, v, allocator);
}
#endif

//! Add any primitive value as member (name-value pair) to the object.
/*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
\param name A string value as name of member.
Expand Down Expand Up @@ -1087,6 +1133,10 @@ class GenericValue {
return RemoveMember(n);
}

#if RAPIDJSON_HAS_STDSTRING
bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
#endif

template <typename SourceAllocator>
bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
MemberIterator m = FindMember(name);
Expand Down
22 changes: 22 additions & 0 deletions test/unittest/valuetest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,19 @@ TEST(Value, Object) {
EXPECT_EQ(2u, o.MemberCount());
}

#if RAPIDJSON_HAS_STDSTRING
{
// AddMember(StringRefType, const std::string&, Allocator)
Value o(kObjectType);
o.AddMember("b", std::string("Banana"), allocator);
EXPECT_STREQ("Banana", o["b"].GetString());

// RemoveMember(const std::string&)
o.RemoveMember(std::string("b"));
EXPECT_TRUE(o.ObjectEmpty());
}
#endif

#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// AddMember(GenericValue&&, ...) variants
{
Expand Down Expand Up @@ -986,6 +999,10 @@ TEST(Value, Object) {
EXPECT_TRUE(y.HasMember("A"));
EXPECT_TRUE(y.HasMember("B"));

#if RAPIDJSON_HAS_STDSTRING
EXPECT_TRUE(x.HasMember(std::string("A")));
#endif

name.SetString("C\0D");
EXPECT_TRUE(x.HasMember(name));
EXPECT_TRUE(y.HasMember(name));
Expand All @@ -1009,6 +1026,11 @@ TEST(Value, Object) {
EXPECT_STREQ("Banana", y["B"].GetString());
EXPECT_STREQ("CherryD", y[C0D].GetString());

#if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ("Apple", x["A"].GetString());
EXPECT_STREQ("Apple", y[std::string("A")].GetString());
#endif

// member iterator
Value::MemberIterator itr = x.MemberBegin();
EXPECT_TRUE(itr != x.MemberEnd());
Expand Down