| 28 |
28 |
| 29 #include "cx/linked_list.h" |
29 #include "cx/linked_list.h" |
| 30 #include "cx/compare.h" |
30 #include "cx/compare.h" |
| 31 #include <string.h> |
31 #include <string.h> |
| 32 #include <assert.h> |
32 #include <assert.h> |
| |
33 |
| |
34 #if __STDC_VERSION__ < 202311L |
| |
35 // we cannot simply include stdalign.h |
| |
36 // because Solaris is not entirely C11 complaint |
| |
37 #ifndef __alignof_is_defined |
| |
38 #define alignof _Alignof |
| |
39 #define __alignof_is_defined 1 |
| |
40 #endif |
| |
41 #endif |
| 33 |
42 |
| 34 // LOW LEVEL LINKED LIST FUNCTIONS |
43 // LOW LEVEL LINKED LIST FUNCTIONS |
| 35 |
44 |
| 36 #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off))) |
45 #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off))) |
| 37 #define ll_prev(node) CX_LL_PTR(node, loc_prev) |
46 #define ll_prev(node) CX_LL_PTR(node, loc_prev) |
| 690 return cx_linked_list_at(list->begin, 0, list->loc_next, index); |
699 return cx_linked_list_at(list->begin, 0, list->loc_next, index); |
| 691 } |
700 } |
| 692 } |
701 } |
| 693 |
702 |
| 694 static void *cx_ll_malloc_node(const cx_linked_list *list) { |
703 static void *cx_ll_malloc_node(const cx_linked_list *list) { |
| 695 return cxZalloc(list->base.collection.allocator, |
704 size_t n; |
| 696 list->loc_data + list->base.collection.elem_size + list->extra_data_len); |
705 if (list->extra_data_len == 0) { |
| |
706 n = list->loc_data + list->base.collection.elem_size; |
| |
707 } else { |
| |
708 n = list->loc_extra + list->extra_data_len; |
| |
709 } |
| |
710 return cxZalloc(list->base.collection.allocator, n); |
| 697 } |
711 } |
| 698 |
712 |
| 699 static int cx_ll_insert_at( |
713 static int cx_ll_insert_at( |
| 700 struct cx_list_s *list, |
714 struct cx_list_s *list, |
| 701 void *node, |
715 void *node, |
| 1264 allocator = cxDefaultAllocator; |
1279 allocator = cxDefaultAllocator; |
| 1265 } |
1280 } |
| 1266 |
1281 |
| 1267 cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list)); |
1282 cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list)); |
| 1268 if (list == NULL) return NULL; |
1283 if (list == NULL) return NULL; |
| 1269 list->extra_data_len = 0; |
|
| 1270 list->loc_prev = 0; |
1284 list->loc_prev = 0; |
| 1271 list->loc_next = sizeof(void*); |
1285 list->loc_next = sizeof(void*); |
| 1272 list->loc_data = sizeof(void*)*2; |
1286 list->loc_data = sizeof(void*)*2; |
| |
1287 list->loc_extra = -1; |
| |
1288 list->extra_data_len = 0; |
| 1273 cx_list_init((CxList*)list, &cx_linked_list_class, |
1289 cx_list_init((CxList*)list, &cx_linked_list_class, |
| 1274 allocator, comparator, elem_size); |
1290 allocator, comparator, elem_size); |
| 1275 |
1291 |
| 1276 return (CxList *) list; |
1292 return (CxList *) list; |
| 1277 } |
1293 } |
| |
1294 |
| |
1295 void cx_linked_list_extra_data(cx_linked_list *list, size_t len) { |
| |
1296 list->extra_data_len = len; |
| |
1297 |
| |
1298 off_t loc_extra = list->loc_data + list->base.collection.elem_size; |
| |
1299 size_t alignment = alignof(void*); |
| |
1300 size_t padding = alignment - (loc_extra % alignment); |
| |
1301 list->loc_extra = loc_extra + padding; |
| |
1302 } |