120 lines
3.6 KiB
C++
120 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
namespace Hyprutils {
|
|
namespace Memory {
|
|
namespace Impl_ {
|
|
class impl_base {
|
|
public:
|
|
virtual ~impl_base() {};
|
|
|
|
virtual void inc() noexcept = 0;
|
|
virtual void dec() noexcept = 0;
|
|
virtual void incWeak() noexcept = 0;
|
|
virtual void decWeak() noexcept = 0;
|
|
virtual unsigned int ref() noexcept = 0;
|
|
virtual unsigned int wref() noexcept = 0;
|
|
virtual void destroy() noexcept = 0;
|
|
virtual bool destroying() noexcept = 0;
|
|
virtual bool dataNonNull() noexcept = 0;
|
|
virtual bool lockable() noexcept = 0;
|
|
virtual void* getData() noexcept = 0;
|
|
};
|
|
|
|
template <typename T>
|
|
class impl : public impl_base {
|
|
public:
|
|
impl(T* data, bool lock = true) noexcept : _lockable(lock), _data(data) {
|
|
;
|
|
}
|
|
|
|
/* strong refcount */
|
|
unsigned int _ref = 0;
|
|
/* weak refcount */
|
|
unsigned int _weak = 0;
|
|
/* if this is lockable (shared) */
|
|
bool _lockable = true;
|
|
|
|
T* _data = nullptr;
|
|
|
|
friend void swap(impl*& a, impl*& b) {
|
|
impl* tmp = a;
|
|
a = b;
|
|
b = tmp;
|
|
}
|
|
|
|
/* if the destructor was called,
|
|
creating shared_ptrs is no longer valid */
|
|
bool _destroying = false;
|
|
|
|
void _destroy() {
|
|
if (!_data || _destroying)
|
|
return;
|
|
|
|
// first, we destroy the data, but keep the pointer.
|
|
// this way, weak pointers will still be able to
|
|
// reference and use, but no longer create shared ones.
|
|
_destroying = true;
|
|
__deleter(_data);
|
|
// now, we can reset the data and call it a day.
|
|
_data = nullptr;
|
|
_destroying = false;
|
|
}
|
|
|
|
std::default_delete<T> __deleter{};
|
|
|
|
//
|
|
virtual void inc() noexcept {
|
|
_ref++;
|
|
}
|
|
|
|
virtual void dec() noexcept {
|
|
_ref--;
|
|
}
|
|
|
|
virtual void incWeak() noexcept {
|
|
_weak++;
|
|
}
|
|
|
|
virtual void decWeak() noexcept {
|
|
_weak--;
|
|
}
|
|
|
|
virtual unsigned int ref() noexcept {
|
|
return _ref;
|
|
}
|
|
|
|
virtual unsigned int wref() noexcept {
|
|
return _weak;
|
|
}
|
|
|
|
virtual void destroy() noexcept {
|
|
_destroy();
|
|
}
|
|
|
|
virtual bool destroying() noexcept {
|
|
return _destroying;
|
|
}
|
|
|
|
virtual bool lockable() noexcept {
|
|
return _lockable;
|
|
}
|
|
|
|
virtual bool dataNonNull() noexcept {
|
|
return _data != nullptr;
|
|
}
|
|
|
|
virtual void* getData() noexcept {
|
|
return _data;
|
|
}
|
|
|
|
virtual ~impl() {
|
|
destroy();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
}
|