#ifndef ALREADY_INCLUDED_2006_LIBD_PTR_HH
#define ALREADY_INCLUDED_2006_LIBD_PTR_HH
namespace dmp
{
template<class X>
final class ptr
{
private:
X* inner_ptr;
public:
ptr()
{
inner_ptr = null;
}
ptr(const ptr& p)
{
ASSERT(&p != null);
inner_ptr = p.inner_ptr;
if (inner_ptr != null)
{
inner_ptr->_ref_count++;
}
}
ptr& operator = (const ptr& p)
{
ASSERT(this != null);
ASSERT(&p != null);
if (p != null) {
p.inner_ptr->_ref_count++;
}
if (inner_ptr != null)
{
assert(inner_ptr->_ref_count > 0); inner_ptr->_ref_count--;
if (inner_ptr->_ref_count == 0)
{
inner_ptr->_ref_count = 1; delete inner_ptr;
}
}
if (p == null)
{
inner_ptr = null;
}
else
{
inner_ptr = p.inner_ptr;
}
return *this;
}
~ptr()
{
ASSERT(this != null);
#ifdef ALLEGRO_ONLINE
if (!allegro_on)
{
return;
}
#endif
ASSERT(this != null);
if (inner_ptr != null)
{
assert(inner_ptr->_ref_count > 0); inner_ptr->_ref_count--;
if (inner_ptr->_ref_count == 0)
{
inner_ptr->_ref_count = 1; delete inner_ptr;
}
#ifndef NDEBUG
inner_ptr = null;
#endif
}
}
ptr(X* x)
{
inner_ptr = x;
if (inner_ptr != null)
{
inner_ptr->_ref_count++;
}
}
X* operator -> () const
{
ASSERT(this != null);
ASSERT(inner_ptr != null);
return inner_ptr;
}
X& operator * () const
{
ASSERT(this != null);
ASSERT(inner_ptr != null);
return *inner_ptr;
}
X* get_ptr() const
{
ASSERT(this != null);
return inner_ptr;
}
friend bool operator == (const ptr& p1, const ptr& p2)
{
if ((&p1 == null) && (&p2 == null))
{
return true;
}
else if ((&p1 == null) || (&p2 == null))
{
return false;
}
else
{
return (p1.inner_ptr == p2.inner_ptr);
}
}
friend bool operator != (const ptr& p1, const ptr& p2)
{
return !(p1 == p2);
}
#ifdef DAVINS_IO_ONLINE
friend dmp::string_buffer operator + (const dmp::string& str, const ptr& p)
{
dmp::string_buffer sb;
sb << str;
sb << p.inner_ptr;
return sb;
}
friend dmp::string_buffer operator + (const dmp::string_buffer& csb, const ptr& p)
{
dmp::string_buffer sb = const_cast<dmp::string_buffer&>(csb);
sb << p.inner_ptr;
return sb;
}
friend dmp::Writer& operator << (dmp::Writer& w, const ptr<X>& p)
{
ASSERT(&w != null);
ASSERT(&p != null);
if (p.inner_ptr == null)
{
w << "null";
}
else
{
w << *(p.inner_ptr);
}
return w;
}
friend dmp::Reader& operator >> (dmp::Reader& r, ptr<X>& p)
{
ASSERT(&r != null);
ASSERT(&p != null);
if (r.looking_at("null"))
{
p = null;
r.next_token(); }
else
{
r >> *(p.inner_ptr);
}
return r;
}
#endif
};
}
#endif