From 46dc8e9240113f53e3d9db32f66f46b8e40f89f7 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Fri, 19 Feb 2016 00:49:05 +0800 Subject: [PATCH] Add implicit constructors of GenericValue for GenercArray|Object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also remove SetArray|Object(…) --- include/rapidjson/document.h | 36 +++++++++++++++++++++-------- test/unittest/valuetest.cpp | 44 ++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index c90705c..520e9e1 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -481,8 +481,8 @@ struct TypeHelper { 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 @@ -497,8 +497,8 @@ struct TypeHelper { 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 @@ -681,6 +681,28 @@ public: GenericValue(const std::basic_string& 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. */ @@ -970,9 +992,6 @@ public: /*! \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; } @@ -1431,9 +1450,6 @@ public: /*! \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; } diff --git a/test/unittest/valuetest.cpp b/test/unittest/valuetest.cpp index 28d84d4..db99907 100644 --- a/test/unittest/valuetest.cpp +++ b/test/unittest/valuetest.cpp @@ -1059,9 +1059,32 @@ TEST(Value, ArrayHelper) { Value x2; x2.Set(a); - EXPECT_TRUE(x.IsNull()); + EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving. EXPECT_EQ(1, x2.Get()[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 @@ -1413,9 +1436,26 @@ TEST(Value, ObjectHelper) { Value x2; x2.Set(o); - EXPECT_TRUE(x.IsNull()); + EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving EXPECT_EQ(1, x2.Get()["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