diff --git a/handle.cpp b/handle.cpp new file mode 100644 index 0000000..6827fac --- /dev/null +++ b/handle.cpp @@ -0,0 +1,11 @@ + +#include "handle.h" + + + +Shared::~Shared() { + assert(!counter->ptrRefCount); + if (!--counter->refCount) delete counter; +} + + diff --git a/handle.h b/handle.h new file mode 100644 index 0000000..2d3e14e --- /dev/null +++ b/handle.h @@ -0,0 +1,220 @@ +#ifndef HANDLE_H +#define HANDLE_H + + +#include + +#include +#include + + + +class Shared; + + + +class Counter { +private: + friend class Shared; + friend class HandleBase; + friend class WeakHandleBase; + + typedef unsigned int Type; + std::atomic refCount; + std::atomic ptrRefCount; + Shared* pointer; + + inline explicit Counter(Shared &shared): refCount(1), ptrRefCount(0), pointer(&shared) { } + inline ~Counter() { assert(!refCount && !ptrRefCount); } +}; + + + +class Shared { +private: + friend class HandleBase; + friend class WeakHandleBase; + Counter *counter; + +public: + inline Shared(): counter(new Counter(*this)) { } + virtual ~Shared(); +}; + + + +class WeakHandleBase { +private: + friend class HandleBase; + Counter* counter; + + inline void set(Counter* counter) { + if (this->counter == counter) return; + if (counter) counter->refCount++; + if (this->counter && !--this->counter->refCount) delete this->counter; + this->counter = counter; + } + +protected: + inline WeakHandleBase(): counter() { } + void set(Shared* pointer) { set(pointer ? pointer->counter : nullptr); } + void set(const WeakHandleBase &other) { set(other.counter); } + void swap(WeakHandleBase &other) { std::swap(counter, other.counter); } + +public: + inline ~WeakHandleBase() + { reset(); } + inline void reset() + { return set((Counter*)nullptr); } + inline bool operator<(const WeakHandleBase &other) const + { return counter < other.counter; } +}; + + + +class HandleBase { +private: + Shared *pointer; + +protected: + inline HandleBase(): pointer() { } + + inline void set(Shared *pointer) { + if (this->pointer == pointer) return; + if (pointer) pointer->counter->ptrRefCount++; + if (this->pointer && !--this->pointer->counter->ptrRefCount) delete this->pointer; + this->pointer = pointer; + } + + inline void set(const WeakHandleBase &weak) { + Counter *counter = weak.counter; + if (!counter) { set((Shared*)nullptr); return; } + if (pointer && pointer->counter == counter) return; + + Shared *pointer = nullptr; + Counter::Type cnt = counter->refCount; + while(cnt) + if (counter->ptrRefCount.compare_exchange_weak(cnt, cnt+1)) + { pointer = counter->pointer; break; } + + if (this->pointer && !--this->pointer->counter->ptrRefCount) delete this->pointer; + this->pointer = pointer; + } + + inline void swap(HandleBase &other) { std::swap(pointer, other.pointer); } + + inline Shared* get() const + { return pointer; } + +public: + inline ~HandleBase() + { reset(); } + + inline void reset() + { return set((Shared*)nullptr); } + inline operator bool() const + { return pointer; } + inline bool operator<(const HandleBase &other) const + { return pointer < other.pointer; } + + inline bool operator==(const HandleBase &other) const + { return pointer == other.pointer; } + inline bool operator==(const Shared *pointer) const + { return this->pointer == pointer; } + inline friend bool operator==(const Shared *pointer, const HandleBase &handle) + { return pointer == handle.pointer; } + + inline bool operator!=(const HandleBase &other) const + { return pointer != other.pointer; } + inline bool operator!=(const Shared *pointer) const + { return this->pointer != pointer; } + inline friend bool operator!=(const Shared *pointer, const HandleBase &handle) + { return pointer != handle.pointer; } +}; + + + +template class Handle; + + +template +class WeakHandle: public WeakHandleBase { +public: + typedef T Type; + typedef Handle Handle; + +private: + inline void typeChecker(const Type*) { } + +public: + inline WeakHandle() { } + inline WeakHandle(WeakHandle &&other) { WeakHandleBase::swap(other); } + inline WeakHandle(const WeakHandle &other) { WeakHandleBase::set(other.get()); } + inline explicit WeakHandle(const Handle &handle) { WeakHandleBase::set(handle.pointer()); } + inline explicit WeakHandle(Type *pointer) { WeakHandleBase::set(pointer); } + + inline WeakHandle& operator=(WeakHandle &&other) + { WeakHandleBase::swap(other); return *this; } + inline WeakHandle& operator=(const WeakHandle &other) + { WeakHandleBase::set(other); return *this; } + inline WeakHandle& operator=(const Handle &handle) + { WeakHandleBase::set(handle.pointer()); return *this; } + inline WeakHandle& operator=(Type *pointer) + { WeakHandleBase::set(pointer); return *this; } + + inline void swap(WeakHandle &other) + { WeakHandleBase::swap(other); return *this; } + + template + inline operator WeakHandle&() + { typeChecker((TT*)nullptr); return *reinterpret_cast*>(this); } + template + inline operator const WeakHandle&() const + { typeChecker((TT*)nullptr); return *reinterpret_cast*>(this); } +}; + + + +template +class Handle: public HandleBase { +public: + typedef T Type; + typedef WeakHandle Weak; + +private: + inline void typeChecker(const Type*) { } + +public: + inline Handle() { } + inline Handle(Handle &&other) { HandleBase::swap(other); } + inline Handle(const Handle &other) { HandleBase::set(other.get()); } + inline explicit Handle(const Weak &weak) { HandleBase::set(weak); } + inline explicit Handle(Type *pointer) { HandleBase::set(pointer); } + + inline Handle& operator=(Handle &&other) + { HandleBase::swap(other); return *this; } + inline Handle& operator=(const Handle &other) + { HandleBase::set(other.get()); return *this; } + inline Handle& operator=(const Weak &weak) + { HandleBase::set(weak); return *this; } + inline Handle& operator=(Type *pointer) + { HandleBase::set(pointer); return *this; } + + inline void swap(Handle &other) + { HandleBase::swap(other); return *this; } + + inline Type* pointer() const { return (Type*)HandleBase::get(); } + inline Type* operator->() const { return get(); } + inline Type& operator*() const { return *get(); } + + template + inline operator Handle&() + { typeChecker((TT*)nullptr); return *reinterpret_cast*>(this); } + template + inline operator const Handle&() const + { typeChecker((TT*)nullptr); return *reinterpret_cast*>(this); } +}; + + + +#endif diff --git a/socket.h b/socket.h deleted file mode 100644 index a508e8c..0000000 --- a/socket.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SOCKET_H -#define SOCKET_H - - - - - -#endif diff --git a/tcpprotocol.h b/tcpprotocol.h new file mode 100644 index 0000000..a508e8c --- /dev/null +++ b/tcpprotocol.h @@ -0,0 +1,8 @@ +#ifndef SOCKET_H +#define SOCKET_H + + + + + +#endif