Artifact 20e48ccd57b9a37ddb4dc8c6a3fc937356f7a34ec56360808f90087b01dacdcf:
- File
src/OFMutableArray.m
— part of check-in
[3d16a30f41]
at
2013-06-22 12:12:36
on branch trunk
— Rework exceptions.
This mostly removes the argument for the class in which the exception
occurred. As backtraces were recently added for all platforms, the
passed class does not give any extra information on where the exception
occurred anymore.This also removes a few other arguments which were not too helpful. In
the past, the idea was to pass as many arguments as possible so that it
is easier to find the origin of the exception. However, as backtraces
are a much better way to find the origin, those are not useful anymore
and just make the exception more cumbersome to use. The rule is now to
only pass arguments that might help in recovering from the exception or
provide information that is otherwise not easily accessible. (user: js, size: 8000) [annotate] [blame] [check-ins using]
/* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 * Jonathan Schleifer <js@webkeks.org> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableArray.h" #import "OFMutableArray_adjacent.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" #import "autorelease.h" #import "macros.h" static struct { Class isa; } placeholder; @interface OFMutableArray_placeholder: OFMutableArray @end static void quicksort(OFMutableArray *array, size_t left, size_t right, int options) { of_comparison_result_t ascending, descending; if (options & OF_SORT_OPTIONS_DESCENDING) { ascending = OF_ORDERED_DESCENDING; descending = OF_ORDERED_ASCENDING; } else { ascending = OF_ORDERED_ASCENDING; descending = OF_ORDERED_DESCENDING; } while (left < right) { size_t i = left; size_t j = right - 1; id pivot = [array objectAtIndex: right]; do { while ([[array objectAtIndex: i] compare: pivot] != descending && i < right) i++; while ([[array objectAtIndex: j] compare: pivot] != ascending && j > left) j--; if (i < j) [array exchangeObjectAtIndex: i withObjectAtIndex: j]; } while (i < j); if ([[array objectAtIndex: i] compare: pivot] == descending) [array exchangeObjectAtIndex: i withObjectAtIndex: right]; if (i > 0) quicksort(array, left, i - 1, options); left = i + 1; } } @implementation OFMutableArray_placeholder - init { return (id)[[OFMutableArray_adjacent alloc] init]; } - initWithCapacity: (size_t)capacity { return (id)[[OFMutableArray_adjacent alloc] initWithCapacity: capacity]; } - initWithObject: (id)object { return (id)[[OFMutableArray_adjacent alloc] initWithObject: object]; } - initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFMutableArray_adjacent alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMutableArray_adjacent alloc] initWithObject: firstObject arguments: arguments]; } - initWithArray: (OFArray*)array { return (id)[[OFMutableArray_adjacent alloc] initWithArray: array]; } - initWithObjects: (id const*)objects count: (size_t)count { return (id)[[OFMutableArray_adjacent alloc] initWithObjects: objects count: count]; } - initWithSerialization: (OFXMLElement*)element { return (id)[[OFMutableArray_adjacent alloc] initWithSerialization: element]; } - retain { return self; } - autorelease { return self; } - (void)release { } - (void)dealloc { [self doesNotRecognizeSelector: _cmd]; abort(); /* Get rid of a stupid warning */ [super dealloc]; } @end @implementation OFMutableArray + (void)initialize { if (self == [OFMutableArray class]) placeholder.isa = [OFMutableArray_placeholder class]; } + alloc { if (self == [OFMutableArray class]) return (id)&placeholder; return [super alloc]; } + (instancetype)arrayWithCapacity: (size_t)capacity { return [[[self alloc] initWithCapacity: capacity] autorelease]; } - init { if (object_getClass(self) == [OFMutableArray class]) { @try { [self doesNotRecognizeSelector: _cmd]; abort(); } @catch (id e) { [self release]; @throw e; } } return [super init]; } - initWithCapacity: (size_t)capacity { @try { [self doesNotRecognizeSelector: _cmd]; } @catch (id e) { [self release]; @throw e; } abort(); } - copy { return [[OFArray alloc] initWithArray: self]; } - (void)addObject: (id)object { [self insertObject: object atIndex: [self count]]; } - (void)addObjectsFromArray: (OFArray*)array { [self insertObjectsFromArray: array atIndex: [self count]]; } - (void)insertObject: (id)object atIndex: (size_t)index { [self doesNotRecognizeSelector: _cmd]; abort(); } - (void)insertObjectsFromArray: (OFArray*)array atIndex: (size_t)index { void *pool = objc_autoreleasePoolPush(); OFEnumerator *enumerator = [array objectEnumerator]; size_t i, count = [array count]; for (i = 0; i < count; i++) { id object = [enumerator nextObject]; assert(object != nil); [self insertObject: object atIndex: index + i]; } objc_autoreleasePoolPop(pool); } - (void)replaceObjectAtIndex: (size_t)index withObject: (id)object { [self doesNotRecognizeSelector: _cmd]; abort(); } - (void)setObject: (id)object atIndexedSubscript: (size_t)index { [self replaceObjectAtIndex: index withObject: object]; } - (void)replaceObject: (id)oldObject withObject: (id)newObject { size_t i, count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = [self count]; for (i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: oldObject]) { [self replaceObjectAtIndex: i withObject: newObject]; return; } } } - (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject { size_t i, count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = [self count]; for (i = 0; i < count; i++) { if ([self objectAtIndex: i] == oldObject) { [self replaceObjectAtIndex: i withObject: newObject]; return; } } } - (void)removeObjectAtIndex: (size_t)index { [self doesNotRecognizeSelector: _cmd]; abort(); } - (void)removeObject: (id)object { size_t i, count; if (object == nil) @throw [OFInvalidArgumentException exception]; count = [self count]; for (i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: object]) { [self removeObjectAtIndex: i]; return; } } } - (void)removeObjectIdenticalTo: (id)object { size_t i, count; if (object == nil) @throw [OFInvalidArgumentException exception]; count = [self count]; for (i = 0; i < count; i++) { if ([self objectAtIndex: i] == object) { [self removeObjectAtIndex: i]; return; } } } - (void)removeObjectsInRange: (of_range_t)range { size_t i; for (i = 0; i < range.length; i++) [self removeObjectAtIndex: range.location]; } - (void)removeLastObject { size_t count = [self count]; if (count == 0) return; [self removeObjectAtIndex: count - 1]; } - (void)removeAllObjects { [self removeObjectsInRange: of_range(0, [self count])]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block { [self enumerateObjectsUsingBlock: ^ (id object, size_t index, bool *stop) { id new = block(object, index); if (new != object) [self replaceObjectAtIndex: index withObject: new]; }]; } #endif - (void)exchangeObjectAtIndex: (size_t)index1 withObjectAtIndex: (size_t)index2 { id object1 = [self objectAtIndex: index1]; id object2 = [self objectAtIndex: index2]; [object1 retain]; @try { [self replaceObjectAtIndex: index1 withObject: object2]; [self replaceObjectAtIndex: index2 withObject: object1]; } @finally { [object1 release]; } } - (void)sort { [self sortWithOptions: 0]; } - (void)sortWithOptions: (int)options { size_t count = [self count]; if (count == 0 || count == 1) return; quicksort(self, 0, count - 1, options); } - (void)reverse { size_t i, j, count = [self count]; if (count == 0 || count == 1) return; for (i = 0, j = count - 1; i < j; i++, j--) [self exchangeObjectAtIndex: i withObjectAtIndex: j]; } - (void)makeImmutable { } @end