📄 elst2.h
字号:
/*********************************************************************** * ELIST2_ITERATOR::at_last() * * Are we at the end of the list? * **********************************************************************/inline BOOL8 ELIST2_ITERATOR::at_last() { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST2_ITERATOR::at_last", ABORT, NULL); if (!list) NO_LIST.error ("ELIST2_ITERATOR::at_last", ABORT, NULL); #endif //we're at a deleted return ((list->empty ()) || (current == list->last) || ((current == NULL) && (prev == list->last) && //last point between ex_current_was_last)); //first and last}/*********************************************************************** * ELIST2_ITERATOR::cycled_list() * * Have we returned to the cycle_pt since it was set? * **********************************************************************/inline BOOL8 ELIST2_ITERATOR::cycled_list() { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST2_ITERATOR::cycled_list", ABORT, NULL); if (!list) NO_LIST.error ("ELIST2_ITERATOR::cycled_list", ABORT, NULL); #endif return ((list->empty ()) || ((current == cycle_pt) && started_cycling));}/*********************************************************************** * ELIST2_ITERATOR::length() * * Return the length of the list * **********************************************************************/inline INT32 ELIST2_ITERATOR::length() { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST2_ITERATOR::length", ABORT, NULL); if (!list) NO_LIST.error ("ELIST2_ITERATOR::length", ABORT, NULL); #endif return list->length ();}/*********************************************************************** * ELIST2_ITERATOR::sort() * * Sort the elements of the list, then reposition at the start. * **********************************************************************/inline voidELIST2_ITERATOR::sort ( //sort elementsint comparator ( //comparison routineconst void *, const void *)) { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST2_ITERATOR::sort", ABORT, NULL); if (!list) NO_LIST.error ("ELIST2_ITERATOR::sort", ABORT, NULL); #endif list->sort (comparator); move_to_first();}/*********************************************************************** * ELIST2_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 ELIST2_ITERATOR::add_to_end( // element to add ELIST2_LINK *new_element) { #ifdef _DEBUG if (!this) NULL_OBJECT.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL); if (!list) NO_LIST.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL); if (!new_element) BAD_PARAMETER.error ("ELIST2_ITERATOR::add_to_end", ABORT, "new_element is NULL"); if (new_element->next) STILL_LINKED.error ("ELIST2_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; new_element->prev = list->last; list->last->next->prev = new_element; list->last->next = new_element; list->last = new_element; } }}/*********************************************************************** QUOTE_IT MACRO DEFINITION ===========================Replace <parm> with "<parm>". <parm> may be an arbitrary number of tokens***********************************************************************/#define QUOTE_IT( parm ) #parm/*********************************************************************** ELIST2IZE( CLASSNAME ) MACRO DEFINITION ======================================CLASSNAME is assumed to be the name of a class which has a baseclass ofELIST2_LINK.NOTE: Because we dont use virtual functions in the list code, the list codewill NOT work correctly for classes derived from this.The macro generates: - 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_LIST2 subclass: CLASSNAME##_LIST - An E_LIST2_ITERATOR subclass: CLASSNAME##_ITNOTE: Generated names are DELIBERATELY designed to clash with those forELISTIZE but NOT with those for CLISTIZE and CLIST2IZEFour macros are provided: ELIST2IZE, ELIST2IZE_S, ELIST2IZEH and ELIST2IZEH_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 fromELIST2_LINK to define serialise() and de_serialise() members for the listelements.***********************************************************************//*********************************************************************** ELIST2IZEH( CLASSNAME ) and ELIST2IZEH_S( CLASSNAME ) MACROSThese macros are constructed from 3 fragments ELIST2IZEH_A, ELIST2IZEH_B andELIST2IZEH_C. ELIST2IZEH is simply a concatenation of these parts.ELIST2IZEH_S has some additional bits thrown in the gaps.***********************************************************************/#define ELIST2IZEH_A( CLASSNAME ) \ \extern DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \ELIST2_LINK* link); /*link to delete*/ \ \extern DLLSYM ELIST2_LINK* CLASSNAME##_copier( /*deep copy a link*/ \ELIST2_LINK* old_element); /*source link */#define ELIST2IZEH_B( CLASSNAME ) \ \/*********************************************************************** \* CLASS - CLASSNAME##_LIST \* \* List class for class CLASSNAME \* \**********************************************************************/ \ \class DLLSYM CLASSNAME##_LIST : public ELIST2 \{ \public: \ CLASSNAME##_LIST():ELIST2() {} \ /* 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 */\ { ELIST2::internal_clear( &CLASSNAME##_zapper ); } \ \ ~CLASSNAME##_LIST() /* destructor */ \ { clear(); } \ \void deep_copy( /* become a deep */ \ const CLASSNAME##_LIST* list) /* copy of src list*/\ { ELIST2::internal_deep_copy( &CLASSNAME##_copier, list ); } \ \void operator=( /* prevent assign */ \ const CLASSNAME##_LIST&) \ { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ), \ ABORT, NULL ); }#define ELIST2IZEH_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 ELIST2_ITERATOR \{ \public: \ CLASSNAME##_IT():ELIST2_ITERATOR(){} \ \ CLASSNAME##_IT( \CLASSNAME##_LIST* list):ELIST2_ITERATOR(list){} \ \ CLASSNAME* data() \ { return (CLASSNAME*) ELIST2_ITERATOR::data(); } \ \ CLASSNAME* data_relative( \ INT8 offset) \ { return (CLASSNAME*) ELIST2_ITERATOR::data_relative( offset ); } \ \ CLASSNAME* forward() \ { return (CLASSNAME*) ELIST2_ITERATOR::forward(); } \ \ CLASSNAME* backward() \ { return (CLASSNAME*) ELIST2_ITERATOR::backward(); } \ \ CLASSNAME* extract() \ { return (CLASSNAME*) ELIST2_ITERATOR::extract(); } \ \ CLASSNAME* move_to_first() \ { return (CLASSNAME*) ELIST2_ITERATOR::move_to_first(); } \ \ CLASSNAME* move_to_last() \ { return (CLASSNAME*) ELIST2_ITERATOR::move_to_last(); } \};#define ELIST2IZEH( CLASSNAME ) \ \ELIST2IZEH_A( CLASSNAME ) \ \ELIST2IZEH_B( CLASSNAME ) \ \ELIST2IZEH_C( CLASSNAME )#define ELIST2IZEH_S( CLASSNAME ) \ \ELIST2IZEH_A( CLASSNAME ) \ \extern DLLSYM void CLASSNAME##_serialiser( \FILE* f, \ELIST2_LINK* element); \ \extern DLLSYM ELIST2_LINK* CLASSNAME##_de_serialiser( \FILE* f); \ \ELIST2IZEH_B( CLASSNAME ) \ \ void dump( /* dump to file */ \ FILE* f) \ { ELIST2::internal_dump( f, &CLASSNAME##_serialiser );} \ \ void de_dump( /* get from file */ \ FILE* f) \ { ELIST2::internal_de_dump( f, &CLASSNAME##_de_serialiser );} \ \make_serialise( CLASSNAME##_LIST ) \ \ELIST2IZEH_C( CLASSNAME )/*********************************************************************** ELIST2IZE( CLASSNAME ) and ELIST2IZE_S( CLASSNAME ) MACROSELIST2IZE_S is a simple extension to ELIST2IZE***********************************************************************/#define ELIST2IZE( 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*/ \ELIST2_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 ELIST2_LINK* CLASSNAME##_copier( /*deep copy a link*/ \ELIST2_LINK* old_element) /*source link*/ \{ \ CLASSNAME* new_element; \ \new_element = new CLASSNAME; \*new_element = *((CLASSNAME*) old_element); \return (ELIST2_LINK*) new_element; \}#define ELIST2IZE_S( CLASSNAME ) \ \ELIST2IZE( CLASSNAME ) \ \/*********************************************************************** \* 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, \ELIST2_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 ELIST2_LINK* CLASSNAME##_de_serialiser( \FILE* f) \{ \return (ELIST2_LINK*) CLASSNAME::de_serialise( f ); \}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -