112 lines
2.7 KiB
Objective-C
112 lines
2.7 KiB
Objective-C
//
|
|
// RACIndexSetSequence.m
|
|
// ReactiveObjC
|
|
//
|
|
// Created by Sergey Gavrilyuk on 12/18/13.
|
|
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
|
//
|
|
|
|
#import "RACIndexSetSequence.h"
|
|
|
|
@interface RACIndexSetSequence ()
|
|
|
|
// A buffer holding the `NSUInteger` values to enumerate over.
|
|
//
|
|
// This is mostly used for memory management. Most access should go through
|
|
// `indexes` instead.
|
|
@property (nonatomic, strong, readonly) NSData *data;
|
|
|
|
// The indexes that this sequence should enumerate.
|
|
@property (nonatomic, readonly) const NSUInteger *indexes;
|
|
|
|
// The number of indexes to enumerate.
|
|
@property (nonatomic, readonly) NSUInteger count;
|
|
|
|
@end
|
|
|
|
@implementation RACIndexSetSequence
|
|
|
|
#pragma mark Lifecycle
|
|
|
|
+ (RACSequence *)sequenceWithIndexSet:(NSIndexSet *)indexSet {
|
|
NSUInteger count = indexSet.count;
|
|
|
|
if (count == 0) return self.empty;
|
|
|
|
NSUInteger sizeInBytes = sizeof(NSUInteger) * count;
|
|
|
|
NSMutableData *data = [[NSMutableData alloc] initWithCapacity:sizeInBytes];
|
|
[indexSet getIndexes:data.mutableBytes maxCount:count inIndexRange:NULL];
|
|
|
|
RACIndexSetSequence *seq = [[self alloc] init];
|
|
seq->_data = data;
|
|
seq->_indexes = data.bytes;
|
|
seq->_count = count;
|
|
return seq;
|
|
}
|
|
|
|
+ (instancetype)sequenceWithIndexSetSequence:(RACIndexSetSequence *)indexSetSequence offset:(NSUInteger)offset {
|
|
NSCParameterAssert(offset < indexSetSequence.count);
|
|
|
|
RACIndexSetSequence *seq = [[self alloc] init];
|
|
seq->_data = indexSetSequence.data;
|
|
seq->_indexes = indexSetSequence.indexes + offset;
|
|
seq->_count = indexSetSequence.count - offset;
|
|
return seq;
|
|
}
|
|
|
|
#pragma mark RACSequence
|
|
|
|
- (id)head {
|
|
return @(self.indexes[0]);
|
|
}
|
|
|
|
- (RACSequence *)tail {
|
|
if (self.count <= 1) return [RACSequence empty];
|
|
|
|
return [self.class sequenceWithIndexSetSequence:self offset:1];
|
|
}
|
|
|
|
#pragma mark NSFastEnumeration
|
|
|
|
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id[])stackbuf count:(NSUInteger)len {
|
|
NSCParameterAssert(len > 0);
|
|
|
|
if (state->state >= self.count) {
|
|
// Enumeration has completed.
|
|
return 0;
|
|
}
|
|
|
|
if (state->state == 0) {
|
|
// Enumeration begun, mark the mutation flag.
|
|
state->mutationsPtr = state->extra;
|
|
}
|
|
|
|
state->itemsPtr = stackbuf;
|
|
|
|
unsigned long index = 0;
|
|
while (index < MIN(self.count - state->state, len)) {
|
|
stackbuf[index] = @(self.indexes[index + state->state]);
|
|
++index;
|
|
}
|
|
|
|
state->state += index;
|
|
return index;
|
|
}
|
|
|
|
#pragma mark NSObject
|
|
|
|
- (NSString *)description {
|
|
NSMutableString *indexesStr = [NSMutableString string];
|
|
|
|
for (unsigned int i = 0; i < self.count; ++i) {
|
|
if (i > 0) [indexesStr appendString:@", "];
|
|
|
|
[indexesStr appendFormat:@"%lu", (unsigned long)self.indexes[i]];
|
|
}
|
|
|
|
return [NSString stringWithFormat:@"<%@: %p>{ name = %@, indexes = %@ }", self.class, self, self.name, indexesStr];
|
|
}
|
|
|
|
@end
|