#include <cassert>
#ifndef NDEBUG
#include <typeinfo>
#endif
class shape
{
public :
virtual ~shape( ) { }
shape* clone( ) const
{
shape* const p = do_clone( ) ;
assert ( p && "do_clone must not return a null pointer" ) ;
assert (
typeid ( * p) == typeid ( * this )
&& "do_clone must return a pointer to an object of the same type"
) ;
return p;
}
private :
virtual shape* do_clone( ) const = 0 ;
} ;
template < class D>
class cloneable_shape : public shape
{
private :
virtual cloneable_shape* do_clone( ) const
{
return new D( static_cast < D const & > ( * this ) ) ;
}
} ;
class triangle : public cloneable_shape< triangle>
{
} ;
class square : public cloneable_shape< square>
{
} ;
I2luY2x1ZGUgPGNhc3NlcnQ+CiNpZm5kZWYgTkRFQlVHCiNpbmNsdWRlIDx0eXBlaW5mbz4KI2VuZGlmCiAKY2xhc3Mgc2hhcGUKewpwdWJsaWM6Cgl2aXJ0dWFsIH5zaGFwZSgpIHsgfQoKCXNoYXBlKiBjbG9uZSgpIGNvbnN0Cgl7CgkJc2hhcGUqIGNvbnN0IHAgPSBkb19jbG9uZSgpOwoJCWFzc2VydChwICYmICJkb19jbG9uZSBtdXN0IG5vdCByZXR1cm4gYSBudWxsIHBvaW50ZXIiKTsKCQlhc3NlcnQoCgkJCXR5cGVpZCgqcCkgPT0gdHlwZWlkKCp0aGlzKQoJCQkmJiAiZG9fY2xvbmUgbXVzdCByZXR1cm4gYSBwb2ludGVyIHRvIGFuIG9iamVjdCBvZiB0aGUgc2FtZSB0eXBlIgoJCSk7CgkJcmV0dXJuIHA7Cgl9CiAKcHJpdmF0ZToKCXZpcnR1YWwgc2hhcGUqIGRvX2Nsb25lKCkgY29uc3QgPSAwOwp9OwogCnRlbXBsYXRlPGNsYXNzIEQ+CmNsYXNzIGNsb25lYWJsZV9zaGFwZSA6IHB1YmxpYyBzaGFwZQp7CnByaXZhdGU6Cgl2aXJ0dWFsIGNsb25lYWJsZV9zaGFwZSogZG9fY2xvbmUoKSBjb25zdAoJewoJCXJldHVybiBuZXcgRChzdGF0aWNfY2FzdDxEIGNvbnN0Jj4oKnRoaXMpKTsKCX0KfTsKIApjbGFzcyB0cmlhbmdsZSA6IHB1YmxpYyBjbG9uZWFibGVfc2hhcGU8dHJpYW5nbGU+CnsKfTsKIApjbGFzcyBzcXVhcmUgOiBwdWJsaWMgY2xvbmVhYmxlX3NoYXBlPHNxdWFyZT4Kewp9Owo=