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];
|
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.
|
//! Constructor for boolean value.
|
||||||
explicit GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}
|
explicit GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}
|
||||||
|
|
||||||
@ -183,6 +193,21 @@ public:
|
|||||||
new (this) GenericValue(value);
|
new (this) GenericValue(value);
|
||||||
return *this;
|
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
|
//!@name Type
|
||||||
@ -579,7 +604,7 @@ int z = a[0u].GetInt(); // This works too.
|
|||||||
case kObjectType:
|
case kObjectType:
|
||||||
handler.StartObject();
|
handler.StartObject();
|
||||||
for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
|
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);
|
m->value.Accept(handler);
|
||||||
}
|
}
|
||||||
handler.EndObject(data_.o.size);
|
handler.EndObject(data_.o.size);
|
||||||
@ -593,7 +618,7 @@ int z = a[0u].GetInt(); // This works too.
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kStringType:
|
case kStringType:
|
||||||
handler.String(data_.s.str, data_.s.length, false);
|
handler.String(data_.s.str, data_.s.length, (flags_ & kCopyFlag) != 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kNumberType:
|
case kNumberType:
|
||||||
@ -840,8 +865,10 @@ public:
|
|||||||
//! Get the capacity of stack in bytes.
|
//! Get the capacity of stack in bytes.
|
||||||
size_t GetStackCapacity() const { return stack_.GetCapacity(); }
|
size_t GetStackCapacity() const { return stack_.GetCapacity(); }
|
||||||
|
|
||||||
//private:
|
private:
|
||||||
//friend class GenericReader<Encoding>; // for Reader to call the following private handler functions
|
// 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
|
// Implementation of Handler
|
||||||
void Null() { new (stack_.template Push<ValueType>()) ValueType(); }
|
void Null() { new (stack_.template Push<ValueType>()) ValueType(); }
|
||||||
@ -893,6 +920,17 @@ private:
|
|||||||
|
|
||||||
typedef GenericDocument<UTF8<> > Document;
|
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
|
} // namespace rapidjson
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -25,6 +25,36 @@ TEST(Value, assignment_operator) {
|
|||||||
EXPECT_EQ(1234, y.GetInt());
|
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) {
|
TEST(Value, Null) {
|
||||||
// Default constructor
|
// Default constructor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user