/* -*- c++ -*-
C++ empty pointer classes
This file is part of the dpp library of C++ template classes
doc: http://diaxen.ssji.net/dpp/index.html
repo: https://www.ssji.net/svn/projets/trunk/libdpp
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
.
(c) 2008-2011 Alexandre Becoulet
*/
#ifndef DPP_EMPTY_REF_HH_
#define DPP_EMPTY_REF_HH_
/** @file @module{Empty pointer} */
namespace dpp {
template class weak_ptr_base;
template class weak_ptr;
/**
@internal
*/
class weak_ptr_node
{
template friend class weak_ptr_base;
template friend class weak_ptr;
void init()
{
m_prev = m_next = this;
}
void add(weak_ptr_node *n)
{
n->m_prev = this;
m_next->m_prev = n;
n->m_next = m_next;
m_next = n;
}
void remove()
{
m_prev->m_next = m_next;
m_next->m_prev = m_prev;
}
weak_ptr_node *m_next;
weak_ptr_node *m_prev;
};
/**
@short Empty pointer object base class
@module{Empty pointer}
@header dpp/weak_ptr
@This is the referenced object base class, any class which
inherits from this class can be pointed to by an @ref weak_ptr
pointer.
*/
template
class weak_ptr_base : public weak_ptr_node
{
template friend class weak_ptr;
typedef X _dpp_weak_ptr_type;
public:
weak_ptr_base()
{
weak_ptr_node::init();
}
~weak_ptr_base()
{
for (weak_ptr_node *n = weak_ptr_node::m_next;
n != (weak_ptr_node*)this; n = n->m_next)
static_cast*>(n)->_obj = 0;
}
};
/**
@short Empty pointer class
@module{Empty pointer}
@header dpp/weak_ptr
@main
@This implements a pointer class which is automatically set to 0
when the associated object is deleted.
All pointers to the same object are linked together and
this list is used to clear all pointers from object
destructor. Object class must inherit from the @ref
weak_ptr_base class.
@example test/test_weak_ptr.cc:1
*/
template
class weak_ptr : public weak_ptr_node
{
template friend class weak_ptr_base;
public:
weak_ptr()
: _obj(0)
{
}
weak_ptr(X *o)
: _obj(o)
{
const_cast(_obj)->add(this);
}
~weak_ptr()
{
if (_obj)
weak_ptr_node::remove();
}
weak_ptr & operator=(X *o)
{
if (_obj)
weak_ptr_node::remove();
_obj = o;
if (_obj)
const_cast(_obj)->add(this);
return *this;
}
X & operator*() const
{
return *_obj;
}
X * operator->() const
{
return _obj;
}
operator X* () const
{
return _obj;
}
private:
X *_obj;
};
}
#endif