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 }