#include <iostream>
#include <utility>
#include <cstddef>
template <typename T>
struct my_shared_ptr
{
my_shared_ptr() : rc(0) {}
template <typename... Args>
my_shared_ptr(Args&&... args)
: rc(new refcount_block(std::forward<Args>(args)...))
{}
T& operator * ()
{
return *rc->ptr();
}
T* operator -> ()
{
return rc->ptr();
}
~my_shared_ptr()
{
if(!--rc->refs)
delete rc;
}
private:
struct refcount_block
{
template <typename... Args>
refcount_block(Args&&... args)
: refs(1)
{
new (object) T(std::forward<Args>(args)...);
}
~refcount_block()
{
ptr()->~T();
}
T* ptr()
{
return reinterpret_cast<T*>(object);
}
std::size_t refs;
char object[sizeof(T)]; // alignas(T)
};
refcount_block* rc;
};
int main()
{
std::cout << sizeof(int*) << '\n'
<< sizeof(my_shared_ptr<int>) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGNzdGRkZWY+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IG15X3NoYXJlZF9wdHIKewoJbXlfc2hhcmVkX3B0cigpIDogcmMoMCkge30KCgl0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KCW15X3NoYXJlZF9wdHIoQXJncyYmLi4uIGFyZ3MpCgkJOiByYyhuZXcgcmVmY291bnRfYmxvY2soc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKSkKCXt9CgoJVCYgb3BlcmF0b3IgKiAoKQoJewoJCXJldHVybiAqcmMtPnB0cigpOwoJfQoKCVQqIG9wZXJhdG9yIC0+ICgpCgl7CgkJcmV0dXJuIHJjLT5wdHIoKTsKCX0KCgl+bXlfc2hhcmVkX3B0cigpCgl7CgkJaWYoIS0tcmMtPnJlZnMpCgkJCWRlbGV0ZSByYzsKCX0KCnByaXZhdGU6CglzdHJ1Y3QgcmVmY291bnRfYmxvY2sKCXsKCQl0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KCQlyZWZjb3VudF9ibG9jayhBcmdzJiYuLi4gYXJncykKCQkJOiByZWZzKDEpCgkJewoJCQluZXcgKG9iamVjdCkgVChzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwoJCX0KCgkJfnJlZmNvdW50X2Jsb2NrKCkKCQl7CgkJCXB0cigpLT5+VCgpOwoJCX0KCgkJVCogcHRyKCkKCQl7CgkJCXJldHVybiByZWludGVycHJldF9jYXN0PFQqPihvYmplY3QpOwoJCX0KCgkJc3RkOjpzaXplX3QgcmVmczsKCQljaGFyIG9iamVjdFtzaXplb2YoVCldOyAvLyBhbGlnbmFzKFQpCgl9OwoKCXJlZmNvdW50X2Jsb2NrKiByYzsKfTsKCmludCBtYWluKCkKewoJc3RkOjpjb3V0IDw8IHNpemVvZihpbnQqKSAgICAgICAgICAgICAgICAgPDwgJ1xuJwoJICAgICAgICAgIDw8IHNpemVvZihteV9zaGFyZWRfcHRyPGludD4pICAgPDwgJ1xuJzsKfQ==