// // MPRange.m // MathPad // // Created by Kim Wittenburg on 18.04.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPRange.h" @implementation MPRange #pragma mark Creation Methods - (instancetype)init { return [self initWithLocation:[[NSIndexPath alloc] init] length:0]; } - (instancetype)initWithLocation:(NSIndexPath *)location length:(NSUInteger)length { self = [super init]; if (self) { _location = location; _length = length; } return self; } - (instancetype)initWithRange:(NSRange)aRange { return [self initWithLocation:[[NSIndexPath alloc] initWithIndex:aRange.location] length:aRange.length]; } + (instancetype)emptyRange { return [[self alloc] init]; } + (instancetype)rangeWithLocation:(NSIndexPath *)location length:(NSUInteger)length { return [[self alloc] initWithLocation:location length:length]; } + (instancetype)rangeWithRange:(NSRange)aRange { return [[self alloc] initWithRange:aRange]; } #pragma mark Properties - (NSIndexPath *)maxRange { NSUInteger lastIndex = [self.location indexAtPosition:self.location.length-1]; NSUInteger newLastIndex = lastIndex + self.length; return [[self.location indexPathByRemovingLastIndex] indexPathByAddingIndex:newLastIndex]; } - (NSRange)rangeAtLastIndex { return NSMakeRange([self.location indexAtPosition:self.location.length-1], self.length); } #pragma mark Working with Ranges - (BOOL)containsRange:(MPRange *)aRange { if (aRange.location.length < self.location.length) { return NO; } // Compare indices (except the last one) for (NSUInteger pos = 0; pos < self.location.length-1; pos++) { NSUInteger selfIndex = [self.location indexAtPosition:pos]; NSUInteger otherIndex = [aRange.location indexAtPosition:pos]; if (selfIndex != otherIndex) { return NO; } } // Compare range at last index NSUInteger selfIndex = [self.location indexAtPosition:self.location.length-1]; NSUInteger otherIndex = [aRange.location indexAtPosition:self.location.length-1]; if (aRange.location.length > self.location.length) { return NSLocationInRange(otherIndex, self.rangeAtLastIndex); } else { return otherIndex >= selfIndex && NSMaxRange(aRange.rangeAtLastIndex) <= NSMaxRange(self.rangeAtLastIndex); } } - (BOOL)containsLocation:(NSIndexPath *)location { return [self containsRange:[[MPRange alloc] initWithLocation:location length:0]]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (object == nil) { return NO; } if (![object isKindOfClass:[MPRange class]]) { return NO; } return [self isEqualToRange:(MPRange *)object]; } - (BOOL)isEqualToRange:(MPRange *)aRange { return [self.location isEqual:aRange.location] && self.length == aRange.length; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { MPRange *copy = [[MPRange allocWithZone:zone] initWithLocation:self.location.copy length:self.length]; return copy; } #pragma mark - NSCoding - (id)initWithCoder:(NSCoder *)aDecoder { return [self initWithLocation:[aDecoder decodeObjectForKey:@"location"] length:[aDecoder decodeIntegerForKey:@"length"]]; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.location forKey:@"location"]; [aCoder encodeInteger:self.length forKey:@"length"]; } @end