#include<memory>
#include<iostream>
#include<typeinfo>
using namespace std;
template<typename T>
struct void_ { typedef void type; };
template<typename T, typename = void>
struct My_sfinae {
typedef T RealType;
static T& getPtr (T &p) { return p; }
}; //^^^^^^^^^ business logic!
template<typename T>
struct My_sfinae<T, typename void_<typename T::smart_type>::type> {
typedef typename My_sfinae<typename T::smart_type>::RealType RealType;
static RealType& getPtr (T &p) { return My_sfinae<typename T::smart_type>::getPtr(p.getPtr()); }
};
template<typename T>
class some_smart_ptr_wrapper
{
T m_ptr;
public:
typedef T smart_type; // <-- unique name
T& getPtr () { return m_ptr; }
typename My_sfinae<T>::RealType& getFinalPtr () { return My_sfinae<T>::getPtr(m_ptr); }
};
int main ()
{
shared_ptr<int> p1;
some_smart_ptr_wrapper<some_smart_ptr_wrapper<some_smart_ptr_wrapper<shared_ptr<int>>>> p2;
if(typeid(p1) == typeid(p2.getFinalPtr()))
cout << "working\n";
else
cout << "not working\n";
}
I2luY2x1ZGU8bWVtb3J5PgojaW5jbHVkZTxpb3N0cmVhbT4KI2luY2x1ZGU8dHlwZWluZm8+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3Qgdm9pZF8geyB0eXBlZGVmIHZvaWQgdHlwZTsgfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4Kc3RydWN0IE15X3NmaW5hZSB7CiAgdHlwZWRlZiBUIFJlYWxUeXBlOwogIHN0YXRpYyBUJiBnZXRQdHIgKFQgJnApIHsgcmV0dXJuIHA7IH0KfTsgICAgICAgICAgICAgICAgICAgICAgICAvL15eXl5eXl5eXiBidXNpbmVzcyBsb2dpYyEKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IE15X3NmaW5hZTxULCB0eXBlbmFtZSB2b2lkXzx0eXBlbmFtZSBUOjpzbWFydF90eXBlPjo6dHlwZT4gewogIHR5cGVkZWYgdHlwZW5hbWUgTXlfc2ZpbmFlPHR5cGVuYW1lIFQ6OnNtYXJ0X3R5cGU+OjpSZWFsVHlwZSBSZWFsVHlwZTsKICBzdGF0aWMgUmVhbFR5cGUmIGdldFB0ciAoVCAmcCkgeyByZXR1cm4gTXlfc2ZpbmFlPHR5cGVuYW1lIFQ6OnNtYXJ0X3R5cGU+OjpnZXRQdHIocC5nZXRQdHIoKSk7IH0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIHNvbWVfc21hcnRfcHRyX3dyYXBwZXIKewogIFQgbV9wdHI7CnB1YmxpYzoKICB0eXBlZGVmIFQgc21hcnRfdHlwZTsgIC8vIDwtLSB1bmlxdWUgbmFtZQogIFQmIGdldFB0ciAoKSB7IHJldHVybiBtX3B0cjsgfQoKICB0eXBlbmFtZSBNeV9zZmluYWU8VD46OlJlYWxUeXBlJiBnZXRGaW5hbFB0ciAoKSB7IHJldHVybiBNeV9zZmluYWU8VD46OmdldFB0cihtX3B0cik7IH0KfTsKCmludCBtYWluICgpCnsKICBzaGFyZWRfcHRyPGludD4gcDE7IAogIHNvbWVfc21hcnRfcHRyX3dyYXBwZXI8c29tZV9zbWFydF9wdHJfd3JhcHBlcjxzb21lX3NtYXJ0X3B0cl93cmFwcGVyPHNoYXJlZF9wdHI8aW50Pj4+PiBwMjsgCgogIGlmKHR5cGVpZChwMSkgPT0gdHlwZWlkKHAyLmdldEZpbmFsUHRyKCkpKQogICAgY291dCA8PCAid29ya2luZ1xuIjsKICBlbHNlCiAgICBjb3V0IDw8ICJub3Qgd29ya2luZ1xuIjsKfSAK