📄 clst.h
字号:
/********************************************************************** * File: clst.h (Formerly clist.h) * Description: CONS cell list module include file. * Author: Phil Cheatle * Created: Mon Jan 28 08:33:13 GMT 1991 * * (C) Copyright 1991, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#ifndef CLST_H#define CLST_H#include <stdio.h>#include "host.h"#include "serialis.h"#include "lsterr.h"class CLIST_ITERATOR;/********************************************************************** * CLASS - CLIST_LINK * * Generic link class for singly linked CONS cell lists * * Note: No destructor - elements are assumed to be destroyed EITHER after * they have been extracted from a list OR by the CLIST destructor which * walks the list. **********************************************************************/class DLLSYM CLIST_LINK{ friend class CLIST_ITERATOR; friend class CLIST; CLIST_LINK *next; void *data; public: CLIST_LINK() { //constructor data = next = NULL; } CLIST_LINK( //copy constructor const CLIST_LINK &) { //dont copy link data = next = NULL; } void operator= ( //dont copy links const CLIST_LINK &) { data = next = NULL; } NEWDELETE2 (CLIST_LINK) /* NOTE that none of the serialise member functions are required for CLIST_LINKS as they are never serialised. */};/********************************************************************** * CLASS - CLIST * * Generic list class for singly linked CONS cell lists **********************************************************************/class DLLSYM CLIST{ friend class CLIST_ITERATOR; CLIST_LINK *last; //End of list //(Points to head) CLIST_LINK *First() { // return first return last != NULL ? last->next : NULL; } public: CLIST() { //constructor last = NULL; } ~CLIST () { //destructor shallow_clear(); } void internal_deep_clear ( //destroy all links void (*zapper) (void *)); //ptr to zapper functn void shallow_clear(); //clear list but dont //delete data elements BOOL8 empty() { //is list empty? return !last; } BOOL8 singleton() { return last != NULL ? (last == last->next) : FALSE; } void shallow_copy( //dangerous!! CLIST *from_list) { //beware destructors!! last = from_list->last; } //ptr to copier functn void internal_deep_copy (void *(*copier) (void *), const CLIST * list); //list being copied void assign_to_sublist( //to this list CLIST_ITERATOR *start_it, //from list start CLIST_ITERATOR *end_it); //from list end INT32 length(); //# elements in list void sort ( //sort elements int comparator ( //comparison routine const void *, const void *)); void internal_dump ( //serialise each elem FILE * f, //to this file void element_serialiser ( //using this function FILE *, void *)); void internal_de_dump ( //de_serial each elem FILE * f, //from this file void *element_de_serialiser (//using this function FILE *)); void prep_serialise(); //change last to count /* Note that dump() and de_dump() are not required as calls to dump/de_dump a list class should be handled by a class derived from this. make_serialise is not required for a similar reason. */};/*********************************************************************** * CLASS - CLIST_ITERATOR * * Generic iterator class for singly linked lists with embedded links **********************************************************************/class DLLSYM CLIST_ITERATOR{ friend void CLIST::assign_to_sublist(CLIST_ITERATOR *, CLIST_ITERATOR *); CLIST *list; //List being iterated CLIST_LINK *prev; //prev element CLIST_LINK *current; //current element CLIST_LINK *next; //next element BOOL8 ex_current_was_last; //current extracted //was end of list BOOL8 ex_current_was_cycle_pt; //current extracted //was cycle point CLIST_LINK *cycle_pt; //point we are cycling //the list to. BOOL8 started_cycling; //Have we moved off //the start? CLIST_LINK *extract_sublist( //from this current... CLIST_ITERATOR *other_it); //to other current public: CLIST_ITERATOR() { //constructor list = NULL; } //unassigned list CLIST_ITERATOR( //constructor CLIST *list_to_iterate); void set_to_list( //change list CLIST *list_to_iterate); void add_after_then_move( //add after current & void *new_data); //move to new void add_after_stay_put( //add after current & void *new_data); //stay at current void add_before_then_move( //add before current & void *new_data); //move to new void add_before_stay_put( //add before current & void *new_data); //stay at current void add_list_after( //add a list & CLIST *list_to_add); //stay at current void add_list_before( //add a list & CLIST *list_to_add); //move to it 1st item void *data() { //get current data #ifdef _DEBUG if (!list) NO_LIST.error ("CLIST_ITERATOR::data", ABORT, NULL); if (!current) NULL_DATA.error ("CLIST_ITERATOR::data", ABORT, NULL); #endif return current->data; } void *data_relative( //get data + or - ... INT8 offset); //offset from current void *forward(); //move to next element void *extract(); //remove from list void *move_to_first(); //go to start of list void *move_to_last(); //go to end of list void mark_cycle_pt(); //remember current BOOL8 empty() { //is list empty? #ifdef _DEBUG if (!list) NO_LIST.error ("CLIST_ITERATOR::empty", ABORT, NULL); #endif return list->empty (); } BOOL8 current_extracted() { //current extracted? return !current; } BOOL8 at_first(); //Current is first? BOOL8 at_last(); //Current is last? BOOL8 cycled_list(); //Completed a cycle? void add_to_end( //add at end & void *new_data); //dont move void exchange( //positions of 2 links CLIST_ITERATOR *other_it); //other iterator INT32 length(); //# elements in list void sort ( //sort elements int comparator ( //comparison routine const void *, const void *));};/*********************************************************************** * CLIST_ITERATOR::set_to_list * * (Re-)initialise the iterator to point to the start of the list_to_iterate * over. **********************************************************************/inline void CLIST_ITERATOR::set_to_list( //change list CLIST *list_to_iterate) { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("CLIST_ITERATOR::set_to_list", ABORT, NULL); if (!list_to_iterate) BAD_PARAMETER.error ("CLIST_ITERATOR::set_to_list", ABORT, "list_to_iterate is NULL"); #endif list = list_to_iterate; prev = list->last; current = list->First (); next = current != NULL ? current->next : NULL; cycle_pt = NULL; //await explicit set started_cycling = FALSE; ex_current_was_last = FALSE; ex_current_was_cycle_pt = FALSE;}/*********************************************************************** * CLIST_ITERATOR::CLIST_ITERATOR * * CONSTRUCTOR - set iterator to specified list; **********************************************************************/inline CLIST_ITERATOR::CLIST_ITERATOR(CLIST *list_to_iterate) { set_to_list(list_to_iterate);}/*********************************************************************** * CLIST_ITERATOR::add_after_then_move * * Add a new element to the list after the current element and move the * iterator to the new element. **********************************************************************/inline void CLIST_ITERATOR::add_after_then_move( // element to add void *new_data) { CLIST_LINK *new_element; #ifdef _DEBUG if (!this) NULL_OBJECT.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL); if (!list) NO_LIST.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL); if (!new_data) BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_then_move", ABORT, "new_data is NULL"); #endif new_element = new CLIST_LINK; new_element->data = new_data; if (list->empty ()) { new_element->next = new_element; list->last = new_element; prev = next = new_element; } else { new_element->next = next; if (current) { //not extracted current->next = new_element; prev = current; if (current == list->last) list->last = new_element; } else { //current extracted prev->next = new_element; if (ex_current_was_last) list->last = new_element; if (ex_current_was_cycle_pt) cycle_pt = new_element; } } current = new_element;}/*********************************************************************** * CLIST_ITERATOR::add_after_stay_put * * Add a new element to the list after the current element but do not move * the iterator to the new element. **********************************************************************/inline void CLIST_ITERATOR::add_after_stay_put( // element to add void *new_data) { CLIST_LINK *new_element; #ifdef _DEBUG if (!this) NULL_OBJECT.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL); if (!list) NO_LIST.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL); if (!new_data)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -