1 //
2 //  KTMatrix
3 //  KTMatrix collection class cluster
4 //
5 //  Stores a matrix of objects
6 //  Class cluster
7 //
8 //  It works like this:
9 //    - A set of keys is used to denote the matrix axes
10 //    - A dictionary is used to access individual elements
11 //    - (A hash is used to transform this dictionary into a key)
12 //    - The axis values should be NSNumbers
13 //  This differs from a dictionary with dictionary keys only in that
14 //    the hash does not depend on the key type
15 //  Also, if two locations hash the same, they are treated as identical
16 //
17 //  Copyright (c) 2002 Chris Purcell. All rights reserved.
18 //
19 //  You may use this code for whatever purposes you wish.
20 //  This code comes with no warranties, implied or otherwise.
21 //  Using it may damage your data. It shouldn't, but save a copy first.
22 //  That's a good idea anyway, actually.
23 //
24 
25 #import <Foundation/Foundation.h>
26 
27 // Any hash used by a KTMatrix object must conform to this protocol
28 @protocol KTLocationHash <NSObject, NSCopying>
29 // Return the hashed location for the information given in the two dictionaries
30 // This is the most flexible - and hence slowest - form of location storage
31 // All methods use this if no efficiency protocol are implemented
32 - (unsigned)hashForLocation:(NSDictionary *)loc1
33                  byLocation:(NSDictionary *)loc2;
34     // Return the axes used by the hashing object
35     // Used to translate coordinates into locations
36     // If coordinates are not used, this need not be meaningfully implemented
37 - (NSArray *)axes;
38     // Return the lower bound for a given oxis
39     // Need not be meaningfully implemented
40 - (unsigned)lowerBoundForAxis:(id)axis;
41     // Return the lower bound for a given oxis
42     // Need not be meaningfully implemented
43 - (unsigned)upperBoundForAxis:(id)axis;
44     // Return a bound on the largest hash value that can be returned
45     // Used to select optimal implementations of the matrix
46     // Return 0 if any unsigned hash value could be returned
47     // (This disables dense implementations of the matrix)
48 - (unsigned)hashBound;
49 @end
50 
51 @protocol KTLocationHashInverse
52 - (id)locationForHash:(unsigned)hash;
53 @end
54 
55 // Conforming your hash to this can speed up coordinate-based methods manyfold
56 @protocol KTLocationHashCoordinatesOptimization
57 // Take a va_list object and extract the required coordinates from it
58 - (unsigned)hashForCoordinatesList:(va_list *)coords;
59     // As before, except the first value is supplied in x
60 - (unsigned)hashForCoordinatesList:(unsigned)x :(va_list *)coords;
61     // Return [[self axes] count], or equivalent implementation
62 - (unsigned)dimension;
63     // Return [self lowerBoundForAxis:[NSNumber numberWithInt:dim]]
64     // Or equivalent implementation
65 - (unsigned)lowerBoundForDimension:(unsigned)dim;
66     // Return [self upperBoundForAxis:[NSNumber numberWithInt:dim]]
67     // Or equivalent implementation
68 - (unsigned)upperBoundForDimension:(unsigned)dim;
69 @end
70 
71 @protocol KTMatrixEnumerator
72 - (unsigned)hashedLocation;
73 @end
74 
75 @interface KTMatrix
76 : NSObject <NSCoding,NSCopying,NSMutableCopying> { }
77 
78 // Constructors
79 + (id)matrix;
80 + (id)matrixWithMatrix:(KTMatrix *)matrix; // Primitive
81 
82 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash; // Primitive
83 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
84                       object:(id)object
85                   atLocation:(NSDictionary *)loc;
86 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
87                       object:(id)object
88                   atLocation:(NSDictionary *)loc1
89                   byLocation:(NSDictionary *)loc2;
90 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
91                      objects:(NSArray *)objects
92                  atLocations:(NSArray *)locs;
93 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
94                      objects:(NSArray *)objects
95                  atLocations:(NSArray *)loc1s
96                   byLocation:(NSDictionary *)loc2;
97 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash // Primitive
98                      objects:(NSArray *)objects
99                  atLocations:(NSArray *)loc1s
100                  byLocations:(NSArray *)loc2s;
101 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
102           objectsAtLocations:(id)object1,...;
103 + (id)       matrixWithLocationHash:(id<KTLocationHash>)hash
104       objectsAtLocationsByLocations:(id)object1,...;
105 
106 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
107                       object:(id)object
108            atCoordinateArray:(NSArray *)coord;
109 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
110                       object:(id)object
111                atCoordinates:(unsigned)x,...;
112 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
113                      objects:(NSArray *)objects
114           atCoordinateArrays:(NSArray *)coords;
115 + (id)matrixWithLocationHash:(id<KTLocationHash>)hash
116         objectsAtCoordinates:(id)object1,...;
117 
118 + (id)matrixWithCuboidBoundArray:(NSArray *)bounds;
119 + (id)matrixWithCuboidBoundArray:(NSArray *)bounds
120                           object:(id)object
121                atCoordinateArray:(NSArray *)coord;
122 + (id)matrixWithCuboidBoundArray:(NSArray *)bounds
123                           object:(id)object
124                    atCoordinates:(unsigned)x,...;
125 + (id)matrixWithCuboidBoundArray:(NSArray *)bounds
126                          objects:(NSArray *)objects
127               atCoordinateArrays:(NSArray *)coords;
128 + (id)matrixWithCuboidBoundArray:(NSArray *)bounds
129             objectsAtCoordinates:(id)object1,...;
130 + (id)matrixWithCuboidBounds:(unsigned)bound1,...;
131 + (id)matrixWithCuboidBoundsObjectAtCoordinates:(unsigned)bound1,...;
132 + (id)matrixWithCuboidBoundsObjectsAtCoordinateArrays:(unsigned)bound1,...;
133 + (id)matrixWithCuboidBoundsObjectsAtCoordinates:(unsigned)bound1,...;
134 
135 - (id)init;
136 - (id)initWithMatrix:(KTMatrix *)matrix;  // Primitive
137 
138 - (id)initWithLocationHash:(id<KTLocationHash>)hash;
139 - (id)initWithLocationHash:(id<KTLocationHash>)hash
140                     object:(id)object
141                 atLocation:(NSDictionary *)loc;
142 - (id)initWithLocationHash:(id<KTLocationHash>)hash
143                      object:(id)object
144                 atLocation:(NSDictionary *)loc1
145                 byLocation:(NSDictionary *)loc2;
146 - (id)initWithLocationHash:(id<KTLocationHash>)hash
147                    objects:(NSArray *)objects
148                atLocations:(NSArray *)locs;
149 - (id)initWithLocationHash:(id<KTLocationHash>)hash
150                    objects:(NSArray *)objects
151                atLocations:(NSArray *)loc1s
152                 byLocation:(NSDictionary *)loc2;
153 - (id)initWithLocationHash:(id<KTLocationHash>)hash
154                    objects:(NSArray *)objects
155                atLocations:(NSArray *)loc1s
156                byLocations:(NSArray *)loc2s;
157 - (id)initWithLocationHash:(id<KTLocationHash>)hash
158         objectsAtLocations:(id)object1,...;
159 - (id)         initWithLocationHash:(id<KTLocationHash>)hash
160       objectsAtLocationsByLocations:(id)object1,...;
161 
162 - (id)initWithLocationHash:(id<KTLocationHash>)hash
163                     object:(id)object
164          atCoordinateArray:(NSArray *)coord;
165 - (id)initWithLocationHash:(id<KTLocationHash>)hash
166                     object:(id)object
167              atCoordinates:(unsigned)x,...;
168 - (id)initWithLocationHash:(id<KTLocationHash>)hash
169                    objects:(NSArray *)objects
170         atCoordinateArrays:(NSArray *)coords;
171 - (id)initWithLocationHash:(id<KTLocationHash>)hash
172       objectsAtCoordinates:(id)object1,...;
173 
174 - (id)initWithCuboidBoundArray:(NSArray *)bounds;
175 - (id)initWithCuboidBoundArray:(NSArray *)bounds
176                         object:(id)object
177              atCoordinateArray:(NSArray *)coord;
178 - (id)initWithCuboidBoundArray:(NSArray *)bounds
179                         object:(id)object
180                  atCoordinates:(unsigned)x,...;
181 - (id)initWithCuboidBoundArray:(NSArray *)bounds
182                        objects:(NSArray *)objects
183             atCoordinateArrays:(NSArray *)coords;
184 - (id)initWithCuboidBoundArray:(NSArray *)bounds
185           objectsAtCoordinates:(id)object1,...;
186 - (id)initWithCuboidBounds:(unsigned)bound1,...;
187 - (id)initWithCuboidBoundsObjectAtCoordinates:(unsigned)bound1,...;
188 - (id)initWithCuboidBoundsObjectsAtCoordinateArrays:(unsigned)bound1,...;
189 - (id)initWithCuboidBoundsObjectsAtCoordinates:(unsigned)bound1,...;
190 
191     // Accessor methods
192 - (id)objectAtLocation:(NSDictionary *)loc;
193 - (id)objectAtLocation:(NSDictionary *)loc1
194             byLocation:(NSDictionary *)loc2; // Primitive
195 - (NSArray *)objectsAtLocations:(NSArray *)locs
196                  notFoundMarker:(id)anObject;
197 - (NSArray *)objectsAtLocations:(NSArray *)loc1s
198                      byLocation:(NSDictionary *)loc2
199                  notFoundMarker:(id)anObject;
200 - (NSArray *)objectsAtLocations:(NSArray *)loc1s
201                     byLocations:(NSArray *)loc2s
202                  notFoundMarker:(id)anObject;
203 - (id)objectAtCoordinateArray:(NSArray *)coords;
204 - (NSArray *)objectsAtCoordinateArrays:(NSArray *)coords
205                         notFoundMarker:(id)anObject;
206 - (id)objectAtCoordinates:(unsigned)x,...;
207 
208 - (id<KTLocationHash>)locationHash; // Primitive
209 
210     // Internal use accessors
211 - (NSDictionary *)matrixData; // Primitive
212 
213     // Convenience methods fall straight through to hash equivalents
214 - (NSArray *)axes;
215 - (unsigned)dimension;
216 - (unsigned)lowerBoundForAxis:(id)axis;
217 - (unsigned)lowerBoundForDimension:(unsigned)dimension;
218 - (unsigned)upperBoundForAxis:(id)axis;
219 - (unsigned)upperBoundForDimension:(unsigned)dimension;
220 
221     // Object methods
222 - (NSArray *)allObjects;
223 - (unsigned)count; // Primitive
224 - (NSEnumerator *)objectEnumerator; // Primitive
225 - (NSEnumerator *)objectEnumeratorRetained;
226 - (NSEnumerator *)reverseObjectEnumerator;
227 
228 @end
229