/* * 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 list_element { public: list_element *right; list_element *left; list_element (T *in); T *data; }; template class ordered_list { private: list_element *head; list_element *tail; list_element *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 ordered_list::ordered_list() : head(0), tail(0), ptr(0) { } template ordered_list::~ordered_list() { list_element *temp=head; do { temp = head; if (temp != 0) { head = head->right; delete temp; } } while ((head != 0) && (head != tail)); } template list_element::list_element(T *in) : right(0), left(0) { data = in; } template void ordered_list::add(T *in) { list_element *t = new list_element(in); // create a new list element with data field initialized list_element *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 void ordered_list::sub_move_right (void) { list_element *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 void ordered_list::start_from_head (void) { ptr = head; } template void ordered_list::start_from_tail (void) { ptr = tail; } template int ordered_list::is_empty (void) { return( head == 0 ); } template int ordered_list::is_equal_to_tail (void) { return( ptr == tail ); } template int ordered_list::is_equal_to_head (void) { return( ptr == head ); } template void ordered_list::move_left (void) { ptr = ptr->left; } template void ordered_list::move_right (void) { ptr = ptr->right; } template T* ordered_list::get_data (void) { return( ptr->data ); } template T* ordered_list::move_right_get_data (void) { ptr = ptr->right; if (ptr == head) { return( 0 ); } else { return( ptr->data ); } } template T* ordered_list::move_left_get_data (void) { ptr = ptr->left; if (ptr == tail) { return( 0 ); } else { return( ptr->data ); } }