Merge pull request #20 from pah/feature/value-copy-from
GenericValue: add copy constructor and CopyFrom
This commit is contained in:
commit
9c6f7b90d3
@ -69,6 +69,16 @@ public:
|
||||
flags_ = defaultFlags[type];
|
||||
}
|
||||
|
||||
//! Explicit copy constructor (with allocator)
|
||||
/*! Creates a copy of a Value by using the given Allocator
|
||||
\tparam SourceAllocator allocator of \c rhs
|
||||
\param rhs Value to copy from (read-only)
|
||||
\param allocator Allocator to use for copying
|
||||
\see CopyFrom()
|
||||
*/
|
||||
template< typename SourceAllocator >
|
||||
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator & allocator);
|
||||
|
||||
//! Constructor for boolean value.
|
||||
explicit GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}
|
||||
|
||||
@ -183,6 +193,21 @@ public:
|
||||
new (this) GenericValue(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Deep-copy assignment from Value
|
||||
/*! Assigns a \b copy of the Value to the current Value object
|
||||
\tparam SourceAllocator Allocator type of \c rhs
|
||||
\param rhs Value to copy from (read-only)
|
||||
\param allocator Allocator to use for copying
|
||||
*/
|
||||
template <typename SourceAllocator>
|
||||
GenericValue& CopyFrom(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) {
|
||||
RAPIDJSON_ASSERT((void*)this != (void*)&rhs);
|
||||
this->~GenericValue();
|
||||
new (this) GenericValue(rhs,allocator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//!@name Type
|
||||
@ -579,7 +604,7 @@ int z = a[0u].GetInt(); // This works too.
|
||||
case kObjectType:
|
||||
handler.StartObject();
|
||||
for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
|
||||
handler.String(m->name.data_.s.str, m->name.data_.s.length, false);
|
||||
handler.String(m->name.data_.s.str, m->name.data_.s.length, (m->name.flags_ & kCopyFlag) != 0);
|
||||
m->value.Accept(handler);
|
||||
}
|
||||
handler.EndObject(data_.o.size);
|
||||
@ -593,7 +618,7 @@ int z = a[0u].GetInt(); // This works too.
|
||||
break;
|
||||
|
||||
case kStringType:
|
||||
handler.String(data_.s.str, data_.s.length, false);
|
||||
handler.String(data_.s.str, data_.s.length, (flags_ & kCopyFlag) != 0);
|
||||
break;
|
||||
|
||||
case kNumberType:
|
||||
@ -840,8 +865,10 @@ public:
|
||||
//! Get the capacity of stack in bytes.
|
||||
size_t GetStackCapacity() const { return stack_.GetCapacity(); }
|
||||
|
||||
//private:
|
||||
//friend class GenericReader<Encoding>; // for Reader to call the following private handler functions
|
||||
private:
|
||||
// callers of the following private Handler functions
|
||||
template <typename,typename,typename> friend class GenericReader; // for parsing
|
||||
friend class GenericValue<Encoding,Allocator>; // for deep copying
|
||||
|
||||
// Implementation of Handler
|
||||
void Null() { new (stack_.template Push<ValueType>()) ValueType(); }
|
||||
@ -893,6 +920,17 @@ private:
|
||||
|
||||
typedef GenericDocument<UTF8<> > Document;
|
||||
|
||||
// defined here due to the dependency on GenericDocument
|
||||
template <typename Encoding, typename Allocator>
|
||||
template <typename SourceAllocator>
|
||||
inline
|
||||
GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator)
|
||||
{
|
||||
GenericDocument<Encoding,Allocator> d(&allocator);
|
||||
rhs.Accept(d);
|
||||
RawAssign(*d.stack_.template Pop<GenericValue>(1));
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -25,6 +25,36 @@ TEST(Value, assignment_operator) {
|
||||
EXPECT_EQ(1234, y.GetInt());
|
||||
}
|
||||
|
||||
TEST(Value, CopyFrom)
|
||||
{
|
||||
// use CrtAllocator to explicitly malloc/free any memory
|
||||
// comment this line to use the default Allocator instead
|
||||
typedef GenericValue<UTF8<>,CrtAllocator> Value;
|
||||
|
||||
Value::AllocatorType a;
|
||||
Value v1(1234);
|
||||
Value v2(v1,a); // deep copy constructor
|
||||
EXPECT_TRUE(v1.GetType() == v2.GetType());
|
||||
EXPECT_EQ(v1.GetInt(), v2.GetInt());
|
||||
|
||||
v1.SetString("foo");
|
||||
v2.CopyFrom(v1,a);
|
||||
EXPECT_TRUE(v1.GetType() == v2.GetType());
|
||||
EXPECT_STREQ(v1.GetString(), v2.GetString());
|
||||
EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied
|
||||
|
||||
v1.SetArray().PushBack(1234,a);
|
||||
v2.CopyFrom(v1,a);
|
||||
EXPECT_TRUE(v2.IsArray());
|
||||
EXPECT_EQ(v1.Size(), v2.Size());
|
||||
|
||||
v1.PushBack(Value().SetString("foo",a),a); // push string copy
|
||||
EXPECT_TRUE(v1.Size() != v2.Size());
|
||||
v2.CopyFrom(v1,a);
|
||||
EXPECT_TRUE(v1.Size() == v2.Size());
|
||||
EXPECT_STREQ(v1[1].GetString(), v2[1].GetString());
|
||||
EXPECT_NE(v1[1].GetString(), v2[1].GetString()); // string got copied
|
||||
}
|
||||
|
||||
TEST(Value, Null) {
|
||||
// Default constructor
|
||||
|
Loading…
x
Reference in New Issue
Block a user