Skip to content

Commit

Permalink
Add implicit constructors of GenericValue for GenercArray|Object
Browse files Browse the repository at this point in the history
Also remove SetArray|Object(…)
  • Loading branch information
miloyip committed Feb 18, 2016
1 parent d13be6c commit 46dc8e9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 12 deletions.
36 changes: 26 additions & 10 deletions include/rapidjson/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ struct TypeHelper<ValueType, typename ValueType::Array> {
typedef typename ValueType::Array ArrayType;
static bool Is(const ValueType& v) { return v.IsArray(); }
static ArrayType Get(ValueType& v) { return v.GetArray(); }
static ValueType& Set(ValueType& v, ArrayType data) { return v.SetArray(data); }
static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v.SetArray(data); }
static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
};

template<typename ValueType>
Expand All @@ -497,8 +497,8 @@ struct TypeHelper<ValueType, typename ValueType::Object> {
typedef typename ValueType::Object ObjectType;
static bool Is(const ValueType& v) { return v.IsObject(); }
static ObjectType Get(ValueType& v) { return v.GetObject(); }
static ValueType& Set(ValueType& v, ObjectType data) { return v.SetObject(data); }
static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v.SetObject(data); }
static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
};

template<typename ValueType>
Expand Down Expand Up @@ -681,6 +681,28 @@ class GenericValue {
GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
#endif

//! Constructor for Array.
/*!
\param a An array obtained by \c GetArray().
\note \c Array is always pass-by-value.
\note the source array is moved into this value and the sourec array becomes empty.
*/
GenericValue(Array a) : data_(a.value_.data_), flags_(a.value_.flags_) {
a.value_.data_ = Data();
a.value_.flags_ = kArrayFlag;
}

//! Constructor for Object.
/*!
\param o An object obtained by \c GetObject().
\note \c Object is always pass-by-value.
\note the source object is moved into this value and the sourec object becomes empty.
*/
GenericValue(Object o) : data_(o.value_.data_), flags_(o.value_.flags_) {
o.value_.data_ = Data();
o.value_.flags_ = kObjectFlag;
}

//! Destructor.
/*! Need to destruct elements of array, members of object, or copy-string.
*/
Expand Down Expand Up @@ -970,9 +992,6 @@ class GenericValue {
/*! \post IsObject() == true */
GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }

//! Set this value with an object.
GenericValue& SetObject(Object& o) { return *this = o.value_; }

//! Get the number of members in the object.
SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }

Expand Down Expand Up @@ -1431,9 +1450,6 @@ class GenericValue {
/*! \post IsArray == true */
GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }

//! Set this value with an array.
GenericValue& SetArray(Array& a) { return *this = a.value_; }

//! Get the number of elements in array.
SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }

Expand Down
44 changes: 42 additions & 2 deletions test/unittest/valuetest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,9 +1059,32 @@ TEST(Value, ArrayHelper) {

Value x2;
x2.Set<Value::Array>(a);
EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
}

{
Value y(kArrayType);
y.PushBack(123, allocator);

Value x(y.GetArray()); // Construct value form array.
EXPECT_TRUE(x.IsArray());
EXPECT_EQ(123, x[0].GetInt());
EXPECT_TRUE(y.IsArray()); // Invariant
EXPECT_TRUE(y.Empty());
}

{
Value x(kArrayType);
Value y(kArrayType);
y.PushBack(123, allocator);
x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue

EXPECT_EQ(1, x.Size());
EXPECT_EQ(123, x[0][0].GetInt());
EXPECT_TRUE(y.IsArray());
EXPECT_TRUE(y.Empty());
}
}

#if RAPIDJSON_HAS_CXX11_RANGE_FOR
Expand Down Expand Up @@ -1413,9 +1436,26 @@ TEST(Value, ObjectHelper) {

Value x2;
x2.Set<Value::Object>(o);
EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
}

{
Value x(kObjectType);
x.AddMember("a", "apple", allocator);
Value y(x.GetObject());
EXPECT_STREQ("apple", y["a"].GetString());
EXPECT_TRUE(x.IsObject()); // Invariant
}

{
Value x(kObjectType);
x.AddMember("a", "apple", allocator);
Value y(kObjectType);
y.AddMember("fruits", x.GetObject(), allocator);
EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
EXPECT_TRUE(x.IsObject()); // Invariant
}
}

#if RAPIDJSON_HAS_CXX11_RANGE_FOR
Expand Down

0 comments on commit 46dc8e9

Please sign in to comment.