mirror of https://github.com/PrimeDecomp/prime.git
66 lines
1.6 KiB
C++
66 lines
1.6 KiB
C++
#ifndef _RSTL_RC_PTR
|
|
#define _RSTL_RC_PTR
|
|
|
|
#include "types.h"
|
|
#include "rstl/rmemory_allocator.hpp"
|
|
|
|
namespace rstl {
|
|
class CRefData {
|
|
public:
|
|
CRefData(const void* ptr) : x0_ptr(ptr), x4_refCount(1) {}
|
|
CRefData(const void* ptr, int refCount) : x0_ptr(ptr), x4_refCount(refCount) {}
|
|
~CRefData() {}
|
|
|
|
void* GetPtr() const { return const_cast< void* >(x0_ptr); }
|
|
int GetRefCount() const { return x4_refCount; }
|
|
int AddRef() { return ++x4_refCount; }
|
|
int DelRef() { return --x4_refCount; }
|
|
|
|
const void* x0_ptr;
|
|
int x4_refCount;
|
|
|
|
static CRefData sNull;
|
|
};
|
|
|
|
template < typename T >
|
|
class rc_ptr {
|
|
public:
|
|
rc_ptr() : x0_refData(&CRefData::sNull) { x0_refData->AddRef(); }
|
|
rc_ptr(const T* ptr) : x0_refData(rs_new CRefData(ptr)) {}
|
|
rc_ptr(const rc_ptr& other) : x0_refData(other.x0_refData) { x0_refData->AddRef(); }
|
|
~rc_ptr() { ReleaseData(); }
|
|
T* GetPtr() const { return static_cast< T* >(x0_refData->GetPtr()); }
|
|
void ReleaseData();
|
|
T* operator->() const { return GetPtr(); }
|
|
T& operator*() const { return *GetPtr(); }
|
|
operator bool() const { return GetPtr() != nullptr; }
|
|
|
|
private:
|
|
CRefData* x0_refData;
|
|
};
|
|
|
|
template < typename T >
|
|
void rc_ptr< T >::ReleaseData() {
|
|
if (x0_refData->DelRef() <= 0) {
|
|
delete GetPtr();
|
|
delete x0_refData;
|
|
}
|
|
}
|
|
|
|
template < typename T >
|
|
class ncrc_ptr : public rc_ptr< T > {
|
|
public:
|
|
ncrc_ptr() {}
|
|
ncrc_ptr(T* ptr) : rc_ptr< T >(ptr) {}
|
|
ncrc_ptr(const rc_ptr< T >& other) : rc_ptr< T >(other) {}
|
|
};
|
|
|
|
template < typename T >
|
|
bool operator==(const rc_ptr< T >& left, const rc_ptr< T >& right) {
|
|
return left.GetPtr() == right.GetPtr();
|
|
}
|
|
|
|
} // namespace rstl
|
|
|
|
#endif // _RSTL_RC_PTR
|