Merge pull request #265 from redboltz/add_base_class_support

Base classes packing/converting/creating object::with_zone support in C+...
This commit is contained in:
Nobuyuki Kubota 2015-04-27 23:06:53 -07:00
commit a112ebb4df
3 changed files with 167 additions and 1 deletions

View File

@ -43,6 +43,19 @@
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
}
#define MSGPACK_BASE(base) \
static_cast<base &>( \
const_cast< \
std::add_lvalue_reference< \
std::remove_const< \
std::remove_pointer< \
decltype(this) \
>::type \
>::type \
>::type \
>(*this) \
)
// MSGPACK_ADD_ENUM must be used in the global namespace.
#define MSGPACK_ADD_ENUM(enum_name) \
namespace msgpack { \

View File

@ -185,4 +185,80 @@ TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_class_member)
EXPECT_EQ(val1.t3, val2.t3);
}
struct top {
int t;
MSGPACK_DEFINE(t);
};
struct mid1 : top {
int m1;
MSGPACK_DEFINE(MSGPACK_BASE(top), m1);
};
struct mid2 : top {
int m2;
MSGPACK_DEFINE(m2, MSGPACK_BASE(top));
};
struct bottom : mid1, mid2 {
int b;
MSGPACK_DEFINE(MSGPACK_BASE(mid1), MSGPACK_BASE(mid2), b);
};
TEST(MSGPACK_INHERIT, simple_buffer_non_virtual)
{
bottom b;
b.b = 1;
b.m1 = 2;
b.m2 = 3;
b.mid1::t = 4;
b.mid2::t = 5;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, b);
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size());
bottom br = ret.get().as<bottom>();
EXPECT_EQ(b.b, br.b);
EXPECT_EQ(b.m1, br.m1);
EXPECT_EQ(b.m2, br.m2);
EXPECT_EQ(b.mid1::t, br.mid1::t);
EXPECT_EQ(b.mid2::t, br.mid2::t);
}
struct v_top {
int t;
MSGPACK_DEFINE(t);
};
struct v_mid1 : virtual v_top {
int m1;
MSGPACK_DEFINE(m1);
};
struct v_mid2 : virtual v_top {
int m2;
MSGPACK_DEFINE(m2);
};
struct v_bottom : v_mid1, v_mid2 {
int b;
MSGPACK_DEFINE(MSGPACK_BASE(v_mid1), MSGPACK_BASE(v_mid2), MSGPACK_BASE(v_top), b);
};
TEST(MSGPACK_INHERIT, simple_buffer_virtual)
{
v_bottom b;
b.b = 1;
b.m1 = 2;
b.m2 = 3;
b.t = 4;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, b);
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size());
v_bottom br = ret.get().as<v_bottom>();
EXPECT_EQ(b.b, br.b);
EXPECT_EQ(b.m1, br.m1);
EXPECT_EQ(b.m2, br.m2);
EXPECT_EQ(b.t, br.t);
}
#endif // !defined(MSGPACK_USE_CPP03)

View File

@ -786,4 +786,81 @@ TEST(object_with_zone, tuple_empty)
EXPECT_EQ(obj.as<test_t>(), v);
}
#endif
// User defined inheriting classes
struct top {
int t;
MSGPACK_DEFINE(t);
};
struct mid1 : top {
int m1;
MSGPACK_DEFINE(MSGPACK_BASE(top), m1);
};
struct mid2 : top {
int m2;
MSGPACK_DEFINE(m2, MSGPACK_BASE(top));
};
struct bottom : mid1, mid2 {
int b;
MSGPACK_DEFINE(MSGPACK_BASE(mid1), MSGPACK_BASE(mid2), b);
};
TEST(object_with_zone, user_defined_non_virtual)
{
bottom b;
b.b = 1;
b.m1 = 2;
b.m2 = 3;
b.mid1::t = 4;
b.mid2::t = 5;
msgpack::zone z;
msgpack::object obj(b, z);
bottom br = obj.as<bottom>();
EXPECT_EQ(b.b, br.b);
EXPECT_EQ(b.m1, br.m1);
EXPECT_EQ(b.m2, br.m2);
EXPECT_EQ(b.mid1::t, br.mid1::t);
EXPECT_EQ(b.mid2::t, br.mid2::t);
}
struct v_top {
int t;
MSGPACK_DEFINE(t);
};
struct v_mid1 : virtual v_top {
int m1;
MSGPACK_DEFINE(m1);
};
struct v_mid2 : virtual v_top {
int m2;
MSGPACK_DEFINE(m2);
};
struct v_bottom : v_mid1, v_mid2 {
int b;
MSGPACK_DEFINE(MSGPACK_BASE(v_mid1), MSGPACK_BASE(v_mid2), MSGPACK_BASE(v_top), b);
};
TEST(object_with_zone, user_defined_virtual)
{
v_bottom b;
b.b = 1;
b.m1 = 2;
b.m2 = 3;
b.t = 4;
msgpack::zone z;
msgpack::object obj(b, z);
v_bottom br = obj.as<v_bottom>();
EXPECT_EQ(b.b, br.b);
EXPECT_EQ(b.m1, br.m1);
EXPECT_EQ(b.m2, br.m2);
EXPECT_EQ(b.t, br.t);
}
#endif // !defined(MSGPACK_USE_CPP03)