Skip to content
Snippets Groups Projects
bl00mbox_containers.c 2.42 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "bl00mbox_containers.h"
    
    static bool equals(void * some, void * other, bl00mbox_set_key_t key){
        if(!key) return some == other;
        return key(some, other);
    }
    
    static bool set_add_inner(bl00mbox_set_t * set, void * content){
        bl00mbox_ll_t * ll = malloc(sizeof(bl00mbox_ll_t));
        if(!ll) return false;
        ll->content = content;
        ll->next = set->start;
        set->start = ll;
        set->len++;
        return true;
    }
    
    bool bl00mbox_set_contains(bl00mbox_set_t * set, void * content){
        if(!content) return false; // NULL pointers can't be in set
        if(!set->start) return false;
        bl00mbox_ll_t * seek = set->start;
        while(seek){
            if(equals(seek->content, content, set->key)) break;
            seek = seek->next;
        }
        return seek;
    }
    
    bool bl00mbox_set_add_skip_unique_check(bl00mbox_set_t * set, void * content){
        if(!content) return false; // don't allow for NULL pointers in set
    #ifdef BL00MBOX_DEBUG
        if(bl00mbox_set_contains(set, content)){
            bl00mbox_log_error("set corrupted");
            return false;
        }
    #endif
        return set_add_inner(set, content);
    }
    
    bool bl00mbox_set_add(bl00mbox_set_t * set, void * content){
        if(bl00mbox_set_contains(set, content)) return false;
        return set_add_inner(set, content);
    }
    
    bool bl00mbox_set_remove(bl00mbox_set_t * set, void * content){
        if(!content) return false;
        bl00mbox_ll_t * seek = set->start;
        bl00mbox_ll_t * prev = NULL;
        while(seek){
            if(equals(seek->content, content, set->key)) break;
            prev = seek;
            seek = seek->next;
        }
        if(seek){
            bl00mbox_ll_t ** target = prev ? &(prev->next) : &(set->start);
            (* target) = seek->next;
            set->len--;
        }
        free(seek);
        return true;
    }
    
    void bl00mbox_set_iter_start(bl00mbox_set_iter_t * iter, bl00mbox_set_t * set){
        iter->next = set->start;
    }
    
    void * bl00mbox_set_iter_next(bl00mbox_set_iter_t * iter){
        if(!iter->next) return NULL;
        void * ret = iter->next->content;
        iter->next = iter->next->next;
        return ret;
    }
    
    bl00mbox_array_t * bl00mbox_set_to_array(bl00mbox_set_t * set){
        bl00mbox_array_t * ret = malloc(sizeof(bl00mbox_array_t) + set->len * sizeof(void *));
        if(!ret) return NULL;
        ret->len = set->len;
        bl00mbox_set_iter_t iter;
        bl00mbox_set_iter_start(&iter, set);
        void * content;
        size_t index = 0;
        while((content = bl00mbox_set_iter_next(&iter))){
            ret->elems[index++] = content;
        }
        return ret;
    }