qset_r.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /*<html><pre> -<a href="qh-set_r.htm"
  2. >-------------------------------</a><a name="TOP">-</a>
  3. qset_r.h
  4. header file for qset_r.c that implements set
  5. see qh-set_r.htm and qset_r.c
  6. only uses mem_r.c, malloc/free
  7. for error handling, writes message and calls
  8. qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL);
  9. set operations satisfy the following properties:
  10. - sets have a max size, the actual size (if different) is stored at the end
  11. - every set is NULL terminated
  12. - sets may be sorted or unsorted, the caller must distinguish this
  13. Copyright (c) 1993-2020 The Geometry Center.
  14. $Id: //main/2019/qhull/src/libqhull_r/qset_r.h#4 $$Change: 2953 $
  15. $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
  16. */
  17. #ifndef qhDEFset
  18. #define qhDEFset 1
  19. #include <stdio.h>
  20. /*================= -structures- ===============*/
  21. #ifndef DEFsetT
  22. #define DEFsetT 1
  23. typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
  24. #endif
  25. #ifndef DEFqhT
  26. #define DEFqhT 1
  27. typedef struct qhT qhT; /* defined in libqhull_r.h */
  28. #endif
  29. /* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
  30. /*-<a href="qh-set_r.htm#TOC"
  31. >----------------------------------------</a><a name="setT">-</a>
  32. setT
  33. a set or list of pointers with maximum size and actual size.
  34. variations:
  35. unsorted, unique -- a list of unique pointers with NULL terminator
  36. user guarantees uniqueness
  37. sorted -- a sorted list of unique pointers with NULL terminator
  38. qset_r.c guarantees uniqueness
  39. unsorted -- a list of pointers terminated with NULL
  40. indexed -- an array of pointers with NULL elements
  41. structure for set of n elements:
  42. --------------
  43. | maxsize
  44. --------------
  45. | e[0] - a pointer, may be NULL for indexed sets
  46. --------------
  47. | e[1]
  48. --------------
  49. | ...
  50. --------------
  51. | e[n-1]
  52. --------------
  53. | e[n] = NULL
  54. --------------
  55. | ...
  56. --------------
  57. | e[maxsize] - n+1 or NULL (determines actual size of set)
  58. --------------
  59. */
  60. /*-- setelemT -- internal type to allow both pointers and indices
  61. */
  62. typedef union setelemT setelemT;
  63. union setelemT {
  64. void *p;
  65. int i; /* integer used for e[maxSize] */
  66. };
  67. struct setT {
  68. int maxsize; /* maximum number of elements (except NULL) */
  69. setelemT e[1]; /* array of pointers, tail is NULL */
  70. /* last slot (unless NULL) is actual size+1
  71. e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
  72. /* this may generate a warning since e[] contains
  73. maxsize elements */
  74. };
  75. /*=========== -constants- =========================*/
  76. /*-<a href="qh-set_r.htm#TOC"
  77. >-----------------------------------</a><a name="SETelemsize">-</a>
  78. SETelemsize
  79. size of a set element in bytes
  80. */
  81. #define SETelemsize ((int)sizeof(setelemT))
  82. /*=========== -macros- =========================*/
  83. /*-<a href="qh-set_r.htm#TOC"
  84. >-----------------------------------</a><a name="FOREACHsetelement_">-</a>
  85. FOREACHsetelement_(type, set, variable)
  86. define FOREACH iterator
  87. declare:
  88. assumes *variable and **variablep are declared
  89. no space in "variable)" [DEC Alpha cc compiler]
  90. each iteration:
  91. variable is set element
  92. variablep is one beyond variable.
  93. to repeat an element:
  94. variablep--; / *repeat* /
  95. at exit:
  96. variable is NULL at end of loop
  97. example:
  98. #define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
  99. notes:
  100. use FOREACHsetelement_i_() if need index or include NULLs
  101. assumes set is not modified
  102. WARNING:
  103. nested loops can't use the same variable (define another FOREACH)
  104. needs braces if nested inside another FOREACH
  105. this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
  106. */
  107. #define FOREACHsetelement_(type, set, variable) \
  108. if (((variable= NULL), set)) for (\
  109. variable##p= (type **)&((set)->e[0].p); \
  110. (variable= *variable##p++);)
  111. /*-<a href="qh-set_r.htm#TOC"
  112. >----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
  113. FOREACHsetelement_i_(qh, type, set, variable)
  114. define indexed FOREACH iterator
  115. declare:
  116. type *variable, variable_n, variable_i;
  117. each iteration:
  118. variable is set element, may be NULL
  119. variable_i is index, variable_n is qh_setsize()
  120. to repeat an element:
  121. variable_i--; variable_n-- repeats for deleted element
  122. at exit:
  123. variable==NULL and variable_i==variable_n
  124. example:
  125. #define FOREACHfacet_i_(qh, facets) FOREACHsetelement_i_(qh, facetT, facets, facet)
  126. WARNING:
  127. nested loops can't use the same variable (define another FOREACH)
  128. needs braces if nested inside another FOREACH
  129. this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
  130. */
  131. #define FOREACHsetelement_i_(qh, type, set, variable) \
  132. if (((variable= NULL), set)) for (\
  133. variable##_i= 0, variable= (type *)((set)->e[0].p), \
  134. variable##_n= qh_setsize(qh, set);\
  135. variable##_i < variable##_n;\
  136. variable= (type *)((set)->e[++variable##_i].p) )
  137. /*-<a href="qh-set_r.htm#TOC"
  138. >--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
  139. FOREACHsetelementreverse_(qh, type, set, variable)-
  140. define FOREACH iterator in reverse order
  141. declare:
  142. assumes *variable and **variablep are declared
  143. also declare 'int variabletemp'
  144. each iteration:
  145. variable is set element
  146. to repeat an element:
  147. variabletemp++; / *repeat* /
  148. at exit:
  149. variable is NULL
  150. example:
  151. #define FOREACHvertexreverse_(vertices) FOREACHsetelementreverse_(vertexT, vertices, vertex)
  152. notes:
  153. use FOREACHsetelementreverse12_() to reverse first two elements
  154. WARNING: needs braces if nested inside another FOREACH
  155. */
  156. #define FOREACHsetelementreverse_(qh, type, set, variable) \
  157. if (((variable= NULL), set)) for (\
  158. variable##temp= qh_setsize(qh, set)-1, variable= qh_setlast(qh, set);\
  159. variable; variable= \
  160. ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
  161. /*-<a href="qh-set_r.htm#TOC"
  162. >-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
  163. FOREACHsetelementreverse12_(type, set, variable)-
  164. define FOREACH iterator with e[1] and e[0] reversed
  165. declare:
  166. assumes *variable and **variablep are declared
  167. each iteration:
  168. variable is set element
  169. variablep is one after variable.
  170. to repeat an element:
  171. variablep--; / *repeat* /
  172. at exit:
  173. variable is NULL at end of loop
  174. example
  175. #define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
  176. notes:
  177. WARNING: needs braces if nested inside another FOREACH
  178. */
  179. #define FOREACHsetelementreverse12_(type, set, variable) \
  180. if (((variable= NULL), set)) for (\
  181. variable##p= (type **)&((set)->e[1].p); \
  182. (variable= *variable##p); \
  183. variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
  184. (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
  185. /*-<a href="qh-set_r.htm#TOC"
  186. >-----------------------------------</a><a name="FOREACHelem_">-</a>
  187. FOREACHelem_( set )-
  188. iterate elements in a set
  189. declare:
  190. void *elem, *elemp;
  191. each iteration:
  192. elem is set element
  193. elemp is one beyond
  194. to repeat an element:
  195. elemp--; / *repeat* /
  196. at exit:
  197. elem == NULL at end of loop
  198. example:
  199. FOREACHelem_(set) {
  200. notes:
  201. assumes set is not modified
  202. WARNING: needs braces if nested inside another FOREACH
  203. */
  204. #define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
  205. /*-<a href="qh-set_r.htm#TOC"
  206. >-----------------------------------</a><a name="FOREACHset_">-</a>
  207. FOREACHset_( set )-
  208. iterate a set of sets
  209. declare:
  210. setT *set, **setp;
  211. each iteration:
  212. set is set element
  213. setp is one beyond
  214. to repeat an element:
  215. setp--; / *repeat* /
  216. at exit:
  217. set == NULL at end of loop
  218. example
  219. FOREACHset_(sets) {
  220. notes:
  221. WARNING: needs braces if nested inside another FOREACH
  222. */
  223. #define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
  224. /*-<a href="qh-set_r.htm#TOC"
  225. >-----------------------------------------</a><a name="SETindex_">-</a>
  226. SETindex_( set, elem )
  227. return index of elem in set
  228. notes:
  229. for use with FOREACH iteration
  230. WARN64 -- Maximum set size is 2G
  231. example:
  232. i= SETindex_(ridges, ridge)
  233. */
  234. #define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
  235. /*-<a href="qh-set_r.htm#TOC"
  236. >---------------------------------------</a><a name="SETref_">-</a>
  237. SETref_( elem )
  238. l.h.s. for modifying the current element in a FOREACH iteration
  239. example:
  240. SETref_(ridge)= anotherridge;
  241. */
  242. #define SETref_(elem) (elem##p[-1])
  243. /*-<a href="qh-set_r.htm#TOC"
  244. >---------------------------------------</a><a name="SETelem_">-</a>
  245. SETelem_(set, n)
  246. return the n'th element of set
  247. notes:
  248. assumes that n is valid [0..size] and that set is defined
  249. use SETelemt_() for type cast
  250. */
  251. #define SETelem_(set, n) ((set)->e[n].p)
  252. /*-<a href="qh-set_r.htm#TOC"
  253. >---------------------------------------</a><a name="SETelemt_">-</a>
  254. SETelemt_(set, n, type)
  255. return the n'th element of set as a type
  256. notes:
  257. assumes that n is valid [0..size] and that set is defined
  258. */
  259. #define SETelemt_(set, n, type) ((type *)((set)->e[n].p))
  260. /*-<a href="qh-set_r.htm#TOC"
  261. >---------------------------------------</a><a name="SETelemaddr_">-</a>
  262. SETelemaddr_(set, n, type)
  263. return address of the n'th element of a set
  264. notes:
  265. assumes that n is valid [0..size] and set is defined
  266. */
  267. #define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
  268. /*-<a href="qh-set_r.htm#TOC"
  269. >---------------------------------------</a><a name="SETfirst_">-</a>
  270. SETfirst_(set)
  271. return first element of set
  272. */
  273. #define SETfirst_(set) ((set)->e[0].p)
  274. /*-<a href="qh-set_r.htm#TOC"
  275. >---------------------------------------</a><a name="SETfirstt_">-</a>
  276. SETfirstt_(set, type)
  277. return first element of set as a type
  278. */
  279. #define SETfirstt_(set, type) ((type *)((set)->e[0].p))
  280. /*-<a href="qh-set_r.htm#TOC"
  281. >---------------------------------------</a><a name="SETsecond_">-</a>
  282. SETsecond_(set)
  283. return second element of set
  284. */
  285. #define SETsecond_(set) ((set)->e[1].p)
  286. /*-<a href="qh-set_r.htm#TOC"
  287. >---------------------------------------</a><a name="SETsecondt_">-</a>
  288. SETsecondt_(set, type)
  289. return second element of set as a type
  290. */
  291. #define SETsecondt_(set, type) ((type *)((set)->e[1].p))
  292. /*-<a href="qh-set_r.htm#TOC"
  293. >---------------------------------------</a><a name="SETaddr_">-</a>
  294. SETaddr_(set, type)
  295. return address of set's elements
  296. */
  297. #define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
  298. /*-<a href="qh-set_r.htm#TOC"
  299. >---------------------------------------</a><a name="SETreturnsize_">-</a>
  300. SETreturnsize_(set, size)
  301. return size of a set
  302. notes:
  303. set must be defined
  304. use qh_setsize(qhT *qh, set) unless speed is critical
  305. */
  306. #define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
  307. /*-<a href="qh-set_r.htm#TOC"
  308. >---------------------------------------</a><a name="SETempty_">-</a>
  309. SETempty_(set)
  310. return true(1) if set is empty (i.e., FOREACHsetelement_ is empty)
  311. notes:
  312. set may be NULL
  313. qh_setsize may be non-zero if first element is NULL
  314. */
  315. #define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
  316. /*-<a href="qh-set_r.htm#TOC"
  317. >-------------------------------<a name="SETsizeaddr_">-</a>
  318. SETsizeaddr_(set)
  319. return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
  320. Its type is setelemT* for strict aliasing
  321. All SETelemaddr_ must be cast to setelemT
  322. notes:
  323. *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
  324. */
  325. #define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
  326. /*-<a href="qh-set_r.htm#TOC"
  327. >---------------------------------------</a><a name="SETtruncate_">-</a>
  328. SETtruncate_(set, size)
  329. truncate set to size
  330. see:
  331. qh_settruncate()
  332. */
  333. #define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
  334. set->e[size].p= NULL;}
  335. /*======= prototypes in alphabetical order ============*/
  336. #ifdef __cplusplus
  337. extern "C" {
  338. #endif
  339. void qh_setaddsorted(qhT *qh, setT **setp, void *elem);
  340. void qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem);
  341. void qh_setappend(qhT *qh, setT **setp, void *elem);
  342. void qh_setappend_set(qhT *qh, setT **setp, setT *setA);
  343. void qh_setappend2ndlast(qhT *qh, setT **setp, void *elem);
  344. void qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned int id);
  345. void qh_setcompact(qhT *qh, setT *set);
  346. setT *qh_setcopy(qhT *qh, setT *set, int extra);
  347. void *qh_setdel(setT *set, void *elem);
  348. void *qh_setdellast(setT *set);
  349. void *qh_setdelnth(qhT *qh, setT *set, int nth);
  350. void *qh_setdelnthsorted(qhT *qh, setT *set, int nth);
  351. void *qh_setdelsorted(setT *set, void *newelem);
  352. setT *qh_setduplicate(qhT *qh, setT *set, int elemsize);
  353. void **qh_setendpointer(setT *set);
  354. int qh_setequal(setT *setA, setT *setB);
  355. int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
  356. int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
  357. void qh_setfree(qhT *qh, setT **set);
  358. void qh_setfree2(qhT *qh, setT **setp, int elemsize);
  359. void qh_setfreelong(qhT *qh, setT **set);
  360. int qh_setin(setT *set, void *setelem);
  361. int qh_setindex(setT *set, void *setelem);
  362. void qh_setlarger(qhT *qh, setT **setp);
  363. int qh_setlarger_quick(qhT *qh, int setsize, int *newsize);
  364. void *qh_setlast(setT *set);
  365. setT *qh_setnew(qhT *qh, int size);
  366. setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend);
  367. void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
  368. void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
  369. int qh_setsize(qhT *qh, setT *set);
  370. setT *qh_settemp(qhT *qh, int setsize);
  371. void qh_settempfree(qhT *qh, setT **set);
  372. void qh_settempfree_all(qhT *qh);
  373. setT *qh_settemppop(qhT *qh);
  374. void qh_settemppush(qhT *qh, setT *set);
  375. void qh_settruncate(qhT *qh, setT *set, int size);
  376. int qh_setunique(qhT *qh, setT **set, void *elem);
  377. void qh_setzero(qhT *qh, setT *set, int idx, int size);
  378. #ifdef __cplusplus
  379. } /* extern "C" */
  380. #endif
  381. #endif /* qhDEFset */