Add utilities and static checks to Handle
This commit is contained in:
parent
5dd26e3ce0
commit
6a6e771478
@ -20,6 +20,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "Debug.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
@ -49,6 +52,9 @@ namespace spades {
|
||||
|
||||
public:
|
||||
Handle(T *ptr, bool add = true) : ptr(ptr) {
|
||||
static_assert(std::is_base_of<RefCountedObject, T>::value,
|
||||
"T is not based on RefCountedObject");
|
||||
|
||||
if (ptr && add)
|
||||
ptr->AddRef();
|
||||
}
|
||||
@ -57,10 +63,20 @@ namespace spades {
|
||||
if (ptr)
|
||||
ptr->AddRef();
|
||||
}
|
||||
Handle(Handle<T> &&h) : ptr(h.MaybeUnmanage()) {}
|
||||
|
||||
template <class S> Handle(Handle<S> &&h) : ptr(h.MaybeUnmanage()) {}
|
||||
|
||||
~Handle() {
|
||||
if (ptr)
|
||||
ptr->Release();
|
||||
}
|
||||
|
||||
template <class... Args> static Handle New(Args &&... args) {
|
||||
T *ptr = new T{std::forward<Args>(args)...};
|
||||
return {ptr, false};
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
SPAssert(ptr != NULL);
|
||||
return ptr;
|
||||
@ -99,6 +115,32 @@ namespace spades {
|
||||
ptr = NULL;
|
||||
return p;
|
||||
}
|
||||
T *MaybeUnmanage() {
|
||||
T *p = ptr;
|
||||
ptr = NULL;
|
||||
return p;
|
||||
}
|
||||
operator bool() { return ptr != NULL; }
|
||||
|
||||
/**
|
||||
* Attempts to cast this `Handle<T>` to `Handle<S>` using `dynamic_cast`, consuming this
|
||||
* `Handle<T>`. Throws an exception if the cast was unsuccessful.
|
||||
*/
|
||||
template <class S> Handle<S> Cast() && {
|
||||
static_assert(std::is_base_of<RefCountedObject, S>::value,
|
||||
"S is not based on RefCountedObject");
|
||||
|
||||
if (!ptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
S *other = dynamic_cast<S *>(ptr);
|
||||
if (!other) {
|
||||
SPRaise("Invalid cast from %s to %s", typeid(ptr).name(), typeid(S).name());
|
||||
}
|
||||
|
||||
ptr = nullptr;
|
||||
return {other, false};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user