Skip to content

Instantly share code, notes, and snippets.

@kostja
Created August 15, 2019 20:17
Show Gist options
  • Save kostja/14e34c96b7781632929f27c005f4e097 to your computer and use it in GitHub Desktop.
Save kostja/14e34c96b7781632929f27c005f4e097 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <new>
template <typename T>
struct lw_shared_ptr {
char *_mem;
void destroy() {
if (_mem != nullptr) {
int *counter = reinterpret_cast<int *>(_mem);
*counter -= 1;
if (*counter == 0) {
T *t = reinterpret_cast<T*>(_mem + alignof(int));
t->~T();
delete [] _mem;
}
_mem = nullptr;
}
}
template <typename U> void
init(lw_shared_ptr<U> &rhs) {
_mem = rhs._mem;
if (_mem != nullptr) {
int *counter = reinterpret_cast<int *>(_mem);
*counter += 1;
}
}
lw_shared_ptr(const T& t)
: _mem(new char[alignof(int) + sizeof(T)]) {
int *counter = reinterpret_cast<int *>(_mem);
*counter = 1;
T *place = reinterpret_cast<T*>(_mem + alignof(int));
new (place) T(t);
}
template <typename U>
lw_shared_ptr(lw_shared_ptr<U> &rhs) {
init(rhs);
}
template <typename U> lw_shared_ptr<T>& operator=(lw_shared_ptr<U> &rhs) {
destroy();
init(rhs);
return *this;
}
~lw_shared_ptr() {
destroy();
}
};
struct Base {
Base() {
printf("%p::Base()\n", this);
}
Base(const Base &)
{
printf("%p::Base(Base&)\n", this);
}
virtual ~Base() {
printf("%p::~Base()\n", this);
}
};
struct Derived: public Base {
Derived() {
printf("%p::Dervied()\n", this);
}
Derived(const Derived &) {
printf("%p::Dervied(Derived&)\n", this);
}
virtual ~Derived() {
printf("%p::~Dervied()\n", this);
}
};
int main() {
auto foo = lw_shared_ptr<Base>(Base());
auto bar = lw_shared_ptr<Derived>(Derived());
printf("foo = bar;\n");
foo = bar;
printf("return 0;\n");
return 0;
}
@kostja
Copy link
Author

kostja commented Aug 15, 2019

kostja@atlas ~ % g++ main2.cc; ./a.out
0x7ffe3a866800::Base()
0x55875c7a6284::Base(Base&)
0x7ffe3a866800::~Base()
0x7ffe3a866800::Base()
0x7ffe3a866800::Dervied()
0x55875c7a62a4::Base()
0x55875c7a62a4::Dervied(Derived&)
0x7ffe3a866800::~Dervied()
0x7ffe3a866800::~Base()
foo = bar;
0x55875c7a6284::~Base()
return 0;
0x55875c7a62a4::~Dervied()
0x55875c7a62a4::~Base()
kostja@atlas ~ %

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment