comparison liboctave/Array.cc @ 10645:8645b7087859

abstract scalar index checking off Array<T> (prep for struct optimizations)
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 20 May 2010 15:10:34 +0200
parents c170eb1c067f
children b17a966099ed
comparison
equal deleted inserted replaced
10644:45b72e631cb5 10645:8645b7087859
185 return retval; 185 return retval;
186 } 186 }
187 187
188 template <class T> 188 template <class T>
189 octave_idx_type 189 octave_idx_type
190 Array<T>::compute_index (octave_idx_type i, octave_idx_type j) const
191 {
192 return ::compute_index (i, j, dimensions);
193 }
194
195 template <class T>
196 octave_idx_type
197 Array<T>::compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k) const
198 {
199 return ::compute_index (i, j, k, dimensions);
200 }
201
202 template <class T>
203 octave_idx_type
190 Array<T>::compute_index (const Array<octave_idx_type>& ra_idx) const 204 Array<T>::compute_index (const Array<octave_idx_type>& ra_idx) const
191 { 205 {
192 octave_idx_type retval = 0; 206 return ::compute_index (ra_idx, dimensions);
193
194 int n = dimensions.length (), ni = ra_idx.length ();
195
196 while (ni > n)
197 retval += ra_idx(--ni);
198
199 while (ni > 0)
200 {
201 retval *= dimensions(--ni);
202 retval += ra_idx(ni);
203 }
204
205 return retval;
206 } 207 }
207 208
208 template <class T> 209 template <class T>
209 T& 210 T&
210 Array<T>::checkelem (octave_idx_type n) 211 Array<T>::checkelem (octave_idx_type n)
211 { 212 {
213 // Do checks directly to avoid recomputing slice_len.
212 if (n < 0) 214 if (n < 0)
213 gripe_invalid_index (); 215 gripe_invalid_index ();
214 if (n >= slice_len) 216 if (n >= slice_len)
215 gripe_index_out_of_range (1, 1, n+1, slice_len); 217 gripe_index_out_of_range (1, 1, n+1, slice_len);
216 218
219 221
220 template <class T> 222 template <class T>
221 T& 223 T&
222 Array<T>::checkelem (octave_idx_type i, octave_idx_type j) 224 Array<T>::checkelem (octave_idx_type i, octave_idx_type j)
223 { 225 {
224 if (i < 0 || j < 0) 226 return elem (compute_index (i, j));
225 gripe_invalid_index ();
226 if (i >= dim1 ())
227 gripe_index_out_of_range (2, 1, i+1, dim1 ());
228 if (j >= dimensions.numel (1))
229 gripe_index_out_of_range (2, 2, j+1, dimensions.numel (1));
230
231 return elem (i, j);
232 } 227 }
233 228
234 template <class T> 229 template <class T>
235 T& 230 T&
236 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) 231 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k)
237 { 232 {
238 if (i < 0 || j < 0 || k < 0) 233 return elem (compute_index (i, j, k));
239 gripe_invalid_index ();
240 if (i >= dim1 ())
241 gripe_index_out_of_range (3, 1, i+1, dim1 ());
242 if (j >= dim2 ())
243 gripe_index_out_of_range (3, 2, j+1, dim2 ());
244 if (k >= dimensions.numel (2))
245 gripe_index_out_of_range (3, 3, k+1, dimensions.numel (2));
246
247 return elem (i, j, k);
248 } 234 }
249 235
250 template <class T> 236 template <class T>
251 T& 237 T&
252 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx) 238 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx)
253 { 239 {
254 int nd = ra_idx.length (); 240 return elem (compute_index (ra_idx));
255 const dim_vector dv = dimensions.redim (nd);
256 for (int d = 0; d < nd; d++)
257 {
258 if (ra_idx(d) < 0)
259 gripe_invalid_index ();
260 if (ra_idx(d) >= dv(d))
261 gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d));
262 }
263
264 return elem (ra_idx);
265 } 241 }
266 242
267 template <class T> 243 template <class T>
268 typename Array<T>::crefT 244 typename Array<T>::crefT
269 Array<T>::checkelem (octave_idx_type n) const 245 Array<T>::checkelem (octave_idx_type n) const
270 { 246 {
247 // Do checks directly to avoid recomputing slice_len.
271 if (n < 0) 248 if (n < 0)
272 gripe_invalid_index (); 249 gripe_invalid_index ();
273 if (n >= slice_len) 250 if (n >= slice_len)
274 gripe_index_out_of_range (1, 1, n+1, slice_len); 251 gripe_index_out_of_range (1, 1, n+1, slice_len);
275 252
278 255
279 template <class T> 256 template <class T>
280 typename Array<T>::crefT 257 typename Array<T>::crefT
281 Array<T>::checkelem (octave_idx_type i, octave_idx_type j) const 258 Array<T>::checkelem (octave_idx_type i, octave_idx_type j) const
282 { 259 {
283 if (i < 0 || j < 0) 260 return elem (compute_index (i, j));
284 gripe_invalid_index ();
285 if (i >= dim1 ())
286 gripe_index_out_of_range (2, 1, i+1, dim1 ());
287 if (j >= dimensions.numel (1))
288 gripe_index_out_of_range (2, 2, j+1, dimensions.numel (1));
289
290 return elem (i, j);
291 } 261 }
292 262
293 template <class T> 263 template <class T>
294 typename Array<T>::crefT 264 typename Array<T>::crefT
295 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const 265 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const
296 { 266 {
297 if (i < 0 || j < 0 || k < 0) 267 return elem (compute_index (i, j, k));
298 gripe_invalid_index ();
299 if (i >= dim1 ())
300 gripe_index_out_of_range (3, 1, i+1, dim1 ());
301 if (j >= dim2 ())
302 gripe_index_out_of_range (3, 2, j+1, dim2 ());
303 if (k >= dimensions.numel (2))
304 gripe_index_out_of_range (3, 3, k+1, dimensions.numel (2));
305
306 return elem (i, j, k);
307 } 268 }
308 269
309 template <class T> 270 template <class T>
310 typename Array<T>::crefT 271 typename Array<T>::crefT
311 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx) const 272 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx) const
312 { 273 {
313 int nd = ra_idx.length (); 274 return elem (compute_index (ra_idx));
314 const dim_vector dv = dimensions.redim (nd);
315 for (int d = 0; d < nd; d++)
316 {
317 if (ra_idx(d) < 0)
318 gripe_invalid_index ();
319 if (ra_idx(d) >= dv(d))
320 gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d));
321 }
322
323 return elem (ra_idx);
324 } 275 }
325 276
326 template <class T> 277 template <class T>
327 Array<T> 278 Array<T>
328 Array<T>::column (octave_idx_type k) const 279 Array<T>::column (octave_idx_type k) const