rcx

miscellaneous C library
git clone git://git.rr3.xyz/rcx
Log | Files | Refs | README | LICENSE

defs.h (1728B)


      1 int
      2 LIST_METHOD(resize)(LIST_T **l, usize cap) {
      3 	if (cap == 0) {
      4 		LIST_METHOD(free)(l);
      5 		return 0;
      6 	}
      7 
      8 	cap = MAX(cap, LIST_MIN_CAP);
      9 	RListHdr_ *h = *l ? LIST_HDR(*l) : 0;
     10 	usize len = h ? h->len : 0;
     11 	usize arrsize = cap * sizeof (*l)[0];
     12 	if (r_mul_will_overflow_(cap, sizeof (*l)[0])
     13 			|| sizeof *h > USIZE_MAX - arrsize) {
     14 		errno = ENOMEM;
     15 		return -1;
     16 	}
     17 	if (LIST_REALLOC(&h, sizeof *h + arrsize) < 0) return -1;
     18 	h->len = MIN(len, cap);
     19 	h->cap = cap;
     20 	*l = (void *)(h + 1);
     21 	return 0;
     22 }
     23 
     24 int
     25 LIST_METHOD(reserve)(LIST_T **l, usize n) {
     26 	RListHdr_ *h = *l ? LIST_HDR(*l) : 0;
     27 	usize rem = h ? h->cap - h->len : 0;
     28 	if (n > rem) {
     29 		usize need = n - rem;
     30 		/* Set cap such that the list capacity at least doubles. */
     31 		usize cap = h ? h->cap + MAX(h->cap, need) : need;
     32 		/* Check for overflow. */
     33 		if (h && cap < h->cap) {
     34 			errno = ENOMEM;
     35 			return -1;
     36 		}
     37 		return LIST_METHOD(resize)(l, cap);
     38 	}
     39 	return 0;
     40 }
     41 
     42 int
     43 LIST_METHOD(insarr)(LIST_T **dst, usize i, LIST_T *src, usize n) {
     44 	LIST_ASSERT(i <= LIST_METHOD(len)(dst),
     45 		STRINGIFY(LIST_METHOD(insarr))" called with i out of bounds");
     46 	/* Return early with n == 0, so that LIST_HDR use below is valid. */
     47 	if (n == 0) return 0;
     48 	if (LIST_METHOD(reserve)(dst, n) < 0) return -1;
     49 	usize m = LIST_HDR(*dst)->len - i;
     50 	memmove(&(*dst)[i+n], &(*dst)[i], m * sizeof (*dst)[0]);
     51 	memcpy(&(*dst)[i], src, n * sizeof (*dst)[0]);
     52 	LIST_HDR(*dst)->len += n;
     53 	return 0;
     54 }
     55 
     56 LIST_T
     57 LIST_METHOD(del)(LIST_T **l, usize i) {
     58 	LIST_ASSERT(i < LIST_METHOD(len)(l),
     59 		STRINGIFY(LIST_METHOD(del))" called with i out of bounds");
     60 	LIST_T e = (*l)[i];
     61 	usize m = LIST_HDR(*l)->len - i - 1;
     62 	memmove(&(*l)[i], &(*l)[i+1], m * sizeof (*l)[0]);
     63 	LIST_HDR(*l)->len -= 1;
     64 	return e;
     65 }