cgma
|
00001 //- Class: SDLList 00002 //- Description: SDLList is a doubly linked list class that accepts generic 00003 //- pointers to any object. It is controlled by a macro that 00004 //- substitutes the specific pointer definitions in the class 00005 //- declaration. The list is implemented as an array that is 00006 //- grown by a specified amount when the list becomes full. 00007 //- Insertions and deletions at any point other than the end 00008 //- of the list are handled inefficiently at the current time 00009 //- since all data from that point to the end is bubbled 00010 //- down/up to fill/create the void. Operators {+} and {+=} 00011 //- are provided as an efficient means of assigning one list 00012 //- to another or appending one list onto another. 00013 //- 00014 //- The macro {SDLListdeclare(name,typePtr)} is defined to 00015 //- create specific instances of the SDLList class. 00016 //- {name} is the name of the SDLList class created, and 00017 //- {typePtr} is the type of elements stored in the list. 00018 //- The macro also defines the functions {push(item)} and 00019 //- {pop()} which allow {SDLLists} to perform like stacks. 00020 //- 00021 //- Assumptions: All data are stored contiguously in the array with 00022 //- empty slots at the end of the array. 00023 //- 00024 //- Owner: Greg Sjaardema 00025 //- Checked by: Jim Hipp, 3/28/94 00026 //- Version: $Id: 00027 00028 #ifndef SDLLIST_HPP 00029 #define SDLLIST_HPP 00030 00031 #include "DLList.hpp" 00032 #include "CubitDefines.h" 00033 #include "CubitMessage.hpp" 00034 #include <cstring> 00035 #include <cassert> 00036 #include "CGMUtilConfigure.h" 00037 00038 const int ORDER_ASCENDING = 0; 00039 const int ORDER_DESCENDING = 1; 00040 //- sort direction specifiers for the SSDLListDeclare Constructor 00041 00042 class CUBIT_UTIL_EXPORT SDLList : public DLList 00043 { 00044 public: 00045 00046 SDLList (int size); 00047 //- Constructor: Create a list with initial size {size}. The list 00048 //- will be grown by {size} each time it is filled. Memory for the 00049 //- list is not allocated until the first element is inserted using 00050 //- {insertLink}. 00051 //- If {size} is zero, the default increment ({INCREMENT}) will be used 00052 //- From an efficiency standpoint, it is very important that the 00053 //- increment be set large enough to reduce the number of list 00054 //- growths, but small enough to not waste memory. 00055 //- It is more efficient to sligthly overestimate the size than 00056 //- to underestimate the size. 00057 00058 SDLList(const SDLList& copy_from); //- Copy Constructor 00059 SDLList(const DLList& copy_from); //- Copy Constructor 00060 00061 virtual ~SDLList(); 00062 //- Destructor: Free all resources used by this list. 00063 00064 SDLList& operator=(const SDLList&); 00065 //- Create a copy of a list. 00066 00067 virtual void merge_unique(DLList& merge_list, int merge_list_unique ); 00068 //- Merges the contents of the list, merge_list, with those of "this" 00069 //- list, ensuring that items that are being added do not already 00070 //- exist in "this" list. If the items are known to appear in the 00071 //- merge_list only once, then it can be done faster. 00072 00073 SetDynamicMemoryAllocation(memoryManager) 00074 //- overloaded new and delete operators 00075 00076 protected: 00077 00078 void insert_link(void* newBody); 00079 //- put new item in list after current item and make it current 00080 00081 void insert_link_first(void* new_item); 00082 //- put new item in list at index 0 and make it current 00083 00084 void append_link(void* newBody); 00085 //- put new item at end of list and keep pointer where it is. 00086 //- This call should be used to add items to a list if order 00087 //- of items is not important. 00088 00089 void* extract_link(); 00090 //- remove the item at the current location and return a pointer to it. 00091 //- used for efficiency in cases where preservation of list order is not 00092 //- important. moves last list item (itemCount - 1) to current index and 00093 //- decrements itemCount. eliminates the need to perform the list bubble 00094 //- down (i.e. cut_link) but sacrifices list order in the process. this 00095 //- function should not be used when up-stream order from the removed node 00096 //- is important. when processing a list using this function the user 00097 //- should reset the list to the head (index = 0) before beginning to 00098 //- ensure all list nodes are processed properly. 00099 //- Returns {NULL} if there are no items in list 00100 00101 void *change_item_to(void* newBody); 00102 //- Sets the item at the current index value to {newBody} and 00103 //- returns the old value at that location. 00104 //- Returns {NULL} if there are no items in list 00105 00106 void sort_list(); 00107 //- sort_list sorts SDLLists in an ascending or descending fashion 00108 //- (depending on the assignment of compare_order function pointer). The 00109 //- list is sorted using a standard Heap Sort algorithm. 00110 00111 CubitBoolean move_to_item_sorted(void* value); 00112 //- move_to_item_sorted performs a binary search on the list to locate 00113 //- the item (object) that has functionType functionName() = value 00114 //- (see SSDLListdeclare macro for description of functionType and 00115 //- functionName). If a matching item is found then the current 00116 //- index is set to the matching item index and TRUE is returned. If the 00117 //- object is not found then index is unchanged and FALSE is returned. 00118 00119 void insert_item_sorted(void* value, void* new_item); 00120 //- insert_item_sorted uses compare function (compare_order) to perform a 00121 //- binary search to find the insert index in the list. The function then 00122 //- calls insert_link after setting the index to the insert position - 1. 00123 00124 void* move_to_and_remove_item_sorted(void* value); 00125 //- move_to_and_remove_item_sorted uses move_to_item_sorted function to 00126 //- perform a binary search to locate the item's index which has 00127 //- functionType functionName() = value. If found, remove_link is called 00128 //- to remove and return the item from the list. Otherwise, NULL is 00129 //- returned. 00130 00131 int (*compare_order_obj)(void* object_1, void* object_2); 00132 int (*compare_order)(void* object_1, void* object_2); 00133 int (*compare_equal)(void* object_1, void* object_2); 00134 //- compare function pointers are assigned within the macro definition 00135 //- SSDLListDeclare 00136 00137 void set_sorted_flag(const int sorted_flag); 00138 //- set listIsSorted flag 00139 00140 CubitBoolean where_is_item_sorted( void *value, int &item_index ); 00141 //- Return True if item with given value is in the list, else false. 00142 //- Return in item_index the index of item of that value in list, 00143 //- or -1 if an item of that value is not in the list. 00144 //- This information should never be passed outside the class. 00145 00146 private: 00147 00148 void binary_search(int* min_location, int* max_location, void* item) const; 00149 //- binary_search performs a standard array based binary search (essentially 00150 //- bisection) to bracket/locate an insert/search position. 00151 00152 static MemoryManager memoryManager; 00153 //- memory management static objects for performing block allocation 00154 }; 00155 00156 // *** inline function definitions ******************************************* 00157 00158 //- Add item to end of list, do not change current index value. 00159 //- This function used to reduce time required to do an insert 00160 //- followed by a move_to back to where we were. 00161 inline void SDLList::append_link ( void* new_item ) 00162 { 00163 assert(new_item != NULL); 00164 // see if the list must be lengthened 00165 00166 if ( itemCount == listLength ) 00167 lengthen_list(); 00168 00169 listArray[itemCount++] = new_item; 00170 } 00171 00172 inline void SDLList::set_sorted_flag(const int sorted_flag) 00173 { 00174 listIsSorted = sorted_flag; 00175 } 00176 00177 00178 // *** macro definitions ***************************************************** 00179 00180 // Three separate derived classes are possible from SDLList all of which are 00181 // defined by one of the following macros: 00182 // 00183 // SDLListdeclare(name, typePtr) 00184 // SSDLListdeclare(name, typePtr, functionName, functionType) 00185 // SSDLListIntrinsicdeclare(name, typePtr) 00186 // 00187 // The first is the standard SDLList declaration macro, the second provides 00188 // sorting/searching functionality, and the third provides sorting/searching 00189 // functionallity for simple intrinsic data lists. All three are described in 00190 // more detail below. Two support macros 00191 // 00192 // CommonDefine(typePtr, notSorted) 00193 // CommonSortedDefine(name, typePtr) 00194 // 00195 // are also defined but are not meant to be utilized externally. They simply 00196 // collect class definitions that are common to the three list defintions 00197 // macros described above 00198 00199 // The following macro defintion provides the core functionality for the 00200 // standard SDLListdeclare as-well-as the sorted SSDLListdeclare macros. 00201 // typePtr is still the type pointer of the data stored by the list. 00202 // notSorted is simply a semi-colon (;) for the standard list (if white space 00203 // is used for the parameter the CPP outputs a warning message that a NULL 00204 // string is being substituted for the parameter ... the proper outcome but 00205 // the excessive warning messages are a real nuisance) and a call to the 00206 // set_sort_flag function (with an argument of False) for the sorted lists. 00207 #define CommonDefine2(typePtr, notSorted) \ 00208 \ 00209 typePtr remove() {return (typePtr) cut_link();} \ 00210 int omit(typePtr objPtr) {return omit_link((void*) objPtr);} \ 00211 typePtr get() const {return (typePtr) get_item();} \ 00212 typePtr next() const {return (typePtr) next_item();} \ 00213 typePtr next( int n ) const {return (typePtr) next_item(n);} \ 00214 typePtr prev() const {return (typePtr) prev_item();} \ 00215 typePtr prev(int n) const {return (typePtr) prev_item(n);} \ 00216 typePtr get_and_step() {return (typePtr) get_item_and_step();} \ 00217 typePtr get_and_back() {return (typePtr) get_item_and_back();} \ 00218 typePtr step_and_get() {return (typePtr) step_and_get_item();} \ 00219 \ 00220 int move_between(typePtr objPtr1, typePtr objPtr2) \ 00221 { \ 00222 if (nullItem && (((typePtr) nullItem == objPtr1) || \ 00223 ((typePtr) nullItem == objPtr2) )) \ 00224 return CUBIT_FALSE; \ 00225 else \ 00226 return (move_between_items(((void*) objPtr1), ((void*) objPtr2))); \ 00227 } \ 00228 typePtr pop() {last(); return remove();} \ 00229 typePtr push(typePtr objPtr) \ 00230 { last(); append(objPtr); return objPtr; } \ 00231 \ 00232 void insert_first(typePtr objPtr) \ 00233 { notSorted insert_link_first((void*) objPtr); } \ 00234 void append(typePtr objPtr) \ 00235 { notSorted append_link((void*) objPtr); } \ 00236 typePtr extract() \ 00237 { notSorted return (typePtr) extract_link(); } \ 00238 typePtr nullify() \ 00239 { notSorted return (typePtr) nullify_link(); } \ 00240 typePtr change_to(typePtr objPtr) \ 00241 { notSorted return (typePtr) change_item_to((void*) objPtr); } \ 00242 \ 00243 00244 00245 // The macro CommonSortedDefine contains common public functions used by 00246 // SSDLListdeclare and SSDLListIntrinsicdeclare 00247 #define CommonSortedDefine(name, typePtr) \ 00248 \ 00249 name(int size_in = 0, int direction = ORDER_ASCENDING) : SDLList(size_in) \ 00250 { \ 00251 assert(sizeof(typePtr) == sizeof(void*)); \ 00252 if (direction == ORDER_DESCENDING) \ 00253 { \ 00254 compare_order = &name::compare_descend; \ 00255 compare_order_obj = &name::compare_descend_obj; \ 00256 } \ 00257 else \ 00258 { \ 00259 compare_order = &name::compare_ascend; \ 00260 compare_order_obj = &name::compare_ascend_obj; \ 00261 } \ 00262 compare_equal = &name::compare_equate; \ 00263 set_sorted_flag(CUBIT_TRUE); \ 00264 } \ 00265 \ 00266 void sort() { sort_list(); } \ 00267 void set_list_order_ascend() \ 00268 { \ 00269 compare_order_obj = &name::compare_ascend_obj; \ 00270 compare_order = &name::compare_ascend; sort_list(); \ 00271 } \ 00272 void set_list_order_descend() \ 00273 { \ 00274 compare_order_obj = &name::compare_descend_obj; \ 00275 compare_order = &name::compare_descend; sort_list(); \ 00276 } \ 00277 00278 // The sorted SDLList declaration macro creates an ordered list class that 00279 // is derived from SDLList. The class (name) stores pointers to data of 00280 // type typePtr. List ordering is provided by sorting the objects based 00281 // on the returned value of one of the objects functions (functionName()). 00282 // The return type of functionName is functionType. Searching functionality 00283 // is provided (with move_to) to locate the object (typePtr objPtr) or a 00284 // value (functionType value) of the object utilizing an binary search. 00285 #define SDLListdeclare(name, typePtr, functionName, functionType) \ 00286 \ 00287 class name : public SDLList \ 00288 { \ 00289 \ 00290 public: \ 00291 \ 00292 CommonSortedDefine(name, typePtr) \ 00293 CommonDefine(typePtr, set_sorted_flag(CUBIT_FALSE);) \ 00294 \ 00295 void insert(typePtr objPtr) \ 00296 { \ 00297 functionType value = objPtr->functionName(); \ 00298 insert_item_sorted((void*) &value, (void*) objPtr); \ 00299 } \ 00300 typePtr remove(typePtr objPtr) \ 00301 { \ 00302 assert(objPtr != NULL); \ 00303 functionType value = objPtr->functionName(); \ 00304 return (typePtr) move_to_and_remove_item_sorted((void*) &value); \ 00305 } \ 00306 typePtr remove(functionType value) \ 00307 { \ 00308 return (typePtr) move_to_and_remove_item_sorted((void*) &value); \ 00309 } \ 00310 CubitBoolean move_to(typePtr objPtr) \ 00311 { \ 00312 if (nullItem && ((typePtr) nullItem == objPtr)) \ 00313 return CUBIT_FALSE; \ 00314 else \ 00315 { \ 00316 assert(objPtr != NULL); \ 00317 functionType value = objPtr->functionName(); \ 00318 return move_to_item_sorted((void*) &value); \ 00319 } \ 00320 } \ 00321 CubitBoolean move_to(functionType value) \ 00322 { \ 00323 return move_to_item_sorted((void*) &value); \ 00324 } \ 00325 int is_in_list(functionType value) \ 00326 { \ 00327 int item_index; \ 00328 int return_value = \ 00329 where_is_item_sorted((void*) &value, item_index) ? \ 00330 item_index + 1 : 0; \ 00331 return return_value; \ 00332 } \ 00333 int is_in_list(typePtr objPtr) \ 00334 { \ 00335 if (nullItem && ((typePtr) nullItem == objPtr)) \ 00336 return CUBIT_FALSE; \ 00337 else \ 00338 { \ 00339 assert(objPtr != NULL); \ 00340 functionType value = objPtr->functionName(); \ 00341 return is_in_list( value ); \ 00342 } \ 00343 } \ 00344 \ 00345 private: \ 00346 \ 00347 static int compare_ascend_obj(void* object_1, void* object_2) \ 00348 { \ 00349 return (((typePtr) object_1)->functionName() >= \ 00350 ((typePtr) object_2)->functionName()); \ 00351 } \ 00352 static int compare_descend_obj(void* object_1, void* object_2) \ 00353 { \ 00354 return (((typePtr) object_1)->functionName() <= \ 00355 ((typePtr) object_2)->functionName()); \ 00356 } \ 00357 \ 00358 static int compare_ascend(void* value, void* object) \ 00359 { \ 00360 return (*((functionType*) value) >= \ 00361 ((typePtr) object)->functionName()); \ 00362 } \ 00363 static int compare_descend(void* value, void* object) \ 00364 { \ 00365 return (*((functionType*) value) <= \ 00366 ((typePtr) object)->functionName()); \ 00367 } \ 00368 static int compare_equate(void* value, void* object) \ 00369 { \ 00370 return (*((functionType*) value) == \ 00371 ((typePtr) object)->functionName()); \ 00372 } \ 00373 }; \ 00374 00375 00376 // The sorted Intrinsic SDLList declaration macro creates an ordered intrinsic 00377 // list class that is derived from SDLList. The class (name) stores values of 00378 // typePtr through casting to void* pointers. This macro only works for lists 00379 // of integers or floats. No capability is currently supported for lists of 00380 // doubles. 00381 #define SSDLListIntrinsicdeclare(name, typePtr) \ 00382 \ 00383 class name : public SDLList \ 00384 { \ 00385 \ 00386 public: \ 00387 \ 00388 CommonSortedDefine(name, typePtr) \ 00389 CommonDefine(typePtr, set_sorted_flag(CUBIT_FALSE);) \ 00390 \ 00391 void insert(typePtr objPtr) \ 00392 { \ 00393 insert_item_sorted((void*) objPtr, (void*) objPtr); \ 00394 } \ 00395 typePtr remove(typePtr objPtr) \ 00396 { \ 00397 return (typePtr) move_to_and_remove_item_sorted((void*) objPtr); \ 00398 } \ 00399 int move_to(typePtr objPtr) \ 00400 { \ 00401 return move_to_item_sorted((void*) objPtr); \ 00402 } \ 00403 int is_in_list(typePtr objPtr) \ 00404 { \ 00405 int item_index; \ 00406 int return_value = \ 00407 where_is_item_sorted((void*) &objPtr, item_index) ? \ 00408 item_index + 1 : 0; \ 00409 return return_value; \ 00410 } \ 00411 \ 00412 private: \ 00413 \ 00414 static int compare_ascend_obj(void* object_1, void* object_2) \ 00415 { \ 00416 return (((typePtr) object_1) >= ((typePtr) object_2)); \ 00417 } \ 00418 static int compare_descend_obj(void* object_1, void* object_2) \ 00419 { \ 00420 return (((typePtr) object_1) <= ((typePtr) object_2)); \ 00421 } \ 00422 \ 00423 static int compare_ascend(void* object_1, void* object_2) \ 00424 { \ 00425 return (((typePtr) object_1) >= ((typePtr) object_2)); \ 00426 } \ 00427 static int compare_descend(void* object_1, void* object_2) \ 00428 { \ 00429 return (((typePtr) object_1) <= ((typePtr) object_2)); \ 00430 } \ 00431 static int compare_equate(void* object_1, void* object_2) \ 00432 { \ 00433 return (((typePtr) object_1) == ((typePtr) object_2)); \ 00434 } \ 00435 }; \ 00436 00437 #endif //- SDLLIST_HPP 00438