// // MPRangePath.h // MathKit // // Created by Kim Wittenburg on 18.04.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPExpression.h" /*! @header This file contains the MPRangePath class. The MPRangePath combines an NSIndexPath with a NSRange. A range path is used in a tree structure to identify a number of subsequent nodes. This is achieved by combining a range path that stores the location of the first node in the tree with an integer that stores the number of nodes that should be included in the range path. */ /*! @define MPMakeRangePath @abstract Creates a new NSRangePath instance with the given location and length. @param loc The location of the first included item. This must be an NSIndexPath instance. @param len The number of nodes to include in the range path. @return A new range path. */ #define MPMakeRangePath(loc, len) [MPRangePath rangePathWithLocation:(loc) length:(len)] @class MPRangePath, MPExpression; /*! @class MPRangePath @abstract A MPRangePath instance identifies a range of subsequent nodes in a tree structure. @discussion MPRangePath instances are immutable. */ @interface MPRangePath : NSObject #pragma mark Creation Methods /*! @methodgroup Creation Methods */ /*! @method init @abstract Initializes an empty range path. @discussion This method is a convenience initializer to create a range path with an empty location and a length of 0. @return A new MPRangePath instance. */ - (instancetype)init; /*! @method initWithRange: @abstract Initializes a newly created range path with the specified range. @discussion This method is a convenience initializer to convert from a NSRange struct to a MPRangePath instance. The location of the created range path is an index path of length 1. @param aRange The range to be converted into a MPRangePath. @return A MPRangePath instance. */ - (instancetype)initWithRange:(NSRange)aRange; /*! @method initWithLocation:lenght: @abstract Initializes a newly created range path with the specified location and length. @discussion The last index in the location addresses the first item that is actually selected. @param location The location of the first element that should be addressed by this range path. @param length The number of elements to be addressed by this range path. @return A MPRangePath instance. */ - (instancetype)initWithLocation:(NSIndexPath *)location length:(NSUInteger)length; /* designated initializer */ /*! @method rangePath @abstract Allocates and initializes an empty NSRangePath instance. @discussion An empty range path's location has 0 indexes and a length of 0. @return A newly created MPRangePath instance. */ + (instancetype)rangePath; /*! @method rangePathWithRange: @abstract Allocates a new MPRangePath instance and initializes it with the specified location and length. @discussion The location of aRange is translated into an index path for the range path. @param aRange The range to be converted into a range path. @return A newly created MPRangePath instance. */ + (instancetype)rangePathWithRange:(NSRange)aRange; /*! @method rangePathWithLocation:length: @abstract Allocates a new MPRangePath instance and initializes it with the specified location and length. @param location The location of the first element that should be addressed by the range path. @param length The number of elements that should be addressed by the range path. @return A newly created MPRangePath instance. */ + (instancetype)rangePathWithLocation:(NSIndexPath *)location length:(NSUInteger)length; #pragma mark Properties /*! @methodgroup Properties */ /*! @property location @abstract The location of the first element addressed by the receiver. */ @property (readonly, nonatomic, strong) NSIndexPath *location; /*! @property length @abstract The number of elements addressed by the receiver. The element addressed by the last index of the location property plus the length of the receiver is not considered inside of the range path. */ @property (readonly, nonatomic) NSUInteger length; /*! @method maxRangePath @abstract Similar to the NSRange function NSMaxRange this method returns the first index after the receiving NSRangePath. @return The first index after the receiving NSRangePath. */ - (NSIndexPath *)maxRangePath; /*! @method rangeAtLastIndex @abstract Returns a NSRange constructed from the last index of the receiver's location and the receiver's length. @return The range identifying the elements at the last index in the receiver's index path. */ - (NSRange)rangeAtLastIndex; #pragma mark Working With Ranges /*! @methodgroup Working With Ranges */ /*! @method containsLocation: @abstract Checks wether the range path addressed by the receiver includes location. @discussion The index path is considered inside the receiver if the indexes in the receiver's location property are equal to the respective indexes index in location. For the last position of the last index of the receiver's location it is also valid if the respective index is inside the range at the last index. @param location The index path to check wether it is contained in the receiver. @return YES if the range path addressed by the receiver also contains location, NO otherwise. */ - (BOOL)containsLocation:(NSIndexPath *)location; /*! @method containsRangePath: @abstract Checks wether the receiver completely contains aRangePath. @discussion A range path is contained by another range path if either the receiver's range at its last index contains the index at the respective location of the location path of aRangePath or (if the locations are of the same length) the receiver's range at its last index contains the last index's range of aRangePath. @param aRangePath The range path to check wether it is contained in the receiver. @return YES if the range path addressed by the receiver also includes aRangePath, NO otherwise. */ - (BOOL)containsRangePath:(MPRangePath *)aRangePath; /*! @method isEqualToRangePath: @abstract Checks wether the receiver and aRangePath are equal. @discussion If you know that you are comparing two range paths (that are not nil) you should prefer this method over isEqual: because it is more performant. @param aRangePath The range path to check for equality. If this parameter is nil this method may raise an exception. @return YES if the receiver is equal to aRangePath, NO otherwise. */ - (BOOL)isEqualToRangePath:(MPRangePath *)aRangePath; @end @interface MPExpression (MPRangeExtension) /*! @method subexpressionWithRangePath: @abstract Creates a new expression with the symbols in the specified range path. @discussion The elements in the newly created expression are copied to the new exoression. The range path is specified in the length reference frame. If the specified range exceeds the receiver's bounds a NSRangeException is raised. @param aRangePath The range path from which to create the new expression. @return A new expression. */ - (MPExpression *)subexpressionWithRangePath:(MPRangePath *)aRangePath referenceFrame:(MPReferenceFrame)referenceFrame; /*! @method replaceItemsInRangePath:referenceFrame:withElements: @abstract Replaces the items in the specified range path with the contents of elements. @discussion All objects in the elements array must conform to the @link //apple_ref/occ/intf/MPExpressionElement@/link protocol. If one or more objects do not conform to the protocol a @link //apple_ref/c/data/MPIllegalElementException@/link is raised. @param rangePath The range path to be replaced. The location of the range path (except for the last index) is expressed in the element reference frame. The range of the range path is expressed in the specified referenceFrame. @param referenceFrame The reference frame to use. This only applies to the range at the last index of the range path. The path of the range path is always expressed in the element reference frame. @param elements The elements replacing the ones in the specified range path. */ - (void)replaceItemsInRangePath:(MPRangePath *)rangePath referenceFrame:(MPReferenceFrame)referenceFrame withElements:(NSArray *)elements; @end