#include <memory>
#include <iostream>
template<typename T, typename TPtr>
struct Deep
{
TPtr ptr;
Deep() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
};
template<typename T, typename TPtr>
struct Shallow
{
TPtr ptr;
Shallow() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Shallow(const Shallow& other) = default;
};
template<typename T>
using raw_ptr = T*;
template<typename T>
void test(const T& a1)
{
auto a2 = a1;
a2.set(a2.get() + 1);
std::cout << a1.get() << " " << a2.get() << std::endl;
}
using std::shared_ptr;
int main()
{
Deep<int, raw_ptr<int> > rawDeep;
rawDeep.set(1);
test(rawDeep);
Deep<int, shared_ptr<int> > sharedDeep;
sharedDeep.set(1);
test(sharedDeep);
Shallow<int, raw_ptr<int> > rawShallow;
rawShallow.set(1);
test(rawShallow);
Shallow<int, shared_ptr<int> > sharedShallow;
sharedShallow.set(1);
test(sharedShallow);
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVFB0cj4Kc3RydWN0IERlZXAKewoJVFB0ciBwdHI7CgkKCURlZXAoKSA6IHB0cihuZXcgVCkge30KCQoJVCBnZXQoKSBjb25zdCB7IHJldHVybiAqcHRyOyB9Cgl2b2lkIHNldChUIHQpIHsgKnB0ciA9IHQ7IH0KCQoJRGVlcChjb25zdCBEZWVwJiBvdGhlcik6IHB0cihuZXcgVCgqb3RoZXIucHRyKSkge30KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFRQdHI+CnN0cnVjdCBTaGFsbG93CnsKCVRQdHIgcHRyOwoJCglTaGFsbG93KCkgOiBwdHIobmV3IFQpIHt9CgkKCVQgZ2V0KCkgY29uc3QgeyByZXR1cm4gKnB0cjsgfQoJdm9pZCBzZXQoVCB0KSB7ICpwdHIgPSB0OyB9CgkKCVNoYWxsb3coY29uc3QgU2hhbGxvdyYgb3RoZXIpID0gZGVmYXVsdDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnVzaW5nIHJhd19wdHIgPSBUKjsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnZvaWQgdGVzdChjb25zdCBUJiBhMSkKewoJYXV0byBhMiA9IGExOwoJYTIuc2V0KGEyLmdldCgpICsgMSk7CglzdGQ6OmNvdXQgPDwgYTEuZ2V0KCkgPDwgIiAiIDw8IGEyLmdldCgpIDw8IHN0ZDo6ZW5kbDsJCn0KCnVzaW5nIHN0ZDo6c2hhcmVkX3B0cjsKCmludCBtYWluKCkKewoJRGVlcDxpbnQsIHJhd19wdHI8aW50PiA+IHJhd0RlZXA7CglyYXdEZWVwLnNldCgxKTsKCXRlc3QocmF3RGVlcCk7CgkKCURlZXA8aW50LCBzaGFyZWRfcHRyPGludD4gPiBzaGFyZWREZWVwOwoJc2hhcmVkRGVlcC5zZXQoMSk7Cgl0ZXN0KHNoYXJlZERlZXApOwoJCglTaGFsbG93PGludCwgcmF3X3B0cjxpbnQ+ID4gcmF3U2hhbGxvdzsKCXJhd1NoYWxsb3cuc2V0KDEpOwoJdGVzdChyYXdTaGFsbG93KTsKCQoJU2hhbGxvdzxpbnQsIHNoYXJlZF9wdHI8aW50PiA+IHNoYXJlZFNoYWxsb3c7CglzaGFyZWRTaGFsbG93LnNldCgxKTsKCXRlc3Qoc2hhcmVkU2hhbGxvdyk7Cn0=