📄 elst.h
字号:
**********************************************************************/inline BOOL8 ELIST_ITERATOR::cycled_list() { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST_ITERATOR::cycled_list", ABORT, NULL); if (!list) NO_LIST.error ("ELIST_ITERATOR::cycled_list", ABORT, NULL); #endif return ((list->empty ()) || ((current == cycle_pt) && started_cycling));}/*********************************************************************** * ELIST_ITERATOR::length() * * Return the length of the list * **********************************************************************/inline INT32 ELIST_ITERATOR::length() { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST_ITERATOR::length", ABORT, NULL); if (!list) NO_LIST.error ("ELIST_ITERATOR::length", ABORT, NULL); #endif return list->length ();}/*********************************************************************** * ELIST_ITERATOR::sort() * * Sort the elements of the list, then reposition at the start. * **********************************************************************/inline voidELIST_ITERATOR::sort ( //sort elementsint comparator ( //comparison routineconst void *, const void *)) { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST_ITERATOR::sort", ABORT, NULL); if (!list) NO_LIST.error ("ELIST_ITERATOR::sort", ABORT, NULL); #endif list->sort (comparator); move_to_first();}/*********************************************************************** * ELIST_ITERATOR::add_to_end * * Add a new element to the end of the list without moving the iterator. * This is provided because a single linked list cannot move to the last as * the iterator couldn't set its prev pointer. Adding to the end is * essential for implementing queues.**********************************************************************/inline void ELIST_ITERATOR::add_to_end( // element to add ELIST_LINK *new_element) { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL); if (!list) NO_LIST.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL); if (!new_element) BAD_PARAMETER.error ("ELIST_ITERATOR::add_to_end", ABORT, "new_element is NULL"); if (new_element->next) STILL_LINKED.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL); #endif if (this->at_last ()) { this->add_after_stay_put (new_element); } else { if (this->at_first ()) { this->add_before_stay_put (new_element); list->last = new_element; } else { //Iteratr is elsewhere new_element->next = list->last->next; list->last->next = new_element; list->last = new_element; } }}/*********************************************************************** ******************** MACROS ************************************** ***********************************************************************//*********************************************************************** QUOTE_IT MACRO DEFINITION ===========================Replace <parm> with "<parm>". <parm> may be an arbitrary number of tokens***********************************************************************/#define QUOTE_IT( parm ) #parm/*********************************************************************** ELISTIZE( CLASSNAME ) MACROS ============================CLASSNAME is assumed to be the name of a class which has a baseclass ofELIST_LINK.NOTE: Because we dont use virtual functions in the list code, the list codewill NOT work correctly for classes derived from this.The macros generate: - An element deletion function: CLASSNAME##_zapper - An element copier function: CLASSNAME##_copier - An element serialiser function" CLASSNAME##_serialiser - An element de-serialiser function" CLASSNAME##_de_serialiser - An E_LIST subclass: CLASSNAME##_LIST - An E_LIST_ITERATOR subclass: CLASSNAME##_ITNOTE: Generated names are DELIBERATELY designed to clash with those forELIST2IZE but NOT with those for CLISTIZE and CLIST2IZEFour macros are provided: ELISTIZE, ELISTIZE_S, ELISTIZEH and ELISTIZEH_SThe ...IZEH macros just define the class names for use in .h filesThe ...IZE macros define the code use in .c filesThe _S versions define lists which can be serialised. They assume thatthe make_serialise() macro is used in the list element class derived fromELIST_LINK to define serialise() and de_serialise() members for the listelements.***********************************************************************//*********************************************************************** ELISTIZEH( CLASSNAME ) and ELISTIZEH_S( CLASSNAME ) MACROSThese macros are constructed from 3 fragments ELISTIZEH_A, ELISTIZEH_B andELISTIZEH_C. ELISTIZEH is simply a concatenation of these parts.ELISTIZEH_S has some additional bits thrown in the gaps.***********************************************************************/#define ELISTIZEH_A( CLASSNAME ) \ \extern DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \ELIST_LINK* link); /*link to delete*/ \ \extern DLLSYM ELIST_LINK* CLASSNAME##_copier( /*deep copy a link*/ \ELIST_LINK* old_element); /*source link */#define ELISTIZEH_B( CLASSNAME ) \ \/*********************************************************************** \* CLASS - CLASSNAME##_LIST \* \* List class for class CLASSNAME \* \**********************************************************************/ \ \class DLLSYM CLASSNAME##_LIST : public ELIST \{ \public: \ CLASSNAME##_LIST():ELIST() {}\ /* constructor */ \ \ CLASSNAME##_LIST( /* dont construct */ \ const CLASSNAME##_LIST&) /*by initial assign*/\ { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_LIST ), \ ABORT, NULL ); } \ \void clear() /* delete elements */\ { ELIST::internal_clear( &CLASSNAME##_zapper ); } \ \ ~CLASSNAME##_LIST() /* destructor */ \ { clear(); } \ \void deep_copy( /* become a deep */ \ const CLASSNAME##_LIST* list) /* copy of src list*/\ { ELIST::internal_deep_copy( &CLASSNAME##_copier, list ); } \ \void operator=( /* prevent assign */ \ const CLASSNAME##_LIST&) \ { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ), \ ABORT, NULL ); }#define ELISTIZEH_C( CLASSNAME ) \}; \ \ \ \/*********************************************************************** \* CLASS - CLASSNAME##_IT \* \* Iterator class for class CLASSNAME##_LIST \* \* Note: We don't need to coerce pointers to member functions input \* parameters as these are automatically converted to the type of the base \* type. ("A ptr to a class may be converted to a pointer to a public base \* class of that class") \**********************************************************************/ \ \class DLLSYM CLASSNAME##_IT : public ELIST_ITERATOR \{ \public: \ CLASSNAME##_IT():ELIST_ITERATOR(){} \ \ CLASSNAME##_IT( \CLASSNAME##_LIST* list):ELIST_ITERATOR(list){} \ \ CLASSNAME* data() \ { return (CLASSNAME*) ELIST_ITERATOR::data(); } \ \ CLASSNAME* data_relative( \ INT8 offset) \ { return (CLASSNAME*) ELIST_ITERATOR::data_relative( offset ); } \ \ CLASSNAME* forward() \ { return (CLASSNAME*) ELIST_ITERATOR::forward(); } \ \ CLASSNAME* extract() \ { return (CLASSNAME*) ELIST_ITERATOR::extract(); } \ \ CLASSNAME* move_to_first() \ { return (CLASSNAME*) ELIST_ITERATOR::move_to_first(); } \ \ CLASSNAME* move_to_last() \ { return (CLASSNAME*) ELIST_ITERATOR::move_to_last(); } \};#define ELISTIZEH( CLASSNAME ) \ \ELISTIZEH_A( CLASSNAME ) \ \ELISTIZEH_B( CLASSNAME ) \ \ELISTIZEH_C( CLASSNAME )#define ELISTIZEH_S( CLASSNAME ) \ \ELISTIZEH_A( CLASSNAME ) \ \extern DLLSYM void CLASSNAME##_serialiser( \FILE* f, \ELIST_LINK* element); \ \extern DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser( \FILE* f); \ \ELISTIZEH_B( CLASSNAME ) \ \ void dump( /* dump to file */ \ FILE* f) \ { ELIST::internal_dump( f, &CLASSNAME##_serialiser );} \ \ void de_dump( /* get from file */ \ FILE* f) \ { ELIST::internal_de_dump( f, &CLASSNAME##_de_serialiser );} \ \ void serialise_asc( /*dump to ascii*/ \ FILE* f); \ void de_serialise_asc( /*de-dump from ascii*/\ FILE* f); \ \make_serialise( CLASSNAME##_LIST ) \ \ELISTIZEH_C( CLASSNAME )/*********************************************************************** ELISTIZE( CLASSNAME ) and ELISTIZE_S( CLASSNAME ) MACROSELISTIZE_S is a simple extension to ELISTIZE***********************************************************************/#define ELISTIZE( CLASSNAME ) \ \/*********************************************************************** \* CLASSNAME##_zapper \* \* A function which can delete a CLASSNAME element. This is passed to the \* generic clear list member function so that when a list is cleared the \* elements on the list are properly destroyed from the base class, even \* though we dont use a virtual destructor function. \**********************************************************************/ \ \DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \ELIST_LINK* link) /*link to delete*/ \{ \delete (CLASSNAME *) link; \} \ \/*********************************************************************** \* CLASSNAME##_copier \* \* A function which can generate a new, deep copy of a CLASSNAME element. \* This is passed to the generic deep copy list member function so that when \* a list is copied the elements on the list are properly copied from the \* base class, even though we dont use a virtual function. \**********************************************************************/ \ \DLLSYM ELIST_LINK* CLASSNAME##_copier( /*deep copy a link*/ \ELIST_LINK* old_element) /*source link*/ \{ \ CLASSNAME* new_element; \ \new_element = new CLASSNAME; \*new_element = *((CLASSNAME*) old_element); \return (ELIST_LINK*) new_element; \}#define ELISTIZE_S( CLASSNAME ) \ \ELISTIZE( CLASSNAME ) \ \ void CLASSNAME##_LIST::serialise_asc( \ /*dump to ascii*/ \ FILE* f) \ { \ CLASSNAME##_IT it(this); \ \ serialise_INT32(f,length()); \ for (it.mark_cycle_pt();!it.cycled_list();it.forward()) \ it.data()->serialise_asc(f); /*serialise the list*/\ } \ \ void CLASSNAME##_LIST::de_serialise_asc( \ /*de-dump from ascii*/\ FILE* f) \ { \ INT32 len; /*length to retrive*/\ CLASSNAME##_IT it; \ CLASSNAME* new_elt=NULL; /*list element*/ \ \ len=de_serialise_INT32(f); \ it.set_to_list(this); \ for (;len>0;len--) \ { \ new_elt=new CLASSNAME; \ new_elt->de_serialise_asc(f); \ it.add_to_end(new_elt); /*put on the list*/ \ } \ return; \ } \ \ \/*********************************************************************** \* CLASSNAME##_serialiser \* \* A function which can serialise an element \* This is passed to the generic dump member function so that when a list is \* serialised the elements on the list are properly serialised. \**********************************************************************/ \ \DLLSYM void CLASSNAME##_serialiser( \FILE* f, \ELIST_LINK* element) \{ \((CLASSNAME*) element)->serialise( f ); \} \ \ \ \/*********************************************************************** \* CLASSNAME##_de_serialiser \* \* A function which can de-serialise an element \* This is passed to the generic de-dump member function so that when a list \* is de-serialised the elements on the list are properly de-serialised. \**********************************************************************/ \ \DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser( \FILE* f) \{ \return (ELIST_LINK*) CLASSNAME::de_serialise( f ); \}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -