#ifndef JES_REF_H #define JES_REF_H #include namespace jes { template class Ref { public: Ref(); Ref(T * ptr); Ref(const Ref & orig); Ref & operator=(const Ref & orig); Ref & operator=(T * ptr); ~Ref(); T & operator*() const { return *m_ptr; } T * operator->() const { return m_ptr; } bool is_null() const { return m_ptr == NULL; } bool operator==(const T * ptr) { return m_ptr == ptr; } bool operator!=(const T * ptr) { return m_ptr != ptr; } private: void clone_from(const Ref & orig); void destroy(); T * m_ptr; unsigned int * m_ref_count; }; template Ref::Ref() { m_ptr = NULL; m_ref_count = NULL; } template Ref::Ref(T * ptr) { m_ptr = ptr; m_ref_count = new unsigned int; *m_ref_count = 1u; } template Ref::Ref(const Ref & orig) { clone_from(orig); } template Ref & Ref::operator=(const Ref & orig) { destroy(); clone_from(orig); return *this; } template Ref & Ref::operator=(T * ptr) { destroy(); m_ptr = ptr; m_ref_count = new unsigned int; *m_ref_count = 1u; return *this; } template void Ref::clone_from(const Ref & orig) { this->m_ptr = orig.m_ptr; this->m_ref_count = orig.m_ref_count; if (m_ref_count != NULL) (*m_ref_count)++; } template Ref::~Ref() { destroy(); } template void Ref::destroy() { if (m_ref_count != NULL) { if (*m_ref_count <= 1u) { delete m_ptr; delete m_ref_count; } else { (*m_ref_count)--; } } } } #endif