#include <iostream>
using namespace std;
enum class kTypeFlag { PARENTONE, PARENTTWO, CHILD };
class ParentOne {
public:
ParentOne() { }
virtual ~ParentOne() { }
virtual size_t byte_size() const = 0;
};
class ParentTwo {
public:
ParentTwo(uint32_t id) : id_(id) { }
virtual ~ParentTwo() { }
uint32_t id() const { return id_; }
private:
const uint32_t id_;
};
class Child : public ParentOne, public ParentTwo {
public:
Child(uint32_t id) : ParentOne(), ParentTwo(id) { }
virtual ~Child() { }
size_t byte_size() const override { return sizeof(*this); }
};
namespace details
{
template<typename To, kTypeFlag>
struct cex {To* operator()() {
static_assert(!std::is_same<To, To>::value, "invalid flag to Convert");} };
template<typename To>
struct cex<To, kTypeFlag::PARENTONE> { To* operator()(void*p) {
return static_cast<To*>(static_cast<ParentOne*>(p)); } };
template<typename To>
struct cex<To, kTypeFlag::PARENTTWO> { To* operator()(void*p) {
return static_cast<To*>(static_cast<ParentTwo*>(p)); } };
template<typename To>
struct cex<To, kTypeFlag::CHILD> { To* operator()(void*p) {
return static_cast<To*>(static_cast<Child*>(p)); } };
};
template <typename T, kTypeFlag Flag>
T* ConvertEx (void* pointer)
{
return details::cex<T, Flag>()(pointer);
}
int main()
{
Child* child = new Child(5);
printf("byte_size: %zu\n", child->byte_size());
printf("id: %u\n", child->id());
ParentOne* p1 = ConvertEx<ParentOne, kTypeFlag::CHILD>(child);
ParentTwo* p2 = ConvertEx<ParentTwo, kTypeFlag::CHILD>(child);
printf("byte_size: %zu\n", p1->byte_size());
printf("id: %u\n", p2->id());
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKZW51bSBjbGFzcyBrVHlwZUZsYWcgeyBQQVJFTlRPTkUsIFBBUkVOVFRXTywgQ0hJTEQgfTsKCmNsYXNzIFBhcmVudE9uZSB7CnB1YmxpYzoKICAgIFBhcmVudE9uZSgpIHsgfQogICAgdmlydHVhbCB+UGFyZW50T25lKCkgeyB9CiAgICB2aXJ0dWFsIHNpemVfdCBieXRlX3NpemUoKSBjb25zdCA9IDA7Cn07CgpjbGFzcyBQYXJlbnRUd28gewpwdWJsaWM6CiAgICBQYXJlbnRUd28odWludDMyX3QgaWQpIDogaWRfKGlkKSB7IH0KICAgIHZpcnR1YWwgflBhcmVudFR3bygpIHsgfQogICAgdWludDMyX3QgaWQoKSBjb25zdCB7IHJldHVybiBpZF87IH0KcHJpdmF0ZToKICAgIGNvbnN0IHVpbnQzMl90IGlkXzsKfTsKCmNsYXNzIENoaWxkIDogcHVibGljIFBhcmVudE9uZSwgcHVibGljIFBhcmVudFR3byB7CnB1YmxpYzoKICAgIENoaWxkKHVpbnQzMl90IGlkKSA6IFBhcmVudE9uZSgpLCBQYXJlbnRUd28oaWQpIHsgfQogICAgdmlydHVhbCB+Q2hpbGQoKSB7IH0KICAgIHNpemVfdCBieXRlX3NpemUoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBzaXplb2YoKnRoaXMpOyB9Cn07CgpuYW1lc3BhY2UgZGV0YWlscwp7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUbywga1R5cGVGbGFnPgogICAgc3RydWN0IGNleCB7VG8qIG9wZXJhdG9yKCkoKSB7CiAgICAJc3RhdGljX2Fzc2VydCghc3RkOjppc19zYW1lPFRvLCBUbz46OnZhbHVlLCAiaW52YWxpZCBmbGFnIHRvIENvbnZlcnQiKTt9IH07CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFRvPgogICAgc3RydWN0IGNleDxUbywga1R5cGVGbGFnOjpQQVJFTlRPTkU+IHsgVG8qIG9wZXJhdG9yKCkodm9pZCpwKSB7CiAgICAJcmV0dXJuIHN0YXRpY19jYXN0PFRvKj4oc3RhdGljX2Nhc3Q8UGFyZW50T25lKj4ocCkpOyB9IH07CiAgICAJCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUbz4KICAgIHN0cnVjdCBjZXg8VG8sIGtUeXBlRmxhZzo6UEFSRU5UVFdPPiB7IFRvKiBvcGVyYXRvcigpKHZvaWQqcCkgewogICAgCXJldHVybiBzdGF0aWNfY2FzdDxUbyo+KHN0YXRpY19jYXN0PFBhcmVudFR3byo+KHApKTsgfSB9OwogICAgCQogICAgdGVtcGxhdGU8dHlwZW5hbWUgVG8+CiAgICBzdHJ1Y3QgY2V4PFRvLCBrVHlwZUZsYWc6OkNISUxEPiAgICAgeyBUbyogb3BlcmF0b3IoKSh2b2lkKnApIHsKICAgIAlyZXR1cm4gc3RhdGljX2Nhc3Q8VG8qPihzdGF0aWNfY2FzdDxDaGlsZCo+KHApKTsgfSB9Owp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIGtUeXBlRmxhZyBGbGFnPgpUKiBDb252ZXJ0RXggKHZvaWQqIHBvaW50ZXIpCnsKCXJldHVybiBkZXRhaWxzOjpjZXg8VCwgRmxhZz4oKShwb2ludGVyKTsKfQoKaW50IG1haW4oKQp7CiAgICBDaGlsZCogY2hpbGQgPSBuZXcgQ2hpbGQoNSk7CiAgICBwcmludGYoImJ5dGVfc2l6ZTogJXp1XG4iLCBjaGlsZC0+Ynl0ZV9zaXplKCkpOwogICAgcHJpbnRmKCJpZDogJXVcbiIsIGNoaWxkLT5pZCgpKTsKCiAgICBQYXJlbnRPbmUqIHAxID0gQ29udmVydEV4PFBhcmVudE9uZSwga1R5cGVGbGFnOjpDSElMRD4oY2hpbGQpOwogICAgUGFyZW50VHdvKiBwMiA9IENvbnZlcnRFeDxQYXJlbnRUd28sIGtUeXBlRmxhZzo6Q0hJTEQ+KGNoaWxkKTsKICAgIHByaW50ZigiYnl0ZV9zaXplOiAlenVcbiIsIHAxLT5ieXRlX3NpemUoKSk7CiAgICBwcmludGYoImlkOiAldVxuIiwgcDItPmlkKCkpOwogICAKCglyZXR1cm4gMDsKfQ==