00001 /*<html><pre> -<a href="qh-c.htm#set" 00002 >-------------------------------</a><a name="TOP">-</a> 00003 00004 set.h 00005 header file for set.c that implements set 00006 00007 see qh-c.htm and set.c 00008 00009 only uses mem.c, malloc/free 00010 00011 for error handling, writes message and calls 00012 qh_errexit (qhmem_ERRqhull, NULL, NULL); 00013 00014 set operations satisfy the following properties: 00015 - sets have a max size, the actual size (if different) is stored at the end 00016 - every set is NULL terminated 00017 - sets may be sorted or unsorted, the caller must distinguish this 00018 00019 copyright (c) 1993-1998, The Geometry Center 00020 */ 00021 00022 #ifndef qhDEFset 00023 #define qhDEFset 1 00024 00025 /*================= -structures- ===============*/ 00026 00027 #ifndef DEFsetT 00028 #define DEFsetT 1 00029 typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */ 00030 #endif 00031 00032 /*-<a href="qh-c.htm#set" 00033 >----------------------------------------</a><a name="setT">-</a> 00034 00035 setT 00036 a set or list of pointers with maximum size and actual size. 00037 00038 variations: 00039 unsorted, unique -- a list of unique pointers with NULL terminator 00040 user guarantees uniqueness 00041 sorted -- a sorted list of unique pointers with NULL terminator 00042 set.c guarantees uniqueness 00043 unsorted -- a list of pointers terminated with NULL 00044 indexed -- an array of pointers with NULL elements 00045 00046 structure for set of n elements: 00047 00048 -------------- 00049 | maxsize 00050 -------------- 00051 | e[0] - a pointer, may be NULL for indexed sets 00052 -------------- 00053 | e[1] 00054 00055 -------------- 00056 | ... 00057 -------------- 00058 | e[n-1] 00059 -------------- 00060 | e[n] = NULL 00061 -------------- 00062 | ... 00063 -------------- 00064 | e[maxsize] - n+1 or NULL (determines actual size of set) 00065 -------------- 00066 00067 */ 00068 00069 /*-- setelemT -- internal type to allow both pointers and indices 00070 */ 00071 typedef union setelemT setelemT; 00072 union setelemT { 00073 void *p; 00074 int i; /* integer used for e[maxSize] */ 00075 }; 00076 00077 struct setT { 00078 int maxsize; /* maximum number of elements (except NULL) */ 00079 setelemT e[1]; /* array of pointers, tail is NULL */ 00080 /* last slot (unless NULL) is actual size+1 00081 e[maxsize]==NULL or e[e[maxsize]-1]==NULL */ 00082 /* this may generate a warning since e[] contains 00083 maxsize elements */ 00084 }; 00085 00086 /*=========== -constants- =========================*/ 00087 00088 /*-<a href="qh-c.htm#set" 00089 >-----------------------------------</a><a name="SETelemsize">-</a> 00090 00091 SETelemsize 00092 size of a set element in bytes 00093 */ 00094 #define SETelemsize sizeof(setelemT) 00095 00096 00097 /*=========== -macros- =========================*/ 00098 00099 /*-<a href="qh-c.htm#set" 00100 >-----------------------------------</a><a name="FOREACHsetelement_">-</a> 00101 00102 FOREACHsetelement_(type, set, variable) 00103 define FOREACH iterator 00104 00105 declare: 00106 assumes *variable and **variablep are declared 00107 00108 each iteration: 00109 variable is set element 00110 variablep is one beyond variable. 00111 00112 to repeat an element: 00113 variablep--; / *repeat* / 00114 00115 at exit: 00116 variable is NULL at end of loop 00117 00118 example: 00119 #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet ) 00120 00121 notes: 00122 use FOREACHsetelement_i_() if need index or include NULLs 00123 00124 WARNING: 00125 nested loops can't use the same variable (define another FOREACH) 00126 00127 needs braces if nested inside another FOREACH 00128 this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} ) 00129 */ 00130 #define FOREACHsetelement_(type, set, variable) \ 00131 if (((variable= NULL), set)) for(\ 00132 variable##p= (type **)&((set)->e[0].p); \ 00133 (variable= *variable##p++);) 00134 00135 /*-<a href="qh-c.htm#set" 00136 >----------------------------------------</a><a name="FOREACHsetelement_i_">-</a> 00137 00138 FOREACHsetelement_i_(type, set, variable) 00139 define indexed FOREACH iterator 00140 00141 declare: 00142 type *variable, variable_n, variable_i; 00143 00144 each iteration: 00145 variable is set element, may be NULL 00146 variable_i is index, variable_n is qh_setsize() 00147 00148 to repeat an element: 00149 variable_i--; variable_n-- repeats for deleted element 00150 00151 at exit: 00152 variable==NULL and variable_i==variable_n 00153 00154 example: 00155 #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet ) 00156 00157 WARNING: 00158 nested loops can't use the same variable (define another FOREACH) 00159 00160 needs braces if nested inside another FOREACH 00161 this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} ) 00162 */ 00163 #define FOREACHsetelement_i_(type, set, variable) \ 00164 if (((variable= NULL), set)) for (\ 00165 variable##_i= 0, variable= (type *)((set)->e[0].p), \ 00166 variable##_n= qh_setsize(set);\ 00167 variable##_i < variable##_n;\ 00168 variable= (type *)((set)->e[++variable##_i].p) ) 00169 00170 /*-<a href="qh-c.htm#set" 00171 >--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a> 00172 00173 FOREACHsetelementreverse_(type, set, variable)- 00174 define FOREACH iterator in reverse order 00175 00176 declare: 00177 assumes *variable and **variablep are declared 00178 also declare 'int variabletemp' 00179 00180 each iteration: 00181 variable is set element 00182 00183 to repeat an element: 00184 variabletemp++; / *repeat* / 00185 00186 at exit: 00187 variable is NULL 00188 00189 example: 00190 #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex ) 00191 00192 notes: 00193 use FOREACHsetelementreverse12_() to reverse first two elements 00194 WARNING: needs braces if nested inside another FOREACH 00195 */ 00196 #define FOREACHsetelementreverse_(type, set, variable) \ 00197 if (((variable= NULL), set)) for(\ 00198 variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\ 00199 variable; variable= \ 00200 ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL)) 00201 00202 /*-<a href="qh-c.htm#set" 00203 >-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a> 00204 00205 FOREACHsetelementreverse12_(type, set, variable)- 00206 define FOREACH iterator with e[1] and e[0] reversed 00207 00208 declare: 00209 assumes *variable and **variablep are declared 00210 00211 each iteration: 00212 variable is set element 00213 variablep is one after variable. 00214 00215 to repeat an element: 00216 variablep--; / *repeat* / 00217 00218 at exit: 00219 variable is NULL at end of loop 00220 00221 example 00222 #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex ) 00223 00224 notes: 00225 WARNING: needs braces if nested inside another FOREACH 00226 */ 00227 #define FOREACHsetelementreverse12_(type, set, variable) \ 00228 if (((variable= NULL), set)) for(\ 00229 variable##p= (type **)&((set)->e[1].p); \ 00230 (variable= *variable##p); \ 00231 variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \ 00232 (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++)) 00233 00234 /*-<a href="qh-c.htm#set" 00235 >-----------------------------------</a><a name="FOREACHelem_">-</a> 00236 00237 FOREACHelem_( set )- 00238 iterate elements in a set 00239 00240 declare: 00241 void *elem, *elemp; 00242 00243 each iteration: 00244 elem is set element 00245 elemp is one beyond 00246 00247 to repeat an element: 00248 elemp--; / *repeat* / 00249 00250 at exit: 00251 elem == NULL at end of loop 00252 00253 example: 00254 FOREACHelem_(set) { 00255 00256 notes: 00257 WARNING: needs braces if nested inside another FOREACH 00258 */ 00259 #define FOREACHelem_(set) FOREACHsetelement_(void, set, elem) 00260 00261 /*-<a href="qh-c.htm#set" 00262 >-----------------------------------</a><a name="FOREACHset_">-</a> 00263 00264 FOREACHset_( set )- 00265 iterate a set of sets 00266 00267 declare: 00268 setT *set, **setp; 00269 00270 each iteration: 00271 set is set element 00272 setp is one beyond 00273 00274 to repeat an element: 00275 setp--; / *repeat* / 00276 00277 at exit: 00278 set == NULL at end of loop 00279 00280 example 00281 FOREACHset_(sets) { 00282 00283 notes: 00284 WARNING: needs braces if nested inside another FOREACH 00285 */ 00286 #define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set) 00287 00288 /*-<a href="qh-c.htm#set" 00289 >-----------------------------------------</a><a name="SETindex_">-</a> 00290 00291 SETindex_( set, elem ) 00292 return index of elem in set 00293 00294 notes: 00295 for use with FOREACH iteration 00296 00297 example: 00298 i= SETindex_(ridges, ridge) 00299 */ 00300 #define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p) 00301 00302 /*-<a href="qh-c.htm#set" 00303 >---------------------------------------</a><a name="SETref_">-</a> 00304 00305 SETref_( elem ) 00306 l.h.s. for modifying the current element in a FOREACH iteration 00307 00308 example: 00309 SETref_(ridge)= anotherridge; 00310 */ 00311 #define SETref_(elem) (elem##p[-1]) 00312 00313 /*-<a href="qh-c.htm#set" 00314 >---------------------------------------</a><a name="SETelem_">-</a> 00315 00316 SETelem_(set, n) 00317 return the n'th element of set 00318 00319 notes: 00320 assumes that n is valid [0..size] and that set is defined 00321 use SETelemt_() for type cast 00322 */ 00323 #define SETelem_(set, n) ((set)->e[n].p) 00324 00325 /*-<a href="qh-c.htm#set" 00326 >---------------------------------------</a><a name="SETelemt_">-</a> 00327 00328 SETelemt_(set, n, type) 00329 return the n'th element of set as a type 00330 00331 notes: 00332 assumes that n is valid [0..size] and that set is defined 00333 */ 00334 #define SETelemt_(set, n, type) ((type*)((set)->e[n].p)) 00335 00336 /*-<a href="qh-c.htm#set" 00337 >---------------------------------------</a><a name="SETelemaddr_">-</a> 00338 00339 SETelemaddr_(set, n, type) 00340 return address of the n'th element of a set 00341 00342 notes: 00343 assumes that n is valid [0..size] and set is defined 00344 */ 00345 #define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p))) 00346 00347 /*-<a href="qh-c.htm#set" 00348 >---------------------------------------</a><a name="SETfirst_">-</a> 00349 00350 SETfirst_(set) 00351 return first element of set 00352 00353 */ 00354 #define SETfirst_(set) ((set)->e[0].p) 00355 00356 /*-<a href="qh-c.htm#set" 00357 >---------------------------------------</a><a name="SETfirstt_">-</a> 00358 00359 SETfirstt_(set, type) 00360 return first element of set as a type 00361 00362 */ 00363 #define SETfirstt_(set, type) ((type*)((set)->e[0].p)) 00364 00365 /*-<a href="qh-c.htm#set" 00366 >---------------------------------------</a><a name="SETsecond_">-</a> 00367 00368 SETsecond_(set) 00369 return second element of set 00370 00371 */ 00372 #define SETsecond_(set) ((set)->e[1].p) 00373 00374 /*-<a href="qh-c.htm#set" 00375 >---------------------------------------</a><a name="SETsecondt_">-</a> 00376 00377 SETsecondt_(set, type) 00378 return second element of set as a type 00379 */ 00380 #define SETsecondt_(set, type) ((type*)((set)->e[1].p)) 00381 00382 /*-<a href="qh-c.htm#set" 00383 >---------------------------------------</a><a name="SETaddr_">-</a> 00384 00385 SETaddr_(set, type) 00386 return address of set's elements 00387 */ 00388 #define SETaddr_(set,type) ((type **)(&((set)->e[0].p))) 00389 00390 /*-<a href="qh-c.htm#set" 00391 >---------------------------------------</a><a name="SETreturnsize_">-</a> 00392 00393 SETreturnsize_(set, size) 00394 return size of a set 00395 00396 notes: 00397 set must be defined 00398 use qh_setsize(set) unless speed is critical 00399 */ 00400 #define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize)) 00401 00402 /*-<a href="qh-c.htm#set" 00403 >---------------------------------------</a><a name="SETempty_">-</a> 00404 00405 SETempty_(set) 00406 return true (1) if set is empty 00407 00408 notes: 00409 set may be NULL 00410 */ 00411 #define SETempty_(set) (!set || (SETfirst_(set) ? 0:1)) 00412 00413 /*======= prototypes in alphabetical order ============*/ 00414 00415 void qh_setaddsorted(setT **setp, void *elem); 00416 void qh_setaddnth(setT **setp, int nth, void *newelem); 00417 void qh_setappend(setT **setp, void *elem); 00418 void qh_setappend_set(setT **setp, setT *setA); 00419 void qh_setappend2ndlast(setT **setp, void *elem); 00420 void qh_setcheck(setT *set, char *tname, int id); 00421 void qh_setcompact(setT *set); 00422 setT *qh_setcopy(setT *set, int extra); 00423 void *qh_setdel(setT *set, void *elem); 00424 void *qh_setdellast(setT *set); 00425 void *qh_setdelnth(setT *set, int nth); 00426 void *qh_setdelnthsorted(setT *set, int nth); 00427 void *qh_setdelsorted(setT *set, void *newelem); 00428 setT *qh_setduplicate( setT *set, int elemsize); 00429 int qh_setequal(setT *setA, setT *setB); 00430 int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB); 00431 int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB); 00432 void qh_setfree(setT **set); 00433 void qh_setfree2( setT **setp, int elemsize); 00434 void qh_setfreelong(setT **set); 00435 int qh_setin(setT *set, void *setelem); 00436 int qh_setindex(setT *set, void *setelem); 00437 void qh_setlarger(setT **setp); 00438 void *qh_setlast(setT *set); 00439 setT *qh_setnew(int size); 00440 setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend); 00441 void qh_setprint(FILE *fp, char* string, setT *set); 00442 void qh_setreplace(setT *set, void *oldelem, void *newelem); 00443 int qh_setsize(setT *set); 00444 setT *qh_settemp(int setsize); 00445 void qh_settempfree(setT **set); 00446 void qh_settempfree_all(void); 00447 setT *qh_settemppop(void); 00448 void qh_settemppush(setT *set); 00449 void qh_settruncate (setT *set, int size); 00450 int qh_setunique (setT **set, void *elem); 00451 void qh_setzero (setT *set, int index, int size); 00452 00453 00454 #endif /* qhDEFset */