Commit 6aa664ee authored by Drew Noakes's avatar Drew Noakes

Document traits of types using <type_traits> and static_assert in tests.

The tests state the current traits of types Document, Value and
StringBuffer. There are slight differences between them. It seems like a
good idea to extend this approach across more types, and to review the
expected traits across the board.
parent d6c1c571
...@@ -229,6 +229,31 @@ TEST(Document, UTF16_Document) { ...@@ -229,6 +229,31 @@ TEST(Document, UTF16_Document) {
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include <type_traits>
TEST(Document, Traits) {
static_assert( std::is_constructible<Document>::value, "");
static_assert( std::is_default_constructible<Document>::value, "");
static_assert(!std::is_copy_constructible<Document>::value, "");
static_assert( std::is_move_constructible<Document>::value, "");
static_assert(!std::is_nothrow_constructible<Document>::value, "");
static_assert(!std::is_nothrow_default_constructible<Document>::value, "");
static_assert(!std::is_nothrow_copy_constructible<Document>::value, "");
static_assert( std::is_nothrow_move_constructible<Document>::value, "");
static_assert( std::is_assignable<Document,Document>::value, "");
static_assert(!std::is_copy_assignable<Document>::value, "");
static_assert( std::is_move_assignable<Document>::value, "");
static_assert( std::is_nothrow_assignable<Document,Document>::value, "");
static_assert(!std::is_nothrow_copy_assignable<Document>::value, "");
static_assert( std::is_nothrow_move_assignable<Document>::value, "");
static_assert( std::is_destructible<Document>::value, "");
static_assert( std::is_nothrow_destructible<Document>::value, "");
}
template <typename Allocator> template <typename Allocator>
struct DocumentMove: public ::testing::Test { struct DocumentMove: public ::testing::Test {
}; };
...@@ -248,7 +273,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) { ...@@ -248,7 +273,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) {
EXPECT_EQ(3u, a.Size()); EXPECT_EQ(3u, a.Size());
EXPECT_EQ(&a.GetAllocator(), &allocator); EXPECT_EQ(&a.GetAllocator(), &allocator);
// Document b(a); // should not compile // Document b(a); // does not compile (!is_copy_constructible)
Document b(std::move(a)); Document b(std::move(a));
EXPECT_TRUE(a.IsNull()); EXPECT_TRUE(a.IsNull());
EXPECT_TRUE(b.IsArray()); EXPECT_TRUE(b.IsArray());
...@@ -261,7 +286,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) { ...@@ -261,7 +286,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) {
EXPECT_TRUE(b.IsObject()); EXPECT_TRUE(b.IsObject());
EXPECT_EQ(2u, b.MemberCount()); EXPECT_EQ(2u, b.MemberCount());
// Document c = a; // should not compile // Document c = a; // does not compile (!is_copy_constructible)
Document c = std::move(b); Document c = std::move(b);
EXPECT_TRUE(b.IsNull()); EXPECT_TRUE(b.IsNull());
EXPECT_TRUE(c.IsObject()); EXPECT_TRUE(c.IsObject());
...@@ -336,7 +361,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) { ...@@ -336,7 +361,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) {
EXPECT_EQ(3u, a.Size()); EXPECT_EQ(3u, a.Size());
EXPECT_EQ(&a.GetAllocator(), &allocator); EXPECT_EQ(&a.GetAllocator(), &allocator);
// Document b; b = a; // should not compile // Document b; b = a; // does not compile (!is_copy_assignable)
Document b; Document b;
b = std::move(a); b = std::move(a);
EXPECT_TRUE(a.IsNull()); EXPECT_TRUE(a.IsNull());
...@@ -350,7 +375,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) { ...@@ -350,7 +375,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) {
EXPECT_TRUE(b.IsObject()); EXPECT_TRUE(b.IsObject());
EXPECT_EQ(2u, b.MemberCount()); EXPECT_EQ(2u, b.MemberCount());
// Document c; c = a; // should not compile // Document c; c = a; // does not compile (see static_assert)
Document c; Document c;
c = std::move(b); c = std::move(b);
EXPECT_TRUE(b.IsNull()); EXPECT_TRUE(b.IsNull());
......
...@@ -70,6 +70,32 @@ TEST(StringBuffer, Pop) { ...@@ -70,6 +70,32 @@ TEST(StringBuffer, Pop) {
} }
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include <type_traits>
TEST(StringBuffer, Traits) {
static_assert( std::is_constructible<StringBuffer>::value, "");
static_assert( std::is_default_constructible<StringBuffer>::value, "");
static_assert(!std::is_copy_constructible<StringBuffer>::value, "");
static_assert( std::is_move_constructible<StringBuffer>::value, "");
static_assert(!std::is_nothrow_constructible<StringBuffer>::value, "");
static_assert(!std::is_nothrow_default_constructible<StringBuffer>::value, "");
static_assert(!std::is_nothrow_copy_constructible<StringBuffer>::value, "");
static_assert(!std::is_nothrow_move_constructible<StringBuffer>::value, "");
static_assert( std::is_assignable<StringBuffer,StringBuffer>::value, "");
static_assert(!std::is_copy_assignable<StringBuffer>::value, "");
static_assert( std::is_move_assignable<StringBuffer>::value, "");
static_assert(!std::is_nothrow_assignable<StringBuffer,StringBuffer>::value, "");
static_assert(!std::is_nothrow_copy_assignable<StringBuffer>::value, "");
static_assert(!std::is_nothrow_move_assignable<StringBuffer>::value, "");
static_assert( std::is_destructible<StringBuffer>::value, "");
static_assert( std::is_nothrow_destructible<StringBuffer>::value, "");
}
TEST(StringBuffer, MoveConstructor) { TEST(StringBuffer, MoveConstructor) {
StringBuffer x; StringBuffer x;
x.Put('A'); x.Put('A');
...@@ -80,13 +106,13 @@ TEST(StringBuffer, MoveConstructor) { ...@@ -80,13 +106,13 @@ TEST(StringBuffer, MoveConstructor) {
EXPECT_EQ(4u, x.GetSize()); EXPECT_EQ(4u, x.GetSize());
EXPECT_STREQ("ABCD", x.GetString()); EXPECT_STREQ("ABCD", x.GetString());
// StringBuffer y(x); // should not compile // StringBuffer y(x); // does not compile (!is_copy_constructible)
StringBuffer y(std::move(x)); StringBuffer y(std::move(x));
EXPECT_EQ(0u, x.GetSize()); EXPECT_EQ(0u, x.GetSize());
EXPECT_EQ(4u, y.GetSize()); EXPECT_EQ(4u, y.GetSize());
EXPECT_STREQ("ABCD", y.GetString()); EXPECT_STREQ("ABCD", y.GetString());
// StringBuffer z = y; // should not compile // StringBuffer z = y; // does not compile (!is_copy_assignable)
StringBuffer z = std::move(y); StringBuffer z = std::move(y);
EXPECT_EQ(0u, y.GetSize()); EXPECT_EQ(0u, y.GetSize());
EXPECT_EQ(4u, z.GetSize()); EXPECT_EQ(4u, z.GetSize());
...@@ -104,10 +130,11 @@ TEST(StringBuffer, MoveAssignment) { ...@@ -104,10 +130,11 @@ TEST(StringBuffer, MoveAssignment) {
EXPECT_STREQ("ABCD", x.GetString()); EXPECT_STREQ("ABCD", x.GetString());
StringBuffer y; StringBuffer y;
// y = x; // should not compile // y = x; // does not compile (!is_copy_assignable)
y = std::move(x); y = std::move(x);
EXPECT_EQ(0u, x.GetSize()); EXPECT_EQ(0u, x.GetSize());
EXPECT_EQ(4u, y.GetSize()); EXPECT_EQ(4u, y.GetSize());
EXPECT_STREQ("ABCD", y.GetString()); EXPECT_STREQ("ABCD", y.GetString());
} }
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
...@@ -39,6 +39,33 @@ TEST(Value, DefaultConstructor) { ...@@ -39,6 +39,33 @@ TEST(Value, DefaultConstructor) {
//} //}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include <type_traits>
TEST(Value, Traits) {
typedef GenericValue<UTF8<>, CrtAllocator> Value;
static_assert( std::is_constructible<Value>::value, "");
static_assert( std::is_default_constructible<Value>::value, "");
static_assert(!std::is_copy_constructible<Value>::value, "");
static_assert( std::is_move_constructible<Value>::value, "");
static_assert( std::is_nothrow_constructible<Value>::value, "");
static_assert( std::is_nothrow_default_constructible<Value>::value, "");
static_assert(!std::is_nothrow_copy_constructible<Value>::value, "");
static_assert( std::is_nothrow_move_constructible<Value>::value, "");
static_assert( std::is_assignable<Value,Value>::value, "");
static_assert(!std::is_copy_assignable<Value>::value, "");
static_assert( std::is_move_assignable<Value>::value, "");
static_assert( std::is_nothrow_assignable<Value,Value>::value, "");
static_assert(!std::is_nothrow_copy_assignable<Value>::value, "");
static_assert( std::is_nothrow_move_assignable<Value>::value, "");
static_assert( std::is_destructible<Value>::value, "");
static_assert( std::is_nothrow_destructible<Value>::value, "");
}
TEST(Value, MoveConstructor) { TEST(Value, MoveConstructor) {
typedef GenericValue<UTF8<>, CrtAllocator> Value; typedef GenericValue<UTF8<>, CrtAllocator> Value;
Value::AllocatorType allocator; Value::AllocatorType allocator;
...@@ -49,18 +76,19 @@ TEST(Value, MoveConstructor) { ...@@ -49,18 +76,19 @@ TEST(Value, MoveConstructor) {
EXPECT_TRUE(x.IsArray()); EXPECT_TRUE(x.IsArray());
EXPECT_EQ(4u, x.Size()); EXPECT_EQ(4u, x.Size());
// Value y(x); // should not compile // Value y(x); // does not compile (!is_copy_constructible)
Value y(std::move(x)); Value y(std::move(x));
EXPECT_TRUE(x.IsNull()); EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(y.IsArray()); EXPECT_TRUE(y.IsArray());
EXPECT_EQ(4u, y.Size()); EXPECT_EQ(4u, y.Size());
// Value z = y; // should not compile // Value z = y; // does not compile (!is_copy_assignable)
Value z = std::move(y); Value z = std::move(y);
EXPECT_TRUE(y.IsNull()); EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(z.IsArray()); EXPECT_TRUE(z.IsArray());
EXPECT_EQ(4u, z.Size()); EXPECT_EQ(4u, z.Size());
} }
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, AssignmentOperator) { TEST(Value, AssignmentOperator) {
......
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