diff --git a/erb/cpp03_define.hpp.erb b/erb/cpp03_define.hpp.erb index fb9ebe30..22ea9d47 100644 --- a/erb/cpp03_define.hpp.erb +++ b/erb/cpp03_define.hpp.erb @@ -39,6 +39,8 @@ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ } +#define MSGPACK_BASE(base) (*const_cast(static_cast(this))) + // MSGPACK_ADD_ENUM must be used in the global namespace. #define MSGPACK_ADD_ENUM(enum_name) \ namespace msgpack { \ diff --git a/include/msgpack/adaptor/detail/cpp03_define.hpp b/include/msgpack/adaptor/detail/cpp03_define.hpp index 7635b936..28744169 100644 --- a/include/msgpack/adaptor/detail/cpp03_define.hpp +++ b/include/msgpack/adaptor/detail/cpp03_define.hpp @@ -39,6 +39,8 @@ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ } +#define MSGPACK_BASE(base) (*const_cast(static_cast(this))) + // MSGPACK_ADD_ENUM must be used in the global namespace. #define MSGPACK_ADD_ENUM(enum_name) \ namespace msgpack { \ diff --git a/include/msgpack/adaptor/detail/cpp11_define.hpp b/include/msgpack/adaptor/detail/cpp11_define.hpp index 1287c1b3..f53a2ce5 100644 --- a/include/msgpack/adaptor/detail/cpp11_define.hpp +++ b/include/msgpack/adaptor/detail/cpp11_define.hpp @@ -43,18 +43,7 @@ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ } -#define MSGPACK_BASE(base) \ - static_cast( \ - const_cast< \ - std::add_lvalue_reference< \ - std::remove_const< \ - std::remove_pointer< \ - decltype(this) \ - >::type \ - >::type \ - >::type \ - >(*this) \ - ) +#define MSGPACK_BASE(base) (*const_cast(static_cast(this))) // MSGPACK_ADD_ENUM must be used in the global namespace. #define MSGPACK_ADD_ENUM(enum_name) \ diff --git a/test/msgpack_container.cpp b/test/msgpack_container.cpp index 552d6d57..ea3d854c 100644 --- a/test/msgpack_container.cpp +++ b/test/msgpack_container.cpp @@ -607,3 +607,81 @@ TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member) EXPECT_EQ(val1.value.i, val2.value.i); } } + +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(ret, sbuf.data(), sbuf.size()); + bottom br = ret.get().as(); + 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(ret, sbuf.data(), sbuf.size()); + v_bottom br = ret.get().as(); + EXPECT_EQ(b.b, br.b); + EXPECT_EQ(b.m1, br.m1); + EXPECT_EQ(b.m2, br.m2); + EXPECT_EQ(b.t, br.t); +} diff --git a/test/msgpack_cpp11.cpp b/test/msgpack_cpp11.cpp index 9548b2b8..6dd187cb 100644 --- a/test/msgpack_cpp11.cpp +++ b/test/msgpack_cpp11.cpp @@ -185,80 +185,4 @@ 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(); - 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(); - 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) diff --git a/test/object_with_zone.cpp b/test/object_with_zone.cpp index a2d7c1e3..5b5a7212 100644 --- a/test/object_with_zone.cpp +++ b/test/object_with_zone.cpp @@ -677,6 +677,83 @@ TEST(object_with_zone, construct_enum_outer) EXPECT_EQ(elem, obj.via.u64); } +// 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(); + 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(); + EXPECT_EQ(b.b, br.b); + EXPECT_EQ(b.m1, br.m1); + EXPECT_EQ(b.m2, br.m2); + EXPECT_EQ(b.t, br.t); +} + #if !defined(MSGPACK_USE_CPP03) TEST(object_with_zone, construct_enum_outer_newstyle) @@ -786,81 +863,4 @@ TEST(object_with_zone, tuple_empty) EXPECT_EQ(obj.as(), v); } -// 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(); - 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(); - 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)