ucx/list.c

changeset 121
311cac04d079
parent 120
8170f658f017
child 122
540d99722f1f
     1.1 --- a/ucx/list.c	Sat Jul 20 11:13:26 2013 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,255 +0,0 @@
     1.4 -/*
     1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 - *
     1.7 - * Copyright 2013 Olaf Wintermann. All rights reserved.
     1.8 - *
     1.9 - * Redistribution and use in source and binary forms, with or without
    1.10 - * modification, are permitted provided that the following conditions are met:
    1.11 - *
    1.12 - *   1. Redistributions of source code must retain the above copyright
    1.13 - *      notice, this list of conditions and the following disclaimer.
    1.14 - *
    1.15 - *   2. Redistributions in binary form must reproduce the above copyright
    1.16 - *      notice, this list of conditions and the following disclaimer in the
    1.17 - *      documentation and/or other materials provided with the distribution.
    1.18 - *
    1.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    1.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.29 - * POSSIBILITY OF SUCH DAMAGE.
    1.30 - */
    1.31 -
    1.32 -#include "list.h"
    1.33 -
    1.34 -UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) {
    1.35 -    UcxList *ret = NULL;
    1.36 -    while (l != NULL) {
    1.37 -        if (fnc != NULL) {
    1.38 -            ret = ucx_list_append(ret, fnc(l->data, data));
    1.39 -        } else {
    1.40 -            ret = ucx_list_append(ret, l->data);
    1.41 -        }
    1.42 -        l = l->next;
    1.43 -    }
    1.44 -    return ret;
    1.45 -}
    1.46 -
    1.47 -int ucx_list_equals(const UcxList *l1, const UcxList *l2,
    1.48 -        cmp_func fnc, void* data) {
    1.49 -    if (l1 == l2) return 1;
    1.50 -    
    1.51 -    while (l1 != NULL && l2 != NULL) {
    1.52 -        if (fnc == NULL) {
    1.53 -            if (l1->data != l2->data) return 0;
    1.54 -        } else {
    1.55 -            if (fnc(l1->data, l2->data, data) != 0) return 0;
    1.56 -        }
    1.57 -        l1 = l1->next;
    1.58 -        l2 = l2->next;
    1.59 -    }
    1.60 -    
    1.61 -    return (l1 == NULL && l2 == NULL);
    1.62 -}
    1.63 -
    1.64 -void ucx_list_free(UcxList *l) {
    1.65 -    UcxList *e = l, *f;
    1.66 -    while (e != NULL) {
    1.67 -        f = e;
    1.68 -        e = e->next;
    1.69 -        free(f);
    1.70 -    }
    1.71 -}
    1.72 -
    1.73 -UcxList *ucx_list_append(UcxList *l, void *data)  {
    1.74 -    UcxList *nl = (UcxList*) malloc(sizeof(UcxList));
    1.75 -    if (nl == NULL) return NULL;
    1.76 -    
    1.77 -    nl->data = data;
    1.78 -    nl->next = NULL;
    1.79 -    if (l == NULL) {
    1.80 -        return nl;
    1.81 -    } else {
    1.82 -        UcxList *t = ucx_list_last(l);
    1.83 -        t->next = nl;
    1.84 -        return l;
    1.85 -    }
    1.86 -}
    1.87 -
    1.88 -UcxList *ucx_list_prepend(UcxList *l, void *data) {
    1.89 -    UcxList *nl = ucx_list_append(NULL, data);
    1.90 -    if (nl == NULL) return NULL;
    1.91 -    
    1.92 -    if (l != NULL) {
    1.93 -        nl->next = l;
    1.94 -    }
    1.95 -    return nl;
    1.96 -}
    1.97 -
    1.98 -UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) {
    1.99 -    if (l1 == NULL) {
   1.100 -        return l2;
   1.101 -    } else {
   1.102 -        UcxList *last = ucx_list_last(l1);
   1.103 -        last->next = l2;
   1.104 -        return l1;
   1.105 -    }
   1.106 -}
   1.107 -
   1.108 -UcxList *ucx_list_last(const UcxList *l) {
   1.109 -    if (l == NULL) return NULL;
   1.110 -    
   1.111 -    const UcxList *e = l;
   1.112 -    while (e->next != NULL) {
   1.113 -        e = e->next;
   1.114 -    }
   1.115 -    return (UcxList*)e;
   1.116 -}
   1.117 -
   1.118 -UcxList *ucx_list_get(const UcxList *l, int index) {
   1.119 -    if (l == NULL) return NULL;
   1.120 -
   1.121 -    const UcxList *e = l;
   1.122 -    while (e->next != NULL && index > 0) {
   1.123 -        e = e->next;
   1.124 -        index--;
   1.125 -    }
   1.126 -    
   1.127 -    return (UcxList*)(index == 0 ? e : NULL);
   1.128 -}
   1.129 -
   1.130 -int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
   1.131 -    UCX_FOREACH(UcxList*, l, e) {
   1.132 -        if (!fnc(elem, e->data, cmpdata)) {
   1.133 -            return 1;
   1.134 -        }
   1.135 -    }
   1.136 -    return 0;
   1.137 -}
   1.138 -
   1.139 -size_t ucx_list_size(const UcxList *l) {
   1.140 -    if (l == NULL) return 0;
   1.141 -    
   1.142 -    const UcxList *e = l;
   1.143 -    size_t s = 1;
   1.144 -    while (e->next != NULL) {
   1.145 -        e = e->next;
   1.146 -        s++;
   1.147 -    }
   1.148 -
   1.149 -    return s;
   1.150 -}
   1.151 -
   1.152 -UcxList *ucx_list_sort_merge(int length,
   1.153 -        UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re,
   1.154 -        cmp_func fnc, void* data) {
   1.155 -
   1.156 -    UcxList** sorted = (UcxList**) malloc(sizeof(UcxList*)*length);
   1.157 -    UcxList *rc, *lc;
   1.158 -
   1.159 -    lc = ls; rc = le;
   1.160 -    int n = 0;
   1.161 -    while (lc && lc != le && rc != re) {
   1.162 -        if (fnc(lc->data, rc->data, data) <= 0) {
   1.163 -            sorted[n] = lc;
   1.164 -            lc = lc->next;
   1.165 -        } else {
   1.166 -            sorted[n] = rc;
   1.167 -            rc = rc->next;
   1.168 -        }
   1.169 -        n++;
   1.170 -    }
   1.171 -    while (lc && lc != le) {
   1.172 -        sorted[n] = lc;
   1.173 -        lc = lc->next;
   1.174 -        n++;
   1.175 -    }
   1.176 -    while (rc && rc != re) {
   1.177 -        sorted[n] = rc;
   1.178 -        rc = rc->next;
   1.179 -        n++;
   1.180 -    }
   1.181 -
   1.182 -    // Update pointer
   1.183 -    for (int i = 0 ; i < length-1 ; i++) {
   1.184 -        sorted[i]->next = sorted[i+1];
   1.185 -    }
   1.186 -    sorted[length-1]->next = NULL;
   1.187 -
   1.188 -    UcxList *ret = sorted[0];
   1.189 -    free(sorted);
   1.190 -    return ret;
   1.191 -}
   1.192 -
   1.193 -UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) {
   1.194 -    if (l == NULL) {
   1.195 -        return NULL;
   1.196 -    }
   1.197 -
   1.198 -    UcxList *lc;
   1.199 -    int ln = 1;
   1.200 -
   1.201 -    UcxList *restrict ls = l, *restrict le, *restrict re;
   1.202 -    lc = ls;
   1.203 -    while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) {
   1.204 -        lc = lc->next;
   1.205 -        ln++;
   1.206 -    }
   1.207 -    le = lc->next;
   1.208 -
   1.209 -    if (le == NULL) {
   1.210 -        return l; // this list is already sorted :)
   1.211 -    } else {
   1.212 -        UcxList *rc;
   1.213 -        int rn = 1;
   1.214 -        rc = le;
   1.215 -        while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) {
   1.216 -            rc = rc->next;
   1.217 -            rn++;
   1.218 -        }
   1.219 -        re = rc->next;
   1.220 -
   1.221 -        // Something left? Sort it!
   1.222 -        UcxList *remainder = re;
   1.223 -        size_t remainder_length = ucx_list_size(remainder);
   1.224 -        if (remainder != NULL) {
   1.225 -            remainder = ucx_list_sort(remainder, fnc, data);
   1.226 -        }
   1.227 -
   1.228 -        // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
   1.229 -        UcxList *sorted = ucx_list_sort_merge(ln+rn,
   1.230 -                ls, le, re,
   1.231 -                fnc, data);
   1.232 -
   1.233 -        // merge sorted list with (also sorted) remainder
   1.234 -        l = ucx_list_sort_merge(ln+rn+remainder_length,
   1.235 -                sorted, remainder, NULL, fnc, data);
   1.236 -
   1.237 -        return l;
   1.238 -    }
   1.239 -}
   1.240 -
   1.241 -/* list specific functions */
   1.242 -UcxList *ucx_list_remove(UcxList *l, UcxList *e) {
   1.243 -    if (e == l) {
   1.244 -        l = e->next;
   1.245 -        free(e);
   1.246 -    } else {
   1.247 -        UcxList *f = l;
   1.248 -        while (f->next != NULL && f->next != e) {
   1.249 -            f = f->next;
   1.250 -        }
   1.251 -        /* perform remove if this element is found in this list */
   1.252 -        if (f->next == e) {
   1.253 -            f->next = e->next;
   1.254 -            free(e);
   1.255 -        }
   1.256 -    }
   1.257 -    return l;
   1.258 -}

mercurial