src/list.c

changeset 641
d402fead3386
parent 640
55cc3b373c5e
child 647
2e6e9d9f2159
     1.1 --- a/src/list.c	Wed Jan 25 19:19:29 2023 +0100
     1.2 +++ b/src/list.c	Thu Jan 26 20:59:36 2023 +0100
     1.3 @@ -30,6 +30,158 @@
     1.4  
     1.5  #include <string.h>
     1.6  
     1.7 +// <editor-fold desc="Store Pointers Functionality">
     1.8 +
     1.9 +static _Thread_local CxListComparator cx_pl_cmpfunc_impl;
    1.10 +
    1.11 +static int cx_pl_cmpfunc(
    1.12 +        void const *l,
    1.13 +        void const *r
    1.14 +) {
    1.15 +    void *const *lptr = l;
    1.16 +    void *const *rptr = r;
    1.17 +    void const *left = lptr == NULL ? NULL : *lptr;
    1.18 +    void const *right = rptr == NULL ? NULL : *rptr;
    1.19 +    return cx_pl_cmpfunc_impl(left, right);
    1.20 +}
    1.21 +
    1.22 +static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) {
    1.23 +    // cast away const - this is the hacky thing
    1.24 +    struct cx_list_s *l = (struct cx_list_s *) list;
    1.25 +    cx_pl_cmpfunc_impl = l->cmpfunc;
    1.26 +    l->cmpfunc = cx_pl_cmpfunc;
    1.27 +}
    1.28 +
    1.29 +static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) {
    1.30 +    // cast away const - this is the hacky thing
    1.31 +    struct cx_list_s *l = (struct cx_list_s *) list;
    1.32 +    l->cmpfunc = cx_pl_cmpfunc_impl;
    1.33 +}
    1.34 +
    1.35 +static void cx_pl_destructor(struct cx_list_s *list) {
    1.36 +    list->climpl->destructor(list);
    1.37 +}
    1.38 +
    1.39 +static int cx_pl_insert_element(
    1.40 +        struct cx_list_s *list,
    1.41 +        size_t index,
    1.42 +        void const *element
    1.43 +) {
    1.44 +    return list->climpl->insert_element(list, index, &element);
    1.45 +}
    1.46 +
    1.47 +static size_t cx_pl_insert_array(
    1.48 +        struct cx_list_s *list,
    1.49 +        size_t index,
    1.50 +        void const *array,
    1.51 +        size_t n
    1.52 +) {
    1.53 +    return list->climpl->insert_array(list, index, array, n);
    1.54 +}
    1.55 +
    1.56 +static int cx_pl_insert_iter(
    1.57 +        struct cx_mut_iterator_s *iter,
    1.58 +        void const *elem,
    1.59 +        int prepend
    1.60 +) {
    1.61 +    struct cx_list_s *list = iter->src_handle;
    1.62 +    return list->climpl->insert_iter(iter, &elem, prepend);
    1.63 +}
    1.64 +
    1.65 +static int cx_pl_remove(
    1.66 +        struct cx_list_s *list,
    1.67 +        size_t index
    1.68 +) {
    1.69 +    return list->climpl->remove(list, index);
    1.70 +}
    1.71 +
    1.72 +static void *cx_pl_at(
    1.73 +        struct cx_list_s const *list,
    1.74 +        size_t index
    1.75 +) {
    1.76 +    void **ptr = list->climpl->at(list, index);
    1.77 +    return ptr == NULL ? NULL : *ptr;
    1.78 +}
    1.79 +
    1.80 +static size_t cx_pl_find(
    1.81 +        struct cx_list_s const *list,
    1.82 +        void const *elem
    1.83 +) {
    1.84 +    cx_pl_hack_cmpfunc(list);
    1.85 +    size_t ret = list->climpl->find(list, &elem);
    1.86 +    cx_pl_unhack_cmpfunc(list);
    1.87 +    return ret;
    1.88 +}
    1.89 +
    1.90 +static void cx_pl_sort(struct cx_list_s *list) {
    1.91 +    cx_pl_hack_cmpfunc(list);
    1.92 +    list->climpl->sort(list);
    1.93 +    cx_pl_unhack_cmpfunc(list);
    1.94 +}
    1.95 +
    1.96 +static int cx_pl_compare(
    1.97 +        struct cx_list_s const *list,
    1.98 +        struct cx_list_s const *other
    1.99 +) {
   1.100 +    cx_pl_hack_cmpfunc(list);
   1.101 +    int ret = list->climpl->compare(list, other);
   1.102 +    cx_pl_unhack_cmpfunc(list);
   1.103 +    return ret;
   1.104 +}
   1.105 +
   1.106 +static void cx_pl_reverse(struct cx_list_s *list) {
   1.107 +    list->climpl->reverse(list);
   1.108 +}
   1.109 +
   1.110 +static void *cx_pl_iter_current(void const *it) {
   1.111 +    struct cx_iterator_s const *iter = it;
   1.112 +    void **ptr = iter->base.current_impl(it);
   1.113 +    return ptr == NULL ? NULL : *ptr;
   1.114 +}
   1.115 +
   1.116 +static struct cx_iterator_s cx_pl_iterator(
   1.117 +        struct cx_list_s const *list,
   1.118 +        size_t index
   1.119 +) {
   1.120 +    struct cx_iterator_s iter = list->climpl->iterator(list, index);
   1.121 +    iter.base.current_impl = iter.base.current;
   1.122 +    iter.base.current = cx_pl_iter_current;
   1.123 +    return iter;
   1.124 +}
   1.125 +
   1.126 +static cx_list_class cx_pointer_list_class = {
   1.127 +        cx_pl_destructor,
   1.128 +        cx_pl_insert_element,
   1.129 +        cx_pl_insert_array,
   1.130 +        cx_pl_insert_iter,
   1.131 +        cx_pl_remove,
   1.132 +        cx_pl_at,
   1.133 +        cx_pl_find,
   1.134 +        cx_pl_sort,
   1.135 +        cx_pl_compare,
   1.136 +        cx_pl_reverse,
   1.137 +        cx_pl_iterator,
   1.138 +};
   1.139 +
   1.140 +void cxListStoreObjects(CxList *list) {
   1.141 +    if (list->climpl != NULL) {
   1.142 +        list->cl = list->climpl;
   1.143 +        list->climpl = NULL;
   1.144 +    }
   1.145 +}
   1.146 +
   1.147 +void cxListStorePointers(CxList *list) {
   1.148 +    list->itemsize = sizeof(void *);
   1.149 +    list->climpl = list->cl;
   1.150 +    list->cl = &cx_pointer_list_class;
   1.151 +}
   1.152 +
   1.153 +bool cxListIsStoringPointers(CxList *list) {
   1.154 +    return list->climpl != NULL;
   1.155 +}
   1.156 +
   1.157 +// </editor-fold>
   1.158 +
   1.159  void cxListDestroy(CxList *list) {
   1.160      switch (list->content_destructor_type) {
   1.161          case CX_DESTRUCTOR_SIMPLE: {

mercurial