📄 qset.c
字号:
return SETelem_(set, set->maxsize - 1);
else if (size > 1)
return SETelem_(set, size - 2);
}
return NULL;
} /* setlast */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setnew">-</a>
qh_setnew( setsize )
creates and allocates space for a set
notes:
setsize means the number of elements (NOT including the NULL terminator)
use qh_settemp/qh_setfreetemp if set is temporary
design:
allocate memory for set
roundup memory if small set
initialize as empty set
*/
setT *qh_setnew(int setsize) {
setT *set;
int sizereceived; /* used !qh_NOmem */
int size;
void **freelistp; /* used !qh_NOmem */
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setnew_delnthsorted">-</a>
qh_setnew_delnthsorted( set, size, nth, prepend )
creates a sorted set not containing nth element
if prepend, the first prepend elements are undefined
notes:
set must be defined
checks nth
see also: setdelnthsorted
design:
create new set
setup pointers and allocate room for prepend'ed entries
append head of old set to new set
append tail of old set to new set
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setprint">-</a>
qh_setprint( fp, string, set )
print set elements to fp with identifying string
notes:
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setreplace">-</a>
qh_setreplace( set, oldelem, newelem )
replaces oldelem in set with newelem
notes:
errors if oldelem not in the set
newelem may be NULL, but it turns the set into an indexed set (no FOREACH)
design:
find oldelem
replace with newelem
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setsize">-</a>
qh_setsize( set )
returns the size of a set
notes:
errors if set's maxsize is incorrect
same as SETreturnsize_(set)
design:
determine actual size of set from maxsize
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settemp">-</a>
qh_settemp( setsize )
return a stacked, temporary set of upto setsize elements
notes:
use settempfree or settempfree_all to release from qhmem.tempstack
see also qh_setnew
design:
allocate set
append to qhmem.tempstack
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settempfree">-</a>
qh_settempfree( set )
free temporary set at top of qhmem.tempstack
notes:
nop if set is NULL
errors if set not from previous qh_settemp
to locate errors:
use 'T2' to find source and then find mis-matching qh_settemp
design:
check top of qhmem.tempstack
free it
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settempfree_all">-</a>
qh_settempfree_all( )
free all temporary sets in qhmem.tempstack
design:
for each set in tempstack
free set
free qhmem.tempstack
*/
void qh_settempfree_all(void) {
setT *set, **setp;
FOREACHset_((setT *)qhmem.tempstack)
qh_setfree(&set);
qh_setfree((setT **)&qhmem.tempstack);
} /* settempfree_all */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settemppop">-</a>
qh_settemppop( )
pop and return temporary set from qhmem.tempstack
notes:
the returned set is permanent
design:
pop and check top of qhmem.tempstack
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settemppush">-</a>
qh_settemppush( set )
push temporary set unto qhmem.tempstack (makes it temporary)
notes:
duplicates settemp() for tracing
design:
append set to tempstack
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="settruncate">-</a>
qh_settruncate( set, size )
truncate set to size elements
notes:
set must be defined
design:
check size
update actual size of set
*/
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 */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setunique">-</a>
qh_setunique( set, elem )
add elem to unsorted set unless it is already in set
notes:
returns 1 if it is appended
design:
if elem not in set
append elem to set
*/
int qh_setunique (setT **set, void *elem) {
if (!qh_setin (*set, elem)) {
qh_setappend (set, elem);
return 1;
}
return 0;
} /* setunique */
/*-<a href="qh-c.htm#set"
>-------------------------------<a name="setzero">-</a>
qh_setzero( set, index, size )
zero elements from index on
set actual size of set to size
notes:
set must be defined
the set becomes an indexed set (can not use FOREACH...)
see also:
qh_settruncate
design:
check index and size
update actual size
zero elements starting at e[index]
*/
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 + -