Skip to content

Commit

Permalink
add SharedPointer implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
4z0t committed Dec 5, 2024
1 parent 276b07f commit a130b41
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
106 changes: 106 additions & 0 deletions include/SharedPtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#pragma once
#include "global.h"

template <typename T>
class SharedPtr
{
private:
T *data = nullptr;

struct SharedLock
{
struct vtable_counted_base
{
void(__thiscall *dtr)(SharedLock *);
void(__thiscall *dispose)(SharedLock *);
void(__thiscall *destroy)(SharedLock *);
void *(__thiscall *get_deleter)(SharedLock *);
} *vtable;
unsigned use_count_;
unsigned weak_count_;
void *px_;
} *lock = nullptr;

public:
SharedPtr() : data{nullptr}, lock{nullptr}
{
}

SharedPtr(const SharedPtr &other)
{
data = other.data;
lock = other.lock;
Lock();
}

SharedPtr(SharedPtr &&other)
{
data = other.data;
lock = other.lock;
other.data = nullptr;
other.lock = nullptr;
}

SharedPtr &operator=(const SharedPtr<T> &other)
{
Release();
data = other.data;
lock = other.lock;
Lock();
}

SharedPtr &operator=(SharedPtr &&other)
{
Release();
data = other.data;
lock = other.lock;
other.data = nullptr;
other.lock = nullptr;
}

T *Get() const
{
return data;
}

bool Valid() const
{
return data != nullptr;
}

~SharedPtr()
{
Release();
}

void Release()
{
InternalRelease();
lock = nullptr;
data = nullptr;
}

private:
void InternalRelease()
{
if (!lock)
return;

if (InterlockedExchangeAdd(&lock->use_count_, -1))
return;

lock->vtable->dispose(lock);
if (InterlockedExchangeAdd(&lock->weak_count_, -1))
return;

lock->vtable->destroy(lock);
}

void Lock()
{
if (lock)
{
InterlockedExchangeAdd(&lock->use_count_, 1);
}
}
};
13 changes: 13 additions & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ struct Result {
inline bool IsFail() { return reason != nullptr; }
};

bool InterlockedExchangeAdd(volatile unsigned *addr, unsigned value)
{
bool _result;
asm(
"lock xadd [eax], edx;"
"setnz al;"
: "=a"(_result)
: "a"(addr),
"d"(value)
:);
return _result;
}

template <typename T>
T Offset(void *ptr, size_t offset)
{
Expand Down

0 comments on commit a130b41

Please sign in to comment.