#ifndef ALREADY_INCLUDED_2006_LIBD__LIST_ITERATOR_HH
#define ALREADY_INCLUDED_2006_LIBD__LIST_ITERATOR_HH
namespace dmp
{
template<class X>
class List_Iterator : private Single
{
rtti_same(List_Iterator);
POOL1;
private:
ptr<List<X> > private_list;
ptr<List_Node<X> > private_node;
protected:
///
/// NOTE: disables passing and returning by value
///
List_Iterator(const List_Iterator<X>& it) : Single(DCODE_LIST_ITERATOR)
{
ASSERT(&it != null);
private_list = it.private_list;
private_node = it.private_node;
}
private:
//List_Iterator& operator = (const List_Iterator<X>& it);
public:
///
/// HOW TO ITERATE:
///
/// for (ptr<Iterator<X> > it = list->get_first(); it->has_more(); it->advance())
/// {
/// cout << *it->get_data() << ' ';
/// }
///
/// OR: use a macro to simplify
///
/// for_list (X,it,list)
/// {
/// cout << *it->get_data() << ' ';
/// }
///
/// From the user's point of view there is no Node class as
/// all the methods are private.
///
bool has_more()
{
ASSERT(this != null);
return private_node != null;
}
void advance()
{
//BEGIN_FUNCTION();
ASSERT(this != null);
if (private_node == null)
{
///
/// NOTE: does nothing in the case that you are already at the end of the list
///
}
else
{
ptr<List_Node<X> > next = private_node->private_next;
//if (private_node->private_data == null)
if (private_node->private_deleteme)
{
private_node->delete_node();
}
private_node = next;
}
//END_FUNCTION();
}
void retreat()
{
//BEGIN_FUNCTION();
ASSERT(this != null);
if (private_node == null)
{
}
else
{
ptr<List_Node<X> > prev = private_node->private_previous;
//if (private_node->private_data == null)
if (private_node->private_deleteme)
{
private_node->delete_node();
}
private_node = prev;
}
//END_FUNCTION();
}
ptr<X> get_data() const /// CODE: HAZEL
{
ASSERT(this != null);
ASSERT(private_node != null);
return private_node->private_data;
}
void set_data(const ptr<X>& new_data)
{
ASSERT(this != null);
ASSERT(&new_data != null);
if (private_node == null)
{
should_never_happen();
}
else
{
private_node->private_data = new_data;
}
}
void delete_current()
{
ASSERT(this != null);
///
/// NOTE: double calls are okay
///
if (private_node != null)
{
private_node->private_deleteme = true;
}
}
///
/// Why do we need this?
///
ptr<List<X> > get_owner()
{
ASSERT(this != null);
return private_list;
}
void add_after(const ptr<X>& x)
{
ASSERT(this != null);
ASSERT(&x != null);
if (private_node == null)
{
should_never_happen();
}
else
{
private_node->add_after(x);
}
}
void add_before(const ptr<X>& x)
{
ASSERT(this != null);
ASSERT(&x != null);
if (private_node == null)
{
should_never_happen();
}
else
{
private_node->add_before(x);
}
}
///
/// NOTE: inverse of List_Iterator<X> List<X>::get_element_at(int index)
///
int get_index()
{
ASSERT(this != null);
if (private_list != null)
{
int index = 0;
for (ptr<List_Node<X> > n = private_list->private_first; n != null; n=n->private_next)
{
if (n == private_node)
{
return index;
}
index++;
}
}
return -1;
}
private:
List_Iterator(List<X>* list) : Single(DCODE_LIST_ITERATOR)
{
private_list = list;
if (private_list != null)
{
private_node = list->private_first;
}
}
List_Iterator(List_Node<X>* node) : Single(DCODE_LIST_ITERATOR)
{
if (node != null)
{
private_list = node->private_owner;
}
private_node = node;
}
private:
friend class List<X>;
///
/// Called only from List<X>::get_iterator()
///
static ptr<List_Iterator<X> > ctor(List<X>* list)
{
return new List_Iterator(list);
}
///
/// Called only from List<X>::get_element_at(int)
///
static ptr<List_Iterator<X> > ctor(List_Node<X>* node)
{
return new List_Iterator(node);
}
public:
///
/// NOTE: clones an existing iterator
///
// static ptr<List_Iterator<X> > clone(ptr<List_Iterator<X> > iter)
// {
// return new List_Iterator(iter->private_node);
// }
ptr<List_Iterator<X> > clone() const
{
return new List_Iterator(*this);
}
private:
template <class T> friend class ptr;
~List_Iterator()
{
if (this == null)
{
return;
}
///
/// NOTE: these are done automatically by this destructor
///
//private_list = null;
//private_node = null;
}
#ifdef DAVINS_IO_ONLINE
friend dmp::Writer& operator << (dmp::Writer& w, const List_Iterator<X>& iter)
{
ASSERT(&w != null);
if (&iter == null)
{
//w << "(&iter == null)";
w << "null";
}
else
{
w << iter.private_node;
//w << iter.get_ptr()->private_node;
}
return w;
}
#endif /* DAVINS_IO_ONLINE */
};
}
#endif /* ALREADY_INCLUDED_2006_LIBD__LIST_ITERATOR_HH */
| Back |