|
|
2fb9fd |
#ifndef HANDLE_H
|
|
|
2fb9fd |
#define HANDLE_H
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
#include <cassert></cassert>
|
|
|
2fb9fd |
|
|
|
2fb9fd |
#include <algorithm></algorithm>
|
|
|
2fb9fd |
#include <typeinfo></typeinfo>
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
class Shared {
|
|
|
2fb9fd |
private:
|
|
|
2fb9fd |
int refcount;
|
|
|
2fb9fd |
public:
|
|
|
2fb9fd |
Shared(): refcount(1) { }
|
|
|
2fb9fd |
Shared(const Shared&): refcount(1) { }
|
|
|
2fb9fd |
virtual ~Shared() { };
|
|
|
2fb9fd |
Shared& operator=(const Shared&) { return *this; }
|
|
|
2fb9fd |
void reference() { ++refcount; }
|
|
|
2fb9fd |
void unreference() { if (--refcount <= 0) delete this; }
|
|
|
2fb9fd |
int get_refcount() const { return refcount; }
|
|
|
2fb9fd |
};
|
|
|
2fb9fd |
|
|
|
2fb9fd |
class NoHandle { };
|
|
|
2fb9fd |
const NoHandle nohandle;
|
|
|
2fb9fd |
|
|
|
2fb9fd |
template<typename t=""></typename>
|
|
|
2fb9fd |
class HandleT
|
|
|
2fb9fd |
{
|
|
|
2fb9fd |
public:
|
|
|
2fb9fd |
typedef T Type;
|
|
|
2fb9fd |
|
|
|
2fb9fd |
protected:
|
|
|
2fb9fd |
Type *pointer;
|
|
|
2fb9fd |
|
|
|
2fb9fd |
public:
|
|
|
2fb9fd |
HandleT(): pointer() { }
|
|
|
2fb9fd |
HandleT(const NoHandle &): HandleT() { }
|
|
|
2fb9fd |
explicit HandleT(Type *pointer): HandleT() { set(pointer); }
|
|
|
2fb9fd |
HandleT(const HandleT &x): HandleT(x.get()) { }
|
|
|
2fb9fd |
HandleT(HandleT &&x): pointer(x.pointer) { x.pointer = 0; }
|
|
|
2fb9fd |
~HandleT() { reset(); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Type* get() const { return pointer; }
|
|
|
2fb9fd |
Type& getref() const { assert(pointer); return *pointer; }
|
|
|
2fb9fd |
Type& operator*() const { return getref(); }
|
|
|
2fb9fd |
Type* operator->() const { return &getref(); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
operator bool() const { return pointer; }
|
|
|
2fb9fd |
bool empty() const { return !pointer; }
|
|
|
2fb9fd |
int get_refcount() const { return pointer ? pointer->get_refcount() : 0; }
|
|
|
2fb9fd |
bool unique() const { return get_refcount() == 1; }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
bool operator<(const HandleT &x) const { return pointer < x.get(); }
|
|
|
2fb9fd |
bool operator==(const HandleT &x) const { return pointer == x.get(); }
|
|
|
2fb9fd |
bool operator!=(const HandleT &x) const { return pointer != x.get(); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
void set(Type *x) {
|
|
|
2fb9fd |
if (x != pointer) {
|
|
|
2fb9fd |
if (x) x->reference();
|
|
|
2fb9fd |
if (pointer) pointer->unreference();
|
|
|
2fb9fd |
pointer = x;
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
|
|
|
2fb9fd |
void swap(HandleT &x)
|
|
|
2fb9fd |
{ swap(pointer, x.pointer); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
void grab(HandleT &x) {
|
|
|
2fb9fd |
if (&x != this) {
|
|
|
2fb9fd |
if (pointer) pointer->unreference();
|
|
|
2fb9fd |
pointer = x.pointer;
|
|
|
2fb9fd |
x.pointer = 0;
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
|
|
|
2fb9fd |
void reset() { set(0); }
|
|
|
2fb9fd |
HandleT& operator=(const HandleT &x) { set(x.get()); return *this; }
|
|
|
2fb9fd |
HandleT& operator=(HandleT &&x) { grab(x); return *this; }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
template<typename tt=""> static HandleT cast(TT *x)</typename>
|
|
|
2fb9fd |
{ return HandleT<t>(dynamic_cast<t*>(x)); }</t*></t>
|
|
|
2fb9fd |
template<typename tt=""> static HandleT cast(const HandleT<tt> &x)</tt></typename>
|
|
|
2fb9fd |
{ return cast(x.get()); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
template<class tt=""> operator HandleT<tt>() const</tt></class>
|
|
|
2fb9fd |
{ return HandleT<tt>(pointer); }</tt>
|
|
|
2fb9fd |
|
|
|
2fb9fd |
template<typename tt=""> bool type_is() const</typename>
|
|
|
2fb9fd |
{ return cast<const tt*="">(pointer); }</const>
|
|
|
2fb9fd |
template<typename tt=""> TT* type_pointer() const</typename>
|
|
|
2fb9fd |
{ return dynamic_cast<tt*>(pointer); }</tt*>
|
|
|
2fb9fd |
template<typename tt=""> bool type_equal() const</typename>
|
|
|
2fb9fd |
{ return typeid(*pointer) == typeid(TT); }
|
|
|
2fb9fd |
};
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
#endif
|