Commit 36031b1b authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

valuetest: add tests for rvalue references, reenable erase/remove pattern

parent b5f9d607
...@@ -38,6 +38,31 @@ TEST(Value, DefaultConstructor) { ...@@ -38,6 +38,31 @@ TEST(Value, DefaultConstructor) {
// Value y = x; // Value y = x;
//} //}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, MoveConstructor) {
typedef GenericValue<UTF8<>, CrtAllocator> Value;
Value::AllocatorType allocator;
Value x((Value(kArrayType)));
x.Reserve(4u, allocator);
x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushBack(4, allocator);
EXPECT_TRUE(x.IsArray());
EXPECT_EQ(4u, x.Size());
// Value y(x); // should not compile
Value y(std::move(x));
EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(y.IsArray());
EXPECT_EQ(4u, y.Size());
// Value z = y; // should not compile
Value z = std::move(y);
EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(z.IsArray());
EXPECT_EQ(4u, z.Size());
}
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, AssignmentOperator) { TEST(Value, AssignmentOperator) {
Value x(1234); Value x(1234);
Value y; Value y;
...@@ -63,6 +88,22 @@ TEST(Value, AssignmentOperator) { ...@@ -63,6 +88,22 @@ TEST(Value, AssignmentOperator) {
y = StringRef(mstr); y = StringRef(mstr);
EXPECT_TRUE(y.IsString()); EXPECT_TRUE(y.IsString());
EXPECT_EQ(y.GetString(),mstr); EXPECT_EQ(y.GetString(),mstr);
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// C++11 move assignment
x = Value("World");
EXPECT_TRUE(x.IsString());
EXPECT_STREQ("World", x.GetString());
x = std::move(y);
EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
y = std::move(Value().SetInt(1234));
EXPECT_TRUE(y.IsInt());
EXPECT_EQ(1234, y);
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
} }
template <typename A, typename B> template <typename A, typename B>
...@@ -646,6 +687,21 @@ TEST(Value, Array) { ...@@ -646,6 +687,21 @@ TEST(Value, Array) {
EXPECT_TRUE(y[4u].IsString()); EXPECT_TRUE(y[4u].IsString());
EXPECT_STREQ("foo", y[4u].GetString()); EXPECT_STREQ("foo", y[4u].GetString());
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// PushBack(GenericValue&&, Allocator&);
{
Value y(kArrayType);
y.PushBack(Value(true), allocator);
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
EXPECT_EQ(2u, y.Size());
EXPECT_TRUE(y[0u].IsTrue());
EXPECT_TRUE(y[1u].IsArray());
EXPECT_EQ(2u, y[1u].Size());
EXPECT_TRUE(y[1u][0u].IsInt());
EXPECT_TRUE(y[1u][1u].IsString());
}
#endif
// iterator // iterator
Value::ValueIterator itr = x.Begin(); Value::ValueIterator itr = x.Begin();
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
...@@ -754,7 +810,6 @@ TEST(Value, Array) { ...@@ -754,7 +810,6 @@ TEST(Value, Array) {
} }
// Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed. // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
#if 0
// http://en.wikipedia.org/wiki/Erase-remove_idiom // http://en.wikipedia.org/wiki/Erase-remove_idiom
x.Clear(); x.Clear();
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
...@@ -763,11 +818,11 @@ TEST(Value, Array) { ...@@ -763,11 +818,11 @@ TEST(Value, Array) {
else else
x.PushBack(Value(kNullType).Move(), allocator); x.PushBack(Value(kNullType).Move(), allocator);
x.Erase(std::remove(x.Begin(), x.End(), Value(kNullType)), x.End()); const Value null(kNullType);
x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
EXPECT_EQ(5u, x.Size()); EXPECT_EQ(5u, x.Size());
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
EXPECT_EQ(i * 2, x[i]); EXPECT_EQ(i * 2, x[i]);
#endif
// SetArray() // SetArray()
Value z; Value z;
...@@ -821,6 +876,22 @@ TEST(Value, Object) { ...@@ -821,6 +876,22 @@ TEST(Value, Object) {
EXPECT_EQ(8u, o.MemberCount()); EXPECT_EQ(8u, o.MemberCount());
} }
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// AddMember(GenericValue&&, ...) variants
{
Value o(kObjectType);
o.AddMember(Value("true"), Value(true), allocator);
o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
EXPECT_TRUE(o["true"].GetBool());
EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(4u, o.MemberCount());
}
#endif
// Tests a member with null character // Tests a member with null character
Value name; Value name;
const Value C0D("C\0D", 3); const Value C0D("C\0D", 3);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment