jes-ruby/src/Ref.h

105 lines
2.1 KiB
C++

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