![]() |
API 0.9.5
|
00001 /* 00002 * CPIndexSet.j 00003 * Foundation 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 00024 #define _CPMaxRange(aRange) ((aRange).location + (aRange).length) 00025 #define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength } 00026 #define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length } 00027 00036 @implementation CPIndexSet : CPObject 00037 { 00038 unsigned _count; 00039 CPArray _ranges; 00040 } 00041 00042 // Creating an Index Set 00046 + (id)indexSet 00047 { 00048 return [[self alloc] init]; 00049 } 00050 00054 + (id)indexSetWithIndex:(int)anIndex 00055 { 00056 return [[self alloc] initWithIndex:anIndex]; 00057 } 00058 00063 + (id)indexSetWithIndexesInRange:(CPRange)aRange 00064 { 00065 return [[self alloc] initWithIndexesInRange:aRange]; 00066 } 00067 00068 // Initializing and Index Set 00069 00070 - (id)init 00071 { 00072 return [self initWithIndexesInRange:_CPMakeRange(0, 0)]; 00073 } 00074 00079 - (id)initWithIndex:(CPInteger)anIndex 00080 { 00081 return [self initWithIndexesInRange:_CPMakeRange(anIndex, 1)]; 00082 } 00083 00089 - (id)initWithIndexesInRange:(CPRange)aRange 00090 { 00091 self = [super init]; 00092 00093 if (self) 00094 { 00095 _count = MAX(0, aRange.length); 00096 00097 if (_count > 0) 00098 _ranges = [aRange]; 00099 else 00100 _ranges = []; 00101 } 00102 00103 return self; 00104 } 00105 00111 - (id)initWithIndexSet:(CPIndexSet)anIndexSet 00112 { 00113 self = [super init]; 00114 00115 if (self) 00116 { 00117 _count = [anIndexSet count]; 00118 _ranges = []; 00119 00120 var otherRanges = anIndexSet._ranges, 00121 otherRangesCount = otherRanges.length; 00122 00123 while (otherRangesCount--) 00124 _ranges[otherRangesCount] = _CPMakeRangeCopy(otherRanges[otherRangesCount]); 00125 } 00126 00127 return self; 00128 } 00129 00130 - (BOOL)isEqual:(id)anObject 00131 { 00132 if (self === anObject) 00133 return YES; 00134 00135 if (!anObject || ![anObject isKindOfClass:[CPIndexSet class]]) 00136 return NO; 00137 00138 return [self isEqualToIndexSet:anObject]; 00139 } 00140 00141 // Querying an Index Set 00147 - (BOOL)isEqualToIndexSet:(CPIndexSet)anIndexSet 00148 { 00149 if (!anIndexSet) 00150 return NO; 00151 00152 // Comparisons to ourself are always return YES. 00153 if (self === anIndexSet) 00154 return YES; 00155 00156 var rangesCount = _ranges.length, 00157 otherRanges = anIndexSet._ranges; 00158 00159 // If we have a discrepancy in the number of ranges or the number of indexes, 00160 // simply return NO. 00161 if (rangesCount !== otherRanges.length || _count !== anIndexSet._count) 00162 return NO; 00163 00164 while (rangesCount--) 00165 if (!CPEqualRanges(_ranges[rangesCount], otherRanges[rangesCount])) 00166 return NO; 00167 00168 return YES; 00169 } 00170 00171 - (BOOL)isEqual:(id)anObject 00172 { 00173 return self === anObject || 00174 [anObject isKindOfClass:[self class]] && 00175 [self isEqualToIndexSet:anObject]; 00176 } 00177 00183 - (BOOL)containsIndex:(CPInteger)anIndex 00184 { 00185 return positionOfIndex(_ranges, anIndex) !== CPNotFound; 00186 } 00187 00192 - (BOOL)containsIndexesInRange:(CPRange)aRange 00193 { 00194 if (aRange.length <= 0) 00195 return NO; 00196 00197 // If we have less total indexes than aRange, we can't possibly contain aRange. 00198 if (_count < aRange.length) 00199 return NO; 00200 00201 // Search for first location 00202 var rangeIndex = positionOfIndex(_ranges, aRange.location); 00203 00204 // If we don't have the first location, then we don't contain aRange. 00205 if (rangeIndex === CPNotFound) 00206 return NO; 00207 00208 var range = _ranges[rangeIndex]; 00209 00210 // The intersection must contain all the indexes from the original range. 00211 return CPIntersectionRange(range, aRange).length === aRange.length; 00212 } 00213 00218 - (BOOL)containsIndexes:(CPIndexSet)anIndexSet 00219 { 00220 var otherCount = anIndexSet._count; 00221 00222 if (otherCount <= 0) 00223 return YES; 00224 00225 // If we have less total indexes than anIndexSet, we can't possibly contain aRange. 00226 if (_count < otherCount) 00227 return NO; 00228 00229 var otherRanges = anIndexSet._ranges, 00230 otherRangesCount = otherRanges.length; 00231 00232 while (otherRangesCount--) 00233 if (![self containsIndexesInRange:otherRanges[otherRangesCount]]) 00234 return NO; 00235 00236 return YES; 00237 } 00238 00244 - (BOOL)intersectsIndexesInRange:(CPRange)aRange 00245 { 00246 if (_count <= 0) 00247 return NO; 00248 00249 var lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location); 00250 00251 if (FLOOR(lhsRangeIndex) === lhsRangeIndex) 00252 return YES; 00253 00254 var rhsRangeIndex = assumedPositionOfIndex(_ranges, _CPMaxRange(aRange) - 1); 00255 00256 if (FLOOR(rhsRangeIndex) === rhsRangeIndex) 00257 return YES; 00258 00259 return lhsRangeIndex !== rhsRangeIndex; 00260 } 00261 00265 - (int)count 00266 { 00267 return _count; 00268 } 00269 00270 // Accessing Indexes 00274 - (CPInteger)firstIndex 00275 { 00276 if (_count > 0) 00277 return _ranges[0].location; 00278 00279 return CPNotFound; 00280 } 00281 00285 - (CPInteger)lastIndex 00286 { 00287 if (_count > 0) 00288 return _CPMaxRange(_ranges[_ranges.length - 1]) - 1; 00289 00290 return CPNotFound; 00291 } 00292 00297 - (CPInteger)indexGreaterThanIndex:(CPInteger)anIndex 00298 { 00299 // The first possible index that would satisfy this requirement. 00300 ++anIndex; 00301 00302 // Attempt to find it or something bigger. 00303 var rangeIndex = assumedPositionOfIndex(_ranges, anIndex); 00304 00305 // Nothing at all found? 00306 if (rangeIndex === CPNotFound) 00307 return CPNotFound; 00308 00309 rangeIndex = CEIL(rangeIndex); 00310 00311 if (rangeIndex >= _ranges.length) 00312 return CPNotFound; 00313 00314 var range = _ranges[rangeIndex]; 00315 00316 // Check if it's actually in this range. 00317 if (CPLocationInRange(anIndex, range)) 00318 return anIndex; 00319 00320 // If not, it must be the first element of this range. 00321 return range.location; 00322 } 00323 00328 - (CPInteger)indexLessThanIndex:(CPInteger)anIndex 00329 { 00330 // The first possible index that would satisfy this requirement. 00331 --anIndex; 00332 00333 // Attempt to find it or something smaller. 00334 var rangeIndex = assumedPositionOfIndex(_ranges, anIndex); 00335 00336 // Nothing at all found? 00337 if (rangeIndex === CPNotFound) 00338 return CPNotFound; 00339 00340 rangeIndex = FLOOR(rangeIndex); 00341 00342 if (rangeIndex < 0) 00343 return CPNotFound; 00344 00345 var range = _ranges[rangeIndex]; 00346 00347 // Check if it's actually in this range. 00348 if (CPLocationInRange(anIndex, range)) 00349 return anIndex; 00350 00351 // If not, it must be the first element of this range. 00352 return _CPMaxRange(range) - 1; 00353 } 00354 00359 - (CPInteger)indexGreaterThanOrEqualToIndex:(CPInteger)anIndex 00360 { 00361 return [self indexGreaterThanIndex:anIndex - 1]; 00362 } 00363 00368 - (CPInteger)indexLessThanOrEqualToIndex:(CPInteger)anIndex 00369 { 00370 return [self indexLessThanIndex:anIndex + 1]; 00371 } 00372 00382 - (CPInteger)getIndexes:(CPArray)anArray maxCount:(CPInteger)aMaxCount inIndexRange:(CPRange)aRange 00383 { 00384 if (!_count || aMaxCount === 0 || aRange && !aRange.length) 00385 { 00386 if (aRange) 00387 aRange.length = 0; 00388 00389 return 0; 00390 } 00391 00392 var total = 0; 00393 00394 if (aRange) 00395 { 00396 var firstIndex = aRange.location, 00397 lastIndex = _CPMaxRange(aRange) - 1, 00398 rangeIndex = CEIL(assumedPositionOfIndex(_ranges, firstIndex)), 00399 lastRangeIndex = FLOOR(assumedPositionOfIndex(_ranges, lastIndex)); 00400 } 00401 else 00402 { 00403 var firstIndex = [self firstIndex], 00404 lastIndex = [self lastIndex], 00405 rangeIndex = 0, 00406 lastRangeIndex = _ranges.length - 1; 00407 } 00408 00409 while (rangeIndex <= lastRangeIndex) 00410 { 00411 var range = _ranges[rangeIndex], 00412 index = MAX(firstIndex, range.location), 00413 maxRange = MIN(lastIndex + 1, _CPMaxRange(range)); 00414 00415 for (; index < maxRange; ++index) 00416 { 00417 anArray[total++] = index; 00418 00419 if (total === aMaxCount) 00420 { 00421 // Update aRange if it exists... 00422 if (aRange) 00423 { 00424 aRange.location = index + 1; 00425 aRange.length = lastIndex + 1 - index - 1; 00426 } 00427 00428 return aMaxCount; 00429 } 00430 } 00431 00432 ++rangeIndex; 00433 } 00434 00435 // Update aRange if it exists... 00436 if (aRange) 00437 { 00438 aRange.location = CPNotFound; 00439 aRange.length = 0; 00440 } 00441 00442 return total; 00443 } 00444 00445 - (CPString)description 00446 { 00447 var description = [super description]; 00448 00449 if (_count) 00450 { 00451 var index = 0, 00452 count = _ranges.length; 00453 00454 description += "[number of indexes: " + _count + " (in " + count; 00455 00456 if (count === 1) 00457 description += " range), indexes: ("; 00458 else 00459 description += " ranges), indexes: ("; 00460 00461 for (; index < count; ++index) 00462 { 00463 var range = _ranges[index]; 00464 00465 description += range.location; 00466 00467 if (range.length > 1) 00468 description += "-" + (CPMaxRange(range) - 1); 00469 00470 if (index + 1 < count) 00471 description += " "; 00472 } 00473 00474 description += ")]"; 00475 } 00476 00477 else 00478 description += "(no indexes)"; 00479 00480 return description; 00481 } 00482 00483 @end 00484 00485 @implementation CPIndexSet(CPMutableIndexSet) 00486 00487 // Adding indexes. 00492 - (void)addIndex:(CPInteger)anIndex 00493 { 00494 [self addIndexesInRange:_CPMakeRange(anIndex, 1)]; 00495 } 00496 00501 - (void)addIndexes:(CPIndexSet)anIndexSet 00502 { 00503 var otherRanges = anIndexSet._ranges, 00504 otherRangesCount = otherRanges.length; 00505 00506 // Simply add each range within anIndexSet. 00507 while (otherRangesCount--) 00508 [self addIndexesInRange:otherRanges[otherRangesCount]]; 00509 } 00510 00515 - (void)addIndexesInRange:(CPRange)aRange 00516 { 00517 // If empty range, bail. 00518 if (aRange.length <= 0) 00519 return; 00520 00521 // If we currently don't have any indexes, this represents our entire set. 00522 if (_count <= 0) 00523 { 00524 _count = aRange.length; 00525 _ranges = [aRange]; 00526 00527 return; 00528 } 00529 00530 var rangeCount = _ranges.length, 00531 lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location - 1), 00532 lhsRangeIndexCEIL = CEIL(lhsRangeIndex); 00533 00534 if (lhsRangeIndexCEIL === lhsRangeIndex && lhsRangeIndexCEIL < rangeCount) 00535 aRange = CPUnionRange(aRange, _ranges[lhsRangeIndexCEIL]); 00536 00537 var rhsRangeIndex = assumedPositionOfIndex(_ranges, CPMaxRange(aRange)), 00538 rhsRangeIndexFLOOR = FLOOR(rhsRangeIndex); 00539 00540 if (rhsRangeIndexFLOOR === rhsRangeIndex && rhsRangeIndexFLOOR >= 0) 00541 aRange = CPUnionRange(aRange, _ranges[rhsRangeIndexFLOOR]); 00542 00543 var removalCount = rhsRangeIndexFLOOR - lhsRangeIndexCEIL + 1; 00544 00545 if (removalCount === _ranges.length) 00546 { 00547 _ranges = [aRange]; 00548 _count = aRange.length; 00549 } 00550 00551 else if (removalCount === 1) 00552 { 00553 if (lhsRangeIndexCEIL < _ranges.length) 00554 _count -= _ranges[lhsRangeIndexCEIL].length; 00555 00556 _count += aRange.length; 00557 _ranges[lhsRangeIndexCEIL] = aRange; 00558 } 00559 00560 else 00561 { 00562 if (removalCount > 0) 00563 { 00564 var removal = lhsRangeIndexCEIL, 00565 lastRemoval = lhsRangeIndexCEIL + removalCount - 1; 00566 00567 for (; removal <= lastRemoval; ++removal) 00568 _count -= _ranges[removal].length; 00569 00570 [_ranges removeObjectsInRange:_CPMakeRange(lhsRangeIndexCEIL, removalCount)]; 00571 } 00572 00573 [_ranges insertObject:aRange atIndex:lhsRangeIndexCEIL]; 00574 00575 _count += aRange.length; 00576 } 00577 } 00578 00579 // Removing Indexes 00584 - (void)removeIndex:(CPInteger)anIndex 00585 { 00586 [self removeIndexesInRange:_CPMakeRange(anIndex, 1)]; 00587 } 00588 00594 - (void)removeIndexes:(CPIndexSet)anIndexSet 00595 { 00596 var otherRanges = anIndexSet._ranges, 00597 otherRangesCount = otherRanges.length; 00598 00599 // Simply remove each index from anIndexSet 00600 while (otherRangesCount--) 00601 [self removeIndexesInRange:otherRanges[otherRangesCount]]; 00602 } 00603 00607 - (void)removeAllIndexes 00608 { 00609 _ranges = []; 00610 _count = 0; 00611 } 00612 00618 - (void)removeIndexesInRange:(CPRange)aRange 00619 { 00620 // If empty range, bail. 00621 if (aRange.length <= 0) 00622 return; 00623 00624 // If we currently don't have any indexes, there's nothing to remove. 00625 if (_count <= 0) 00626 return; 00627 00628 var rangeCount = _ranges.length, 00629 lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location), 00630 lhsRangeIndexCEIL = CEIL(lhsRangeIndex); 00631 00632 // Do we fall on an actual existing range? 00633 if (lhsRangeIndex === lhsRangeIndexCEIL && lhsRangeIndexCEIL < rangeCount) 00634 { 00635 var existingRange = _ranges[lhsRangeIndexCEIL]; 00636 00637 // If these ranges don't start in the same place, we have to cull it. 00638 if (aRange.location !== existingRange.location) 00639 { 00640 var maxRange = CPMaxRange(aRange), 00641 existingMaxRange = CPMaxRange(existingRange); 00642 00643 existingRange.length = aRange.location - existingRange.location; 00644 00645 // If this range is internal to the existing range, we have a unique splitting case. 00646 if (maxRange < existingMaxRange) 00647 { 00648 _count -= aRange.length; 00649 [_ranges insertObject:_CPMakeRange(maxRange, existingMaxRange - maxRange) atIndex:lhsRangeIndexCEIL + 1]; 00650 00651 return; 00652 } 00653 else 00654 { 00655 _count -= existingMaxRange - aRange.location; 00656 lhsRangeIndexCEIL += 1; 00657 } 00658 } 00659 } 00660 00661 var rhsRangeIndex = assumedPositionOfIndex(_ranges, CPMaxRange(aRange) - 1), 00662 rhsRangeIndexFLOOR = FLOOR(rhsRangeIndex); 00663 00664 if (rhsRangeIndex === rhsRangeIndexFLOOR && rhsRangeIndexFLOOR >= 0) 00665 { 00666 var maxRange = CPMaxRange(aRange), 00667 existingRange = _ranges[rhsRangeIndexFLOOR], 00668 existingMaxRange = CPMaxRange(existingRange); 00669 00670 if (maxRange !== existingMaxRange) 00671 { 00672 _count -= maxRange - existingRange.location; 00673 rhsRangeIndexFLOOR -= 1; // This is accounted for, and thus as if we got the previous spot. 00674 00675 existingRange.location = maxRange; 00676 existingRange.length = existingMaxRange - maxRange; 00677 } 00678 } 00679 00680 var removalCount = rhsRangeIndexFLOOR - lhsRangeIndexCEIL + 1; 00681 00682 if (removalCount > 0) 00683 { 00684 var removal = lhsRangeIndexCEIL, 00685 lastRemoval = lhsRangeIndexCEIL + removalCount - 1; 00686 00687 for (; removal <= lastRemoval; ++removal) 00688 _count -= _ranges[removal].length; 00689 00690 [_ranges removeObjectsInRange:_CPMakeRange(lhsRangeIndexCEIL, removalCount)]; 00691 } 00692 } 00693 00694 // Shifting Index Groups 00701 - (void)shiftIndexesStartingAtIndex:(CPInteger)anIndex by:(int)aDelta 00702 { 00703 if (!_count || aDelta == 0) 00704 return; 00705 00706 // Later indexes have a higher probability of being shifted 00707 // than lower ones, so start at the end and work backwards. 00708 var i = _ranges.length - 1, 00709 shifted = CPMakeRange(CPNotFound, 0); 00710 00711 for (; i >= 0; --i) 00712 { 00713 var range = _ranges[i], 00714 maximum = CPMaxRange(range); 00715 00716 if (anIndex >= maximum) 00717 break; 00718 00719 // If our index is within our range, but not the first index, 00720 // then this range will be split. 00721 if (anIndex > range.location) 00722 { 00723 // Split the range into shift and unshifted. 00724 shifted = CPMakeRange(anIndex + aDelta, maximum - anIndex); 00725 range.length = anIndex - range.location; 00726 00727 // If our delta is positive, then we can simply add the range 00728 // to the array. 00729 if (aDelta > 0) 00730 [_ranges insertObject:shifted atIndex:i + 1]; 00731 // If it's negative, it needs to be added properly later. 00732 else if (shifted.location < 0) 00733 { 00734 shifted.length = CPMaxRange(shifted); 00735 shifted.location = 0; 00736 } 00737 00738 // We don't need to continue. 00739 break; 00740 } 00741 00742 // Shift the range, and normalize it if the result is negative. 00743 if ((range.location += aDelta) < 0) 00744 { 00745 _count -= range.length - CPMaxRange(range); 00746 range.length = CPMaxRange(range); 00747 range.location = 0; 00748 } 00749 } 00750 00751 // We need to add the shifted ranges if the delta is negative. 00752 if (aDelta < 0) 00753 { 00754 var j = i + 1, 00755 count = _ranges.length, 00756 shifts = []; 00757 00758 for (; j < count; ++j) 00759 { 00760 [shifts addObject:_ranges[j]]; 00761 _count -= _ranges[j].length; 00762 } 00763 00764 if ((j = i + 1) < count) 00765 { 00766 [_ranges removeObjectsInRange:CPMakeRange(j, count - j)]; 00767 00768 for (j = 0, count = shifts.length; j < count; ++j) 00769 [self addIndexesInRange:shifts[j]]; 00770 } 00771 00772 if (shifted.location != CPNotFound) 00773 [self addIndexesInRange:shifted]; 00774 } 00775 } 00776 00777 @end 00778 00779 var CPIndexSetCountKey = @"CPIndexSetCountKey", 00780 CPIndexSetRangeStringsKey = @"CPIndexSetRangeStringsKey"; 00781 00782 @implementation CPIndexSet (CPCoding) 00783 00790 - (id)initWithCoder:(CPCoder)aCoder 00791 { 00792 self = [super init]; 00793 00794 if (self) 00795 { 00796 _count = [aCoder decodeIntForKey:CPIndexSetCountKey]; 00797 _ranges = []; 00798 00799 var rangeStrings = [aCoder decodeObjectForKey:CPIndexSetRangeStringsKey], 00800 index = 0, 00801 count = rangeStrings.length; 00802 00803 for (; index < count; ++index) 00804 _ranges.push(CPRangeFromString(rangeStrings[index])); 00805 } 00806 00807 return self; 00808 } 00809 00815 - (void)encodeWithCoder:(CPCoder)aCoder 00816 { 00817 [aCoder encodeInt:_count forKey:CPIndexSetCountKey]; 00818 00819 var index = 0, 00820 count = _ranges.length, 00821 rangeStrings = []; 00822 00823 for (; index < count; ++index) 00824 rangeStrings[index] = CPStringFromRange(_ranges[index]); 00825 00826 [aCoder encodeObject:rangeStrings forKey:CPIndexSetRangeStringsKey]; 00827 } 00828 00829 @end 00830 00831 @implementation CPIndexSet (CPCopying) 00832 00839 - (id)copy 00840 { 00841 return [[[self class] alloc] initWithIndexSet:self]; 00842 } 00843 00850 - (id)mutableCopy 00851 { 00852 return [[[self class] alloc] initWithIndexSet:self]; 00853 } 00854 00855 @end 00856 00865 @implementation CPMutableIndexSet : CPIndexSet 00866 { 00867 id __doxygen__; 00868 } 00869 00870 @end 00871 00872 var positionOfIndex = function(ranges, anIndex) 00873 { 00874 var low = 0, 00875 high = ranges.length - 1; 00876 00877 while (low <= high) 00878 { 00879 var middle = FLOOR(low + (high - low) / 2), 00880 range = ranges[middle]; 00881 00882 if (anIndex < range.location) 00883 high = middle - 1; 00884 00885 else if (anIndex >= CPMaxRange(range)) 00886 low = middle + 1; 00887 00888 else 00889 return middle; 00890 } 00891 00892 return CPNotFound; 00893 } 00894 00895 var assumedPositionOfIndex = function(ranges, anIndex) 00896 { 00897 var count = ranges.length; 00898 00899 if (count <= 0) 00900 return CPNotFound; 00901 00902 var low = 0, 00903 high = count * 2; 00904 00905 while (low <= high) 00906 { 00907 var middle = FLOOR(low + (high - low) / 2), 00908 position = middle / 2, 00909 positionFLOOR = FLOOR(position); 00910 00911 if (position === positionFLOOR) 00912 { 00913 if (positionFLOOR - 1 >= 0 && anIndex < CPMaxRange(ranges[positionFLOOR - 1])) 00914 high = middle - 1; 00915 00916 else if (positionFLOOR < count && anIndex >= ranges[positionFLOOR].location) 00917 low = middle + 1; 00918 00919 else 00920 return positionFLOOR - 0.5; 00921 } 00922 else 00923 { 00924 var range = ranges[positionFLOOR]; 00925 00926 if (anIndex < range.location) 00927 high = middle - 1; 00928 00929 else if (anIndex >= CPMaxRange(range)) 00930 low = middle + 1; 00931 00932 else 00933 return positionFLOOR; 00934 } 00935 } 00936 00937 return CPNotFound; 00938 } 00939 00940 /* 00941 new old method 00942 X + (id)indexSet; 00943 X + (id)indexSetWithIndex:(unsigned int)value; 00944 X + (id)indexSetWithIndexesInRange:(NSRange)range; 00945 X X - (id)init; 00946 X X - (id)initWithIndex:(unsigned int)value; 00947 X X - (id)initWithIndexesInRange:(NSRange)range; // designated initializer 00948 X X - (id)initWithIndexSet:(NSIndexSet *)indexSet; // designated initializer 00949 X - (BOOL)isEqualToIndexSet:(NSIndexSet *)indexSet; 00950 X X - (unsigned int)count; 00951 X X - (unsigned int)firstIndex; 00952 X X - (unsigned int)lastIndex; 00953 X X - (unsigned int)indexGreaterThanIndex:(unsigned int)value; 00954 X X - (unsigned int)indexLessThanIndex:(unsigned int)value; 00955 X X - (unsigned int)indexGreaterThanOrEqualToIndex:(unsigned int)value; 00956 X X - (unsigned int)indexLessThanOrEqualToIndex:(unsigned int)value; 00957 X - (unsigned int)getIndexes:(unsigned int *)indexBuffer maxCount:(unsigned int)bufferSize inIndexRange:(NSRangePointer)range; 00958 X X - (BOOL)containsIndex:(unsigned int)value; 00959 X X - (BOOL)containsIndexesInRange:(NSRange)range; 00960 X X - (BOOL)containsIndexes:(NSIndexSet *)indexSet; 00961 X X - (BOOL)intersectsIndexesInRange:(NSRange)range; 00962 X X - (void)addIndexes:(NSIndexSet *)indexSet; 00963 X - (void)removeIndexes:(NSIndexSet *)indexSet; 00964 X X - (void)removeAllIndexes; 00965 X - (void)addIndex:(unsigned int)value; 00966 X - (void)removeIndex:(unsigned int)value; 00967 X - (void)addIndexesInRange:(NSRange)range; 00968 X - (void)removeIndexesInRange:(NSRange)range; 00969 - (void)shiftIndexesStartingAtIndex:(unsigned int)index by:(int)delta; 00970 */