#include <iostream>
template <class Handle, class Impl>
class Pimpl
{
private:
Impl* _make() const
{ return ((Handle const*)this)->make(); }
void _unmake(Impl *p) const
{ ((Handle const*)this)->unmake(p); }
Impl* _clone(Impl *p) const
{ return ((Handle const*)this)->clone(p); }
void swap(Pimpl &other) {
Impl *temp = d_ptr;
d_ptr = other.d_ptr;
other.d_ptr = temp;
}
public:
explicit Pimpl();
~Pimpl();
Pimpl(const Pimpl &other);
Pimpl &operator=(const Pimpl &other);
// fall-backs
static Impl* make() { return new Impl; }
static void unmake(Impl* p) { delete p; }
static Impl* clone(Impl* p) { return new Impl(*p); }
protected:
Impl *d_ptr;
};
template<class Handle, class Impl>
Pimpl<Handle, Impl>::Pimpl() :
d_ptr(_make())
{
}
template<class Handle, class Impl>
Pimpl<Handle, Impl>::~Pimpl()
{
_unmake(d_ptr);
d_ptr = 0;
}
template<class Handle, class Impl>
Pimpl<Handle, Impl>::Pimpl(const Pimpl &other) :
d_ptr(_clone(other.d_ptr))
{
}
template<class Handle, class Impl>
Pimpl<Handle, Impl> &Pimpl<Handle, Impl>::operator=(const Pimpl &other)
{
Pimpl copy(other);
swap(copy);
return *this;
}
class ObjectPrivate;
class Object : private Pimpl<Object, ObjectPrivate>
{
public:
Object();
~Object();
};
int main() {
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPGNsYXNzIEhhbmRsZSwgY2xhc3MgSW1wbD4KY2xhc3MgUGltcGwKewpwcml2YXRlOgoJSW1wbCogX21ha2UoKSBjb25zdAoJeyByZXR1cm4gKChIYW5kbGUgY29uc3QqKXRoaXMpLT5tYWtlKCk7IH0KCQoJdm9pZCBfdW5tYWtlKEltcGwgKnApIGNvbnN0Cgl7ICgoSGFuZGxlIGNvbnN0Kil0aGlzKS0+dW5tYWtlKHApOyB9CgkKCUltcGwqIF9jbG9uZShJbXBsICpwKSBjb25zdAoJeyByZXR1cm4gKChIYW5kbGUgY29uc3QqKXRoaXMpLT5jbG9uZShwKTsgfQoJCgl2b2lkIHN3YXAoUGltcGwgJm90aGVyKSB7CgkJSW1wbCAqdGVtcCA9IGRfcHRyOwoJCWRfcHRyID0gb3RoZXIuZF9wdHI7CgkJb3RoZXIuZF9wdHIgPSB0ZW1wOwoJfQoJCnB1YmxpYzoKICAgIGV4cGxpY2l0IFBpbXBsKCk7CiAgICAgICAgICAgIH5QaW1wbCgpOwoKICAgIFBpbXBsKGNvbnN0IFBpbXBsICZvdGhlcik7CiAgICBQaW1wbCAmb3BlcmF0b3I9KGNvbnN0IFBpbXBsICZvdGhlcik7CiAgICAKICAgIC8vIGZhbGwtYmFja3MKICAgIHN0YXRpYyBJbXBsKiBtYWtlKCkgICAgICAgICAgeyByZXR1cm4gbmV3IEltcGw7IH0KICAgIHN0YXRpYyB2b2lkICB1bm1ha2UoSW1wbCogcCkgeyBkZWxldGUgcDsgfQogICAgc3RhdGljIEltcGwqIGNsb25lKEltcGwqIHApICB7IHJldHVybiBuZXcgSW1wbCgqcCk7IH0KCnByb3RlY3RlZDoKCiAgICBJbXBsICpkX3B0cjsKfTsKCnRlbXBsYXRlPGNsYXNzIEhhbmRsZSwgY2xhc3MgSW1wbD4KUGltcGw8SGFuZGxlLCBJbXBsPjo6UGltcGwoKSA6CiAgZF9wdHIoX21ha2UoKSkKewoKfQoKdGVtcGxhdGU8Y2xhc3MgSGFuZGxlLCBjbGFzcyBJbXBsPgpQaW1wbDxIYW5kbGUsIEltcGw+Ojp+UGltcGwoKQp7CiAgICBfdW5tYWtlKGRfcHRyKTsKICAgIGRfcHRyID0gMDsKfQoKdGVtcGxhdGU8Y2xhc3MgSGFuZGxlLCBjbGFzcyBJbXBsPgpQaW1wbDxIYW5kbGUsIEltcGw+OjpQaW1wbChjb25zdCBQaW1wbCAmb3RoZXIpIDoKICBkX3B0cihfY2xvbmUob3RoZXIuZF9wdHIpKQp7Cgp9Cgp0ZW1wbGF0ZTxjbGFzcyBIYW5kbGUsIGNsYXNzIEltcGw+ClBpbXBsPEhhbmRsZSwgSW1wbD4gJlBpbXBsPEhhbmRsZSwgSW1wbD46Om9wZXJhdG9yPShjb25zdCBQaW1wbCAmb3RoZXIpCnsKCVBpbXBsIGNvcHkob3RoZXIpOwoJc3dhcChjb3B5KTsKCiAgICByZXR1cm4gKnRoaXM7Cn0KCmNsYXNzIE9iamVjdFByaXZhdGU7CgpjbGFzcyBPYmplY3QgOiBwcml2YXRlIFBpbXBsPE9iamVjdCwgT2JqZWN0UHJpdmF0ZT4KewpwdWJsaWM6CiAgICBPYmplY3QoKTsKICAgIH5PYmplY3QoKTsKfTsKCmludCBtYWluKCkgewoJLy8geW91ciBjb2RlIGdvZXMgaGVyZQoJcmV0dXJuIDA7Cn0=