PDP-8-E-Simulator/Categories/NSMutableArray+BinarySearch.m

97 lines
2.5 KiB
Objective-C

/*
* PDP-8/E Simulator
*
* Copyright © 1994-2015 Bernhard Baehr
*
* NSMutableArray+BinarySearch.m - Category for binary search
*
* This file is part of PDP-8/E Simulator.
*
* PDP-8/E Simulator is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Cocoa/Cocoa.h>
#import "NSMutableArray+BinarySearch.h"
@implementation NSMutableArray (BinarySearch)
- (unsigned) addObject:(id)object toArraySortedBy:(SEL)compare replaceExistingObject:(BOOL)replace
{
int n = [self count];
if (n == 0) {
[self addObject:object];
return 0;
}
NSRange range = NSMakeRange(0, n);
while (range.length > 0) {
unsigned m = range.location + range.length / 2;
switch ((NSComparisonResult)
[[self objectAtIndex:m] performSelector:compare withObject:object]) {
case NSOrderedAscending:
n = range.location + range.length;
range.location = m + 1;
range.length = n - range.location;
break;
case NSOrderedDescending:
range.length = m - range.location;
break;
case NSOrderedSame:
if (replace)
[self replaceObjectAtIndex:m withObject:object];
return m;
default:
NSAssert (FALSE, @"Invalid comparison result");
break;
}
}
[self insertObject:object atIndex:range.location];
return range.location;
}
- (unsigned) indexOfObject:(id)object inArraySortedBy:(SEL)compare;
{
int n = [self count];
if (n == 0)
return NSNotFound;
NSRange range = NSMakeRange(0, n);
while (range.length > 0) {
unsigned m = range.location + range.length / 2;
switch ((NSComparisonResult)
[[self objectAtIndex:m] performSelector:compare withObject:object]) {
case NSOrderedAscending:
n = range.location + range.length;
range.location = m + 1;
range.length = n - range.location;
break;
case NSOrderedDescending:
range.length = m - range.location;
break;
case NSOrderedSame:
return m;
default:
NSAssert (FALSE, @"Invalid comparison result");
break;
}
}
return NSNotFound;
}
@end