#include <utility>
#include <iostream>
template<typename T>
struct fast_castable_leaf {
virtual T* do_fast_cast(T* unused=nullptr) { return nullptr; }
virtual T const* do_fast_cast(T* unused=nullptr) const { return nullptr; }
virtual ~fast_castable_leaf() {}
};
template<typename Tuple>
struct fast_castable;
template<template<typename...>class Tuple>
struct fast_castable<Tuple<>> {
virtual ~fast_castable() {}
};
template<template<typename...>class Tuple, typename T, typename... Ts>
struct fast_castable<Tuple<T,Ts...>>:
fast_castable_leaf<T>,
fast_castable<Tuple<Ts...>>
{};
template<typename T> struct block_deduction { typedef T type; };
template<typename T> using NoDeduction = typename block_deduction<T>::type;
template<typename T>
T* fast_cast( NoDeduction<fast_castable_leaf<T>>* src ) {
return src->do_fast_cast();
}
template<typename T>
T const* fast_cast( NoDeduction<fast_castable_leaf<T>> const* src ) {
return src->do_fast_cast();
}
template<typename T, typename D>
struct fast_cast_allowed : std::integral_constant<bool,
std::is_base_of<T,D>::value || std::is_same<T,D>::value
> {};
template<typename D, typename B, typename Tuple>
struct implement_fast_cast;
template<typename D, typename B, template<typename...>class Tuple>
struct implement_fast_cast<D,B,Tuple<>> : B {};
template<typename D, typename B, template<typename...>class Tuple, typename T, typename... Ts>
struct implement_fast_cast<D,B,Tuple<T,Ts...>> : implement_fast_cast<D, B, Tuple<Ts...>> {
private:
D* do_cast_work(std::true_type) { return static_cast<D*>(this); }
D const* do_cast_work(std::true_type) const { return static_cast<D const*>(this); }
std::nullptr_t do_cast_work(std::false_type) { return nullptr; }
std::nullptr_t do_cast_work(std::false_type) const { return nullptr; }
public:
T* do_fast_cast( T* unused = nullptr ) override { return do_cast_work( fast_cast_allowed<T,D>() ); }
T const* do_fast_cast( T* unused = nullptr ) const override { return do_cast_work( fast_cast_allowed<T,D>() ); }
};
struct Dog;
struct Cat;
struct Moose;
template<typename...>struct Types {};
typedef Types<Dog, Cat, Moose> Mammal_Types;
struct Mammal : fast_castable<Mammal_Types>
{};
struct Cat : implement_fast_cast< Cat, Mammal, Mammal_Types >
{};
int main() {
Cat c;
Mammal* m=&c;
Cat* c2 = fast_cast<Cat>(m);
Dog* d2 = fast_cast<Dog>(m);
std::cout << c2 << "," << d2 << "\n";
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgc3RydWN0IGZhc3RfY2FzdGFibGVfbGVhZiB7CiAgICAgIHZpcnR1YWwgVCogZG9fZmFzdF9jYXN0KFQqIHVudXNlZD1udWxscHRyKSB7IHJldHVybiBudWxscHRyOyB9CiAgICAgIHZpcnR1YWwgVCBjb25zdCogZG9fZmFzdF9jYXN0KFQqIHVudXNlZD1udWxscHRyKSBjb25zdCB7IHJldHVybiBudWxscHRyOyB9CiAgICAgIHZpcnR1YWwgfmZhc3RfY2FzdGFibGVfbGVhZigpIHt9CiAgICB9OwogICAgdGVtcGxhdGU8dHlwZW5hbWUgVHVwbGU+CiAgICBzdHJ1Y3QgZmFzdF9jYXN0YWJsZTsKICAgIHRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPmNsYXNzIFR1cGxlPgogICAgc3RydWN0IGZhc3RfY2FzdGFibGU8VHVwbGU8Pj4gewogICAgICB2aXJ0dWFsIH5mYXN0X2Nhc3RhYmxlKCkge30KICAgIH07CiAgICB0ZW1wbGF0ZTx0ZW1wbGF0ZTx0eXBlbmFtZS4uLj5jbGFzcyBUdXBsZSwgdHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gVHM+CiAgICBzdHJ1Y3QgZmFzdF9jYXN0YWJsZTxUdXBsZTxULFRzLi4uPj46CiAgICAgIGZhc3RfY2FzdGFibGVfbGVhZjxUPiwKICAgICAgZmFzdF9jYXN0YWJsZTxUdXBsZTxUcy4uLj4+CiAgICB7fTsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBibG9ja19kZWR1Y3Rpb24geyB0eXBlZGVmIFQgdHlwZTsgfTsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IHVzaW5nIE5vRGVkdWN0aW9uID0gdHlwZW5hbWUgYmxvY2tfZGVkdWN0aW9uPFQ+Ojp0eXBlOwogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIFQqIGZhc3RfY2FzdCggTm9EZWR1Y3Rpb248ZmFzdF9jYXN0YWJsZV9sZWFmPFQ+Piogc3JjICkgewogICAgICByZXR1cm4gc3JjLT5kb19mYXN0X2Nhc3QoKTsKICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBUIGNvbnN0KiBmYXN0X2Nhc3QoIE5vRGVkdWN0aW9uPGZhc3RfY2FzdGFibGVfbGVhZjxUPj4gY29uc3QqIHNyYyApIHsKICAgICAgcmV0dXJuIHNyYy0+ZG9fZmFzdF9jYXN0KCk7CiAgICB9CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRD4KICAgIHN0cnVjdCBmYXN0X2Nhc3RfYWxsb3dlZCA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKICAgICAgc3RkOjppc19iYXNlX29mPFQsRD46OnZhbHVlIHx8IHN0ZDo6aXNfc2FtZTxULEQ+Ojp2YWx1ZQogICAgPiB7fTsKICAgIAogICAgdGVtcGxhdGU8dHlwZW5hbWUgRCwgdHlwZW5hbWUgQiwgdHlwZW5hbWUgVHVwbGU+CiAgICBzdHJ1Y3QgaW1wbGVtZW50X2Zhc3RfY2FzdDsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBELCB0eXBlbmFtZSBCLCB0ZW1wbGF0ZTx0eXBlbmFtZS4uLj5jbGFzcyBUdXBsZT4KICAgIHN0cnVjdCBpbXBsZW1lbnRfZmFzdF9jYXN0PEQsQixUdXBsZTw+PiA6IEIge307CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBELCB0eXBlbmFtZSBCLCB0ZW1wbGF0ZTx0eXBlbmFtZS4uLj5jbGFzcyBUdXBsZSwgdHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gVHM+CiAgICBzdHJ1Y3QgaW1wbGVtZW50X2Zhc3RfY2FzdDxELEIsVHVwbGU8VCxUcy4uLj4+IDogaW1wbGVtZW50X2Zhc3RfY2FzdDxELCBCLCBUdXBsZTxUcy4uLj4+IHsKICAgIHByaXZhdGU6CiAgICAgIEQqIGRvX2Nhc3Rfd29yayhzdGQ6OnRydWVfdHlwZSkgeyByZXR1cm4gc3RhdGljX2Nhc3Q8RCo+KHRoaXMpOyB9CiAgICAgIEQgY29uc3QqIGRvX2Nhc3Rfd29yayhzdGQ6OnRydWVfdHlwZSkgY29uc3QgeyByZXR1cm4gc3RhdGljX2Nhc3Q8RCBjb25zdCo+KHRoaXMpOyB9CiAgICAgIHN0ZDo6bnVsbHB0cl90IGRvX2Nhc3Rfd29yayhzdGQ6OmZhbHNlX3R5cGUpIHsgcmV0dXJuIG51bGxwdHI7IH0KICAgICAgc3RkOjpudWxscHRyX3QgZG9fY2FzdF93b3JrKHN0ZDo6ZmFsc2VfdHlwZSkgY29uc3QgeyByZXR1cm4gbnVsbHB0cjsgfQogICAgcHVibGljOgogICAgICBUKiBkb19mYXN0X2Nhc3QoIFQqIHVudXNlZCA9IG51bGxwdHIgKSBvdmVycmlkZSB7IHJldHVybiBkb19jYXN0X3dvcmsoIGZhc3RfY2FzdF9hbGxvd2VkPFQsRD4oKSApOyB9CiAgICAgIFQgY29uc3QqIGRvX2Zhc3RfY2FzdCggVCogdW51c2VkID0gbnVsbHB0ciApIGNvbnN0IG92ZXJyaWRlIHsgcmV0dXJuIGRvX2Nhc3Rfd29yayggZmFzdF9jYXN0X2FsbG93ZWQ8VCxEPigpICk7IH0KICAgIH07CgogICAgc3RydWN0IERvZzsKICAgIHN0cnVjdCBDYXQ7CiAgICBzdHJ1Y3QgTW9vc2U7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZS4uLj5zdHJ1Y3QgVHlwZXMge307CiAgICB0eXBlZGVmIFR5cGVzPERvZywgQ2F0LCBNb29zZT4gTWFtbWFsX1R5cGVzOwoKICAgIHN0cnVjdCBNYW1tYWwgOiBmYXN0X2Nhc3RhYmxlPE1hbW1hbF9UeXBlcz4KICAgIHt9OwoKICAgIHN0cnVjdCBDYXQgOiBpbXBsZW1lbnRfZmFzdF9jYXN0PCBDYXQsIE1hbW1hbCwgTWFtbWFsX1R5cGVzID4KICAgIHt9OwoKICAgIGludCBtYWluKCkgewogICAgICBDYXQgYzsKICAgICAgTWFtbWFsKiBtPSZjOwogICAgICBDYXQqIGMyID0gZmFzdF9jYXN0PENhdD4obSk7CiAgICAgIERvZyogZDIgPSBmYXN0X2Nhc3Q8RG9nPihtKTsKICAgICAgc3RkOjpjb3V0IDw8IGMyIDw8ICIsIiA8PCBkMiA8PCAiXG4iOwogICAgfQo=