Artifact 18ec5ebfccd156f2fb44b9b442be80c2c5222f30eff04aebfe65f5aab83b4469:
- File
src/OFList.m
— part of check-in
[bbf1f79b8f]
at
2009-09-08 16:06:10
on branch trunk
— New OFDictionary implementation and removal of a hack in OFList.
The new implementation is easier to use as it does automatic resizing,
but therefore it's not realtime-capable anymore. The new implementation
should also be a little bit faster.I decided to change the implementation as only very few need a
realtime-capable dictionary and those few will most likely write their
own implementation for their specific case anyway.As the new implementation no longer uses OFList, this also made it
possible to remove a hack from OFList. (user: js, size: 3923) [annotate] [blame] [check-ins using]
/* * Copyright (c) 2008 - 2009 * Jonathan Schleifer <js@webkeks.org> * * All rights reserved. * * This file is part of libobjfw. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE included in * the packaging of this file. */ #include "config.h" #include "assert.h" #import "OFList.h" #import "OFExceptions.h" @implementation OFList + list { return [[[self alloc] init] autorelease]; } - init { self = [super init]; first = NULL; last = NULL; retain_and_release = YES; return self; } - initWithoutRetainAndRelease { self = [super init]; first = NULL; last = NULL; return self; } - (void)dealloc { of_list_object_t *iter; for (iter = first; iter != NULL; iter = iter->next) [iter->object release]; [super dealloc]; } - (of_list_object_t*)first { return first; } - (of_list_object_t*)last { return last; } - (of_list_object_t*)append: (id)obj { of_list_object_t *o; o = [self allocMemoryWithSize: sizeof(of_list_object_t)]; o->object = obj; o->next = NULL; o->prev = last; if (last != NULL) last->next = o; last = o; if (first == NULL) first = o; count++; if (retain_and_release) [obj retain]; return o; } - (of_list_object_t*)prepend: (id)obj { of_list_object_t *o; o = [self allocMemoryWithSize: sizeof(of_list_object_t)]; o->object = obj; o->next = first; o->prev = NULL; if (first != NULL) first->prev = o; first = o; if (last == NULL) last = o; count++; if (retain_and_release) [obj retain]; return o; } - (of_list_object_t*)insert: (id)obj before: (of_list_object_t*)listobj { of_list_object_t *o; o = [self allocMemoryWithSize: sizeof(of_list_object_t)]; o->object = obj; o->next = listobj; o->prev = listobj->prev; if (listobj->prev != NULL) listobj->prev->next = o; listobj->prev = o; if (listobj == first) first = o; count++; if (retain_and_release) [obj retain]; return o; } - (of_list_object_t*)insert: (id)obj after: (of_list_object_t*)listobj { of_list_object_t *o; o = [self allocMemoryWithSize: sizeof(of_list_object_t)]; o->object = obj; o->next = listobj->next; o->prev = listobj; if (listobj->next != NULL) listobj->next->prev = o; listobj->next = o; if (listobj == last) last = o; count++; if (retain_and_release) [obj retain]; return o; } - remove: (of_list_object_t*)listobj { if (listobj->prev != NULL) listobj->prev->next = listobj->next; if (listobj->next != NULL) listobj->next->prev = listobj->prev; if (first == listobj) first = listobj->next; if (last == listobj) last = listobj->prev; count--; if (retain_and_release) [listobj->object release]; [self freeMemory: listobj]; return self; } - (size_t)count { return count; } - (BOOL)isEqual: (id)obj { of_list_object_t *iter, *iter2; if (![obj isKindOfClass: [OFList class]]) return NO; if ([obj count] != count) return NO; for (iter = first, iter2 = [obj first]; iter != NULL && iter2 != NULL; iter = iter->next, iter2 = iter2->next) if (![iter->object isEqual: iter2->object]) return NO; /* One is bigger than the other although we checked the count */ assert(iter == NULL && iter2 == NULL); return YES; } - (id)copy { OFList *new; of_list_object_t *iter, *o, *prev; if (retain_and_release) new = [[OFList alloc] init]; else new = [[OFList alloc] initWithoutRetainAndRelease]; o = NULL; prev = NULL; @try { for (iter = first; iter != NULL; iter = iter->next) { o = [new allocMemoryWithSize: sizeof(of_list_object_t)]; o->object = iter->object; o->next = NULL; o->prev = prev; if (new->first == NULL) new->first = o; if (prev != NULL) prev->next = o; new->count++; if (retain_and_release) [o->object retain]; prev = o; } } @catch (OFException *e) { [new release]; @throw e; } new->last = o; return new; } @end