Blame c++/vector/handle.h

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