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)