freebsd-skq/contrib/groff/grohtml/ordered_list.h
2000-01-12 09:51:43 +00:00

194 lines
3.9 KiB
C++

/*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Ordered list, a template module for simple ordered list manipulation.
*
* Gaius Mulley (gaius@glam.ac.uk)
*/
template <class T> class list_element
{
public:
list_element *right;
list_element *left;
list_element (T *in);
T *data;
};
template <class T> class ordered_list
{
private:
list_element<T> *head;
list_element<T> *tail;
list_element<T> *ptr;
public:
ordered_list (void);
~ ordered_list (void);
void add (T* in);
void sub_move_right (void);
void move_right (void);
void move_left (void);
int is_empty (void);
int is_equal_to_tail (void);
int is_equal_to_head (void);
void start_from_head (void);
void start_from_tail (void);
T *move_right_get_data (void);
T *move_left_get_data (void);
T *get_data (void);
};
template <class T> ordered_list<T>::ordered_list()
: head(0), tail(0), ptr(0)
{
}
template <class T> ordered_list<T>::~ordered_list()
{
list_element<T> *temp=head;
do {
temp = head;
if (temp != 0) {
head = head->right;
delete temp;
}
} while ((head != 0) && (head != tail));
}
template <class T> list_element<T>::list_element(T *in)
: right(0), left(0)
{
data = in;
}
template <class T> void ordered_list<T>::add(T *in)
{
list_element<T> *t = new list_element<T>(in); // create a new list element with data field initialized
list_element<T> *last;
if (in == 0) {
fatal("cannot add NULL to ordered list");
}
if (head == 0) {
head = t;
tail = t;
t->left = t;
t->right = t;
} else {
last = tail;
while ((last != head) && (in->is_less(in, last->data))) {
last = last->left;
}
if (in->is_less(in, last->data)) {
t->right = last;
last->left->right = t;
t->left = last->left;
last->left = t;
// now check for a new head
if (last == head) {
head = t;
}
} else {
// add t onto beyond last
t->right = last->right;
t->left = last;
last->right->left = t;
last->right = t;
// now check for a new tail
if (last == tail) {
tail = t;
}
}
}
}
template <class T> void ordered_list<T>::sub_move_right (void)
{
list_element<T> *t=ptr->right;
if (head == tail) {
head = 0;
if (tail != 0) {
delete tail;
}
tail = 0;
ptr = 0;
} else {
if (head == ptr) {
head = head->right;
}
if (tail == ptr) {
tail = tail->left;
}
ptr->left->right = ptr->right;
ptr->right->left = ptr->left;
ptr=t;
}
}
template <class T> void ordered_list<T>::start_from_head (void)
{
ptr = head;
}
template <class T> void ordered_list<T>::start_from_tail (void)
{
ptr = tail;
}
template <class T> int ordered_list<T>::is_empty (void)
{
return( head == 0 );
}
template <class T> int ordered_list<T>::is_equal_to_tail (void)
{
return( ptr == tail );
}
template <class T> int ordered_list<T>::is_equal_to_head (void)
{
return( ptr == head );
}
template <class T> void ordered_list<T>::move_left (void)
{
ptr = ptr->left;
}
template <class T> void ordered_list<T>::move_right (void)
{
ptr = ptr->right;
}
template <class T> T* ordered_list<T>::get_data (void)
{
return( ptr->data );
}
template <class T> T* ordered_list<T>::move_right_get_data (void)
{
ptr = ptr->right;
if (ptr == head) {
return( 0 );
} else {
return( ptr->data );
}
}
template <class T> T* ordered_list<T>::move_left_get_data (void)
{
ptr = ptr->left;
if (ptr == tail) {
return( 0 );
} else {
return( ptr->data );
}
}