📄 set.c
字号:
skipAp= SETelemaddr_(setA, skipA, void); skipBp= SETelemaddr_(setB, skipB, void); while (1) { if (elemA == skipAp) elemA++; if (elemB == skipBp) elemB++; if (!*elemA) break; if (*elemA++ != *elemB++) return 0; } if (*elemB) return 0; return 1;} /* setequal_skip */ /*-----------------------------------------setfree- frees the space occupied by a sorted or unsorted set set may be NULL*/void qh_setfree(setT **setp) { int size; void **freelistp; if (*setp) { size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; if (size <= qhmem.LASTsize) { qh_memfree_(*setp, size, freelistp); }else qh_memfree (*setp, size); *setp= NULL; }} /* setfree *//*-----------------------------------------setfree2- frees the space occupied by a set and its elements set may be NULL*/void qh_setfree2 (setT **setp, int elemsize) { void *elem, **elemp; FOREACHelem_(*setp) qh_memfree (elem, elemsize); qh_setfree (setp);} /* setfree2 */ /*-----------------------------------------setfreelong- frees a set only if it's in long memory set may be NULL*/void qh_setfreelong(setT **setp) { int size; if (*setp) { size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; if (size > qhmem.LASTsize) { qh_memfree (*setp, size); *setp= NULL; } }} /* setfreelong *//*-----------------------------------------setin- returns 1 if setelem is in a set, 0 otherwise set may be NULL or unsorted*/int qh_setin(setT *set, void *setelem) { void *elem, **elemp; FOREACHelem_(set) { if (elem == setelem) return 1; } return 0;} /* setin *//*-----------------------------------------setindex- returns the index of elem in set. If none, returns -1 set may be NULL and may contain nulls.*/int qh_setindex(setT *set, void *atelem) { void **elem; int size, i; SETreturnsize_(set, size); if (size > set->maxsize) return -1; elem= SETaddr_(set, void); for (i=0; i<size; i++) { if (*elem++ == atelem) return i; } return -1;} /* setindex *//*-----------------------------------------setlarger- returns a larger set that contains elements of *setp the set is at least twice as large updates qhmem.tempstack if needed*/void qh_setlarger(setT **oldsetp) { int size= 1, *sizep; setT *newset, *set, **setp, *oldset; void **oldp, **newp; if (*oldsetp) { oldset= *oldsetp; SETreturnsize_(oldset, size); qhmem.cntlarger++; qhmem.totlarger += size+1; newset= qh_setnew(2 * size); oldp= SETaddr_(oldset, void); newp= SETaddr_(newset, void); memcpy((char *)newp, (char *)oldp, (size+1) * SETelemsize); sizep= SETsizeaddr_(newset); *sizep= size+1; FOREACHset_((setT *)qhmem.tempstack) { if (set == oldset) *(setp-1)= newset; } qh_setfree(oldsetp); }else newset= qh_setnew(3); *oldsetp= newset;} /* setlarger *//*-----------------------------------------setlast- return last element of set or NULL (use type conversion) set may be NULL*/void *qh_setlast(setT *set) { int size; if (set) { size= *SETsizeaddr_(set); if (!size) return SETelem_(set, set->maxsize - 1); else if (size > 1) return SETelem_(set, size - 2); } return NULL;} /* setlast *//*-----------------------------------------setnew- creates and allocates space for a set setsize means the number of elements (NOT including the NULL terminator) use qh_settemp/qh_setfreetemp if set is temporary*/setT *qh_setnew(int setsize) { setT *set; int sizereceived, size; void **freelistp; if (!setsize) setsize++; size= sizeof(setT) + setsize * SETelemsize; if ((unsigned) size <= (unsigned) qhmem.LASTsize) { qh_memalloc_(size, freelistp, set, setT);#ifndef qh_NOmem sizereceived= qhmem.sizetable[ qhmem.indextable[size]]; if (sizereceived > size) setsize += (sizereceived - size)/SETelemsize;#endif }else set= (setT*)qh_memalloc (size); set->maxsize= setsize; set->e[setsize].i= 1; set->e[0].p= NULL; return (set);} /* setnew *//*-----------------------------------------setnew_delnthsorted- creates a sorted set not containing nth element the new set may have prepended undefined entries set must be defined checks nth see also: setdelnthsorted*/setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) { setT *newset; void **oldp, **newp; int tailsize= size - nth -1, newsize; if (tailsize < 0) { fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); qh_setprint (qhmem.ferr, "", set); qh_errexit (qhmem_ERRqhull, NULL, NULL); } newsize= size-1 + prepend; newset= qh_setnew(newsize); newset->e[newset->maxsize].i= newsize+1; /* may be overwritten */ oldp= SETaddr_(set, void); newp= SETaddr_(newset, void) + prepend; switch (nth) { case 0: break; case 1: *(newp++)= *oldp++; break; case 2: *(newp++)= *oldp++; *(newp++)= *oldp++; break; case 3: *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; break; case 4: *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; break; default: memcpy((char *)newp, (char *)oldp, nth * SETelemsize); newp += nth; oldp += nth; break; } oldp++; switch (tailsize) { case 0: break; case 1: *(newp++)= *oldp++; break; case 2: *(newp++)= *oldp++; *(newp++)= *oldp++; break; case 3: *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; break; case 4: *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; *(newp++)= *oldp++; break; default: memcpy((char *)newp, (char *)oldp, tailsize * SETelemsize); newp += tailsize; } *newp= NULL; return(newset);} /* setnew_delnthsorted *//*-----------------------------------------setprint- print set elements to fpnotes: never errors*/void qh_setprint(FILE *fp, char* string, setT *set) { int size, k; if (!set) fprintf (fp, "%s set is null\n", string); else { SETreturnsize_(set, size); fprintf (fp, "%s set=%p maxsize=%d size=%d elems=", string, set, set->maxsize, size); if (size > set->maxsize) size= set->maxsize+1; for (k=0; k<size; k++) fprintf(fp, " %p", set->e[k].p); fprintf(fp, "\n"); }} /* setprint *//*-----------------------------------------setreplace- replaces oldelem in set with newelem errors if oldelem not in the set if newelem is NULL then FOREACH no longer works*/void qh_setreplace(setT *set, void *oldelem, void *newelem) { void **elemp; elemp= SETaddr_(set, void); while(*elemp != oldelem && *elemp) elemp++; if (*elemp) *elemp= newelem; else { fprintf (qhmem.ferr, "qhull internal error (qh_setreplace): elem %p not found in set\n", oldelem); qh_setprint (qhmem.ferr, "", set); qh_errexit (qhmem_ERRqhull, NULL, NULL); }} /* setreplace *//*-----------------------------------------setsize- returns the size of a set same as SETreturnsize_(set)*/int qh_setsize(setT *set) { int size, *sizep; if (!set) return (0); sizep= SETsizeaddr_(set); if ((size= *sizep)) { size--; if (size > set->maxsize) { fprintf (qhmem.ferr, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n", size, set->maxsize); qh_setprint (qhmem.ferr, "set: ", set); qh_errexit (qhmem_ERRqhull, NULL, NULL); } }else size= set->maxsize; return size;} /* setsize *//*-----------------------------------------settemp- return a stacked, temporary set use settempfree or settempfree_all to release from qhmem.tempstack see also qh_setnew*/setT *qh_settemp(int setsize) { setT *newset; newset= qh_setnew (setsize); qh_setappend ((setT **)&qhmem.tempstack, newset); if (qhmem.IStracing >= 5) fprintf (qhmem.ferr, "qh_settemp: temp set %p of %d elements, depth %d\n", newset, newset->maxsize, qh_setsize ((setT*)qhmem.tempstack)); return newset;} /* settemp *//*-----------------------------------------settempfree- free temporary set at top of qhmem.tempstack nop if NULL errors if set not from previous qh_settemp locate source by T2 and find mis-matching qh_settemp*/void qh_settempfree(setT **set) { setT *stackedset; if (!*set) return; stackedset= qh_settemppop (); if (stackedset != *set) { qh_settemppush(stackedset); fprintf (qhmem.ferr, "qhull internal error (qh_settempfree): set %p (size %d) was not last temporary allocated (depth %d, set %p, size %d)\n", *set, qh_setsize(*set), qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset)); qh_errexit (qhmem_ERRqhull, NULL, NULL); } qh_setfree (set);} /* settempfree *//*-----------------------------------------settempfree_all- free all temporary sets in qhmem.tempstack*/void qh_settempfree_all(void) { setT *set, **setp; FOREACHset_((setT *)qhmem.tempstack) qh_setfree(&set); qh_setfree((setT **)&qhmem.tempstack);} /* settempfree_all *//*-----------------------------------------settemppop- pop and return temporary set from qhmem.tempstack (makes it permanent)*/setT *qh_settemppop(void) { setT *stackedset; stackedset= (setT*)qh_setdellast((setT *)qhmem.tempstack); if (!stackedset) { fprintf (qhmem.ferr, "qhull internal error (qh_settemppop): pop from empty temporary stack\n"); qh_errexit (qhmem_ERRqhull, NULL, NULL); } if (qhmem.IStracing >= 5) fprintf (qhmem.ferr, "qh_settemppop: depth %d temp set %p of %d elements\n", qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset)); return stackedset;} /* settemppop *//*-----------------------------------------settemppush- push temporary set unto qhmem.tempstack (makes it temporary) duplicates settemp() for tracing*/void qh_settemppush(setT *set) { qh_setappend ((setT**)&qhmem.tempstack, set); if (qhmem.IStracing >= 5) fprintf (qhmem.ferr, "qh_settemppush: depth %d temp set %p of %d elements\n", qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set));} /* settemppush */ /*-----------------------------------------settruncate- truncate set to size elements set must be defined*/void qh_settruncate (setT *set, int size) { if (size < 0 || size > set->maxsize) { fprintf (qhmem.ferr, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size); qh_setprint (qhmem.ferr, "", set); qh_errexit (qhmem_ERRqhull, NULL, NULL); } set->e[set->maxsize].i= size+1; /* maybe overwritten */ set->e[size].p= NULL;} /* settruncate */ /*-----------------------------------------setunique- add element if it isn't already returns 1 if it's appended*/int qh_setunique (setT **set, void *elem) { if (!qh_setin (*set, elem)) { qh_setappend (set, elem); return 1; } return 0;} /* setunique */ /*-----------------------------------------setzero- zero remainder of set and set its size set must be defined*/void qh_setzero (setT *set, int index, int size) { int count; if (index < 0 || index >= size || size > set->maxsize) { fprintf (qhmem.ferr, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size); qh_setprint (qhmem.ferr, "", set); qh_errexit (qhmem_ERRqhull, NULL, NULL); } set->e[set->maxsize].i= size+1; /* may be overwritten */ count= size - index + 1; /* +1 for NULL terminator */ memset ((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize);} /* setzero */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -