#include <utility>
#include <memory>
#include <iostream>
template<class T>
T& smart_wrap_unwrap(T& v, long)
{
return v;
}
template<class T>
auto smart_wrap_unwrap(T& v, int)
-> decltype(smart_wrap_unwrap(v.getPtr(), 0))
{
return smart_wrap_unwrap(v.getPtr(), 0);
}
template<class T>
struct smart{
template<class U>
smart(U* v) : _ptr(v){}
T& getPtr(){ return _ptr; }
T _ptr;
};
struct X{
void foo(){ std::cout << "!\n"; }
};
int main(){
smart<smart<smart<std::shared_ptr<X>>>> smartception(new X());
smart_wrap_unwrap(smartception, 0)->foo();
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnRlbXBsYXRlPGNsYXNzIFQ+ClQmIHNtYXJ0X3dyYXBfdW53cmFwKFQmIHYsIGxvbmcpCnsKICByZXR1cm4gdjsKfQoKdGVtcGxhdGU8Y2xhc3MgVD4KYXV0byBzbWFydF93cmFwX3Vud3JhcChUJiB2LCBpbnQpCiAgLT4gZGVjbHR5cGUoc21hcnRfd3JhcF91bndyYXAodi5nZXRQdHIoKSwgMCkpCnsKICByZXR1cm4gc21hcnRfd3JhcF91bndyYXAodi5nZXRQdHIoKSwgMCk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQ+CnN0cnVjdCBzbWFydHsKICB0ZW1wbGF0ZTxjbGFzcyBVPgogIHNtYXJ0KFUqIHYpIDogX3B0cih2KXt9CiAgVCYgZ2V0UHRyKCl7IHJldHVybiBfcHRyOyB9CiAgVCBfcHRyOwp9OwoKc3RydWN0IFh7CiAgdm9pZCBmb28oKXsgc3RkOjpjb3V0IDw8ICIhXG4iOyB9Cn07CgppbnQgbWFpbigpewogIHNtYXJ0PHNtYXJ0PHNtYXJ0PHN0ZDo6c2hhcmVkX3B0cjxYPj4+PiBzbWFydGNlcHRpb24obmV3IFgoKSk7CiAgc21hcnRfd3JhcF91bndyYXAoc21hcnRjZXB0aW9uLCAwKS0+Zm9vKCk7Cn0=