Mercurial > octave-libgccjit
annotate liboctave/Array.h @ 7620:36594d5bbe13
Move diag function into the octave_value class
author | David Bateman <dbateman@free.fr> |
---|---|
date | Fri, 21 Mar 2008 00:08:24 +0100 |
parents | 8c32f95c2639 |
children | ff918ee1a983 |
rev | line source |
---|---|
1993 | 1 // Template array classes |
228 | 2 /* |
3 | |
7017 | 4 Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, |
5 2004, 2005, 2006, 2007 John W. Eaton | |
228 | 6 |
7 This file is part of Octave. | |
8 | |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
228 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
228 | 22 |
23 */ | |
24 | |
382 | 25 #if !defined (octave_Array_h) |
26 #define octave_Array_h 1 | |
27 | |
1366 | 28 #include <cassert> |
4152 | 29 #include <cstddef> |
3613 | 30 |
3933 | 31 #include <iostream> |
32 | |
4513 | 33 #include "dim-vector.h" |
3613 | 34 #include "lo-utils.h" |
7433 | 35 #include "oct-sort.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
36 #include "quit.h" |
7433 | 37 |
1560 | 38 class idx_vector; |
39 | |
1359 | 40 // One dimensional array class. Handles the reference counting for |
41 // all the derived classes. | |
238 | 42 |
228 | 43 template <class T> |
4459 | 44 T |
45 resize_fill_value (const T& x) | |
46 { | |
47 return x; | |
48 } | |
49 | |
50 template <class T> | |
3585 | 51 class |
52 Array | |
228 | 53 { |
3504 | 54 protected: |
1619 | 55 |
4513 | 56 //-------------------------------------------------------------------- |
57 // The real representation of all arrays. | |
58 //-------------------------------------------------------------------- | |
1735 | 59 |
60 class ArrayRep | |
61 { | |
62 public: | |
63 | |
64 T *data; | |
5275 | 65 octave_idx_type len; |
1735 | 66 int count; |
67 | |
5275 | 68 ArrayRep (T *d, octave_idx_type l) : data (d), len (l), count (1) { } |
1735 | 69 |
70 ArrayRep (void) : data (0), len (0), count (1) { } | |
71 | |
5275 | 72 explicit ArrayRep (octave_idx_type n) : data (new T [n]), len (n), count (1) { } |
1735 | 73 |
5275 | 74 explicit ArrayRep (octave_idx_type n, const T& val) |
4513 | 75 : data (new T [n]), len (n), count (1) |
76 { | |
77 fill (val); | |
78 } | |
79 | |
1735 | 80 ArrayRep (const ArrayRep& a) |
81 : data (new T [a.len]), len (a.len), count (1) | |
4513 | 82 { |
5275 | 83 for (octave_idx_type i = 0; i < len; i++) |
4513 | 84 data[i] = a.data[i]; |
85 } | |
4517 | 86 |
1735 | 87 ~ArrayRep (void) { delete [] data; } |
88 | |
5275 | 89 octave_idx_type length (void) const { return len; } |
1735 | 90 |
4513 | 91 void fill (const T& val) |
92 { | |
5275 | 93 for (octave_idx_type i = 0; i < len; i++) |
4513 | 94 data[i] = val; |
95 } | |
96 | |
5275 | 97 T& elem (octave_idx_type n) { return data[n]; } |
1735 | 98 |
5275 | 99 T elem (octave_idx_type n) const { return data[n]; } |
1756 | 100 |
101 void qsort (int (*compare) (const void *, const void *)) | |
102 { | |
3613 | 103 octave_qsort (data, static_cast<size_t> (len), sizeof (T), compare); |
1756 | 104 } |
4517 | 105 |
106 private: | |
107 | |
108 // No assignment! | |
109 | |
110 ArrayRep& operator = (const ArrayRep& a); | |
1735 | 111 }; |
112 | |
4513 | 113 //-------------------------------------------------------------------- |
114 | |
6884 | 115 public: |
116 | |
117 // !!! WARNING !!! -- these should be protected, not public. You | |
118 // should not access these methods directly! | |
119 | |
2006 | 120 void make_unique (void) |
121 { | |
122 if (rep->count > 1) | |
123 { | |
124 --rep->count; | |
125 rep = new ArrayRep (*rep); | |
126 } | |
127 } | |
128 | |
4513 | 129 void make_unique (const T& val) |
130 { | |
131 if (rep->count > 1) | |
132 { | |
133 --rep->count; | |
134 rep = new ArrayRep (rep->length (), val); | |
135 } | |
136 else | |
137 rep->fill (val); | |
138 } | |
238 | 139 |
5900 | 140 typedef T element_type; |
141 | |
4902 | 142 // !!! WARNING !!! -- these should be protected, not public. You |
143 // should not access these data members directly! | |
144 | |
145 typename Array<T>::ArrayRep *rep; | |
4518 | 146 |
4513 | 147 dim_vector dimensions; |
148 | |
4518 | 149 protected: |
150 | |
6881 | 151 mutable idx_vector *idx; |
152 mutable int idx_count; | |
4513 | 153 |
5275 | 154 Array (T *d, octave_idx_type n) |
4513 | 155 : rep (new typename Array<T>::ArrayRep (d, n)), dimensions (n), |
156 idx (0), idx_count (0) { } | |
1619 | 157 |
4587 | 158 Array (T *d, const dim_vector& dv) |
159 : rep (new typename Array<T>::ArrayRep (d, get_size (dv))), | |
160 dimensions (dv), idx (0), idx_count (0) { } | |
4513 | 161 |
162 private: | |
163 | |
4585 | 164 typename Array<T>::ArrayRep *nil_rep (void) const |
4513 | 165 { |
166 static typename Array<T>::ArrayRep *nr | |
167 = new typename Array<T>::ArrayRep (); | |
168 | |
169 return nr; | |
1550 | 170 } |
238 | 171 |
4902 | 172 template <class U> |
173 T * | |
174 coerce (const U *a, int len) | |
175 { | |
176 T *retval = new T [len]; | |
177 | |
178 for (int i = 0; i < len; i++) | |
179 retval[i] = T (a[i]); | |
180 | |
181 return retval; | |
182 } | |
183 | |
228 | 184 public: |
238 | 185 |
1550 | 186 Array (void) |
4513 | 187 : rep (nil_rep ()), dimensions (), |
188 idx (0), idx_count (0) { rep->count++; } | |
1550 | 189 |
5275 | 190 explicit Array (octave_idx_type n) |
4513 | 191 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n), |
192 idx (0), idx_count (0) { } | |
1619 | 193 |
5275 | 194 explicit Array (octave_idx_type n, const T& val) |
4513 | 195 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n), |
196 idx (0), idx_count (0) | |
197 { | |
198 fill (val); | |
199 } | |
200 | |
4902 | 201 // Type conversion case. |
202 template <class U> | |
203 Array (const Array<U>& a) | |
204 : rep (new typename Array<T>::ArrayRep (coerce (a.data (), a.length ()), a.length ())), | |
205 dimensions (a.dimensions), idx (0), idx_count (0) | |
206 { | |
207 } | |
208 | |
209 // No type conversion case. | |
4513 | 210 Array (const Array<T>& a) |
211 : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0) | |
212 { | |
213 rep->count++; | |
1550 | 214 } |
215 | |
4513 | 216 public: |
217 | |
4587 | 218 Array (const dim_vector& dv) |
219 : rep (new typename Array<T>::ArrayRep (get_size (dv))), | |
220 dimensions (dv), idx (0), idx_count (0) { } | |
238 | 221 |
4587 | 222 Array (const dim_vector& dv, const T& val) |
223 : rep (new typename Array<T>::ArrayRep (get_size (dv))), | |
224 dimensions (dv), idx (0), idx_count (0) | |
1550 | 225 { |
4513 | 226 fill (val); |
227 } | |
228 | |
4834 | 229 Array (const Array<T>& a, const dim_vector& dv); |
228 | 230 |
4979 | 231 virtual ~Array (void); |
228 | 232 |
4513 | 233 Array<T>& operator = (const Array<T>& a) |
234 { | |
235 if (this != &a) | |
236 { | |
237 if (--rep->count <= 0) | |
238 delete rep; | |
239 | |
240 rep = a.rep; | |
241 rep->count++; | |
242 | |
243 dimensions = a.dimensions; | |
5632 | 244 |
245 idx_count = 0; | |
246 idx = 0; | |
4513 | 247 } |
248 | |
249 return *this; | |
250 } | |
251 | |
252 void fill (const T& val) { make_unique (val); } | |
238 | 253 |
5275 | 254 octave_idx_type capacity (void) const { return rep->length (); } |
255 octave_idx_type length (void) const { return capacity (); } | |
256 octave_idx_type nelem (void) const { return capacity (); } | |
257 octave_idx_type numel (void) const { return nelem (); } | |
4513 | 258 |
5275 | 259 octave_idx_type dim1 (void) const { return dimensions(0); } |
260 octave_idx_type dim2 (void) const { return dimensions(1); } | |
261 octave_idx_type dim3 (void) const { return dimensions(2); } | |
4513 | 262 |
5275 | 263 octave_idx_type rows (void) const { return dim1 (); } |
264 octave_idx_type cols (void) const { return dim2 (); } | |
265 octave_idx_type columns (void) const { return dim2 (); } | |
266 octave_idx_type pages (void) const { return dim3 (); } | |
4513 | 267 |
4902 | 268 size_t byte_size (void) const { return numel () * sizeof (T); } |
269 | |
4513 | 270 dim_vector dims (void) const { return dimensions; } |
271 | |
4532 | 272 Array<T> squeeze (void) const; |
4703 | 273 |
274 void chop_trailing_singletons (void) | |
275 { dimensions.chop_trailing_singletons (); } | |
276 | |
5275 | 277 static octave_idx_type get_size (octave_idx_type r, octave_idx_type c); |
278 static octave_idx_type get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p); | |
279 static octave_idx_type get_size (const dim_vector& dv); | |
228 | 280 |
5275 | 281 octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx) const; |
4517 | 282 |
5275 | 283 T range_error (const char *fcn, octave_idx_type n) const; |
284 T& range_error (const char *fcn, octave_idx_type n); | |
3665 | 285 |
5275 | 286 T range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const; |
287 T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j); | |
4513 | 288 |
5275 | 289 T range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) const; |
290 T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k); | |
4513 | 291 |
6867 | 292 T range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const; |
293 T& range_error (const char *fcn, const Array<octave_idx_type>& ra_idx); | |
4513 | 294 |
2108 | 295 // No checking, even for multiple references, ever. |
296 | |
5275 | 297 T& xelem (octave_idx_type n) { return rep->elem (n); } |
298 T xelem (octave_idx_type n) const { return rep->elem (n); } | |
2108 | 299 |
5275 | 300 T& xelem (octave_idx_type i, octave_idx_type j) { return xelem (dim1()*j+i); } |
301 T xelem (octave_idx_type i, octave_idx_type j) const { return xelem (dim1()*j+i); } | |
4513 | 302 |
5275 | 303 T& xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return xelem (i, dim2()*k+j); } |
304 T xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return xelem (i, dim2()*k+j); } | |
4513 | 305 |
6867 | 306 T& xelem (const Array<octave_idx_type>& ra_idx) |
4513 | 307 { return xelem (compute_index (ra_idx)); } |
308 | |
6867 | 309 T xelem (const Array<octave_idx_type>& ra_idx) const |
4513 | 310 { return xelem (compute_index (ra_idx)); } |
311 | |
5775 | 312 // FIXME -- would be nice to fix this so that we don't |
2006 | 313 // unnecessarily force a copy, but that is not so easy, and I see no |
314 // clean way to do it. | |
315 | |
5275 | 316 T& checkelem (octave_idx_type n) |
2006 | 317 { |
318 if (n < 0 || n >= rep->length ()) | |
2109 | 319 return range_error ("T& Array<T>::checkelem", n); |
2006 | 320 else |
2108 | 321 { |
322 make_unique (); | |
323 return xelem (n); | |
324 } | |
2006 | 325 } |
326 | |
5275 | 327 T& checkelem (octave_idx_type i, octave_idx_type j) |
4513 | 328 { |
329 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
330 return range_error ("T& Array<T>::checkelem", i, j); | |
331 else | |
332 return elem (dim1()*j+i); | |
333 } | |
334 | |
5275 | 335 T& checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) |
4513 | 336 { |
337 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ()) | |
338 return range_error ("T& Array<T>::checkelem", i, j, k); | |
339 else | |
340 return elem (i, dim2()*k+j); | |
341 } | |
342 | |
6867 | 343 T& checkelem (const Array<octave_idx_type>& ra_idx) |
4513 | 344 { |
5275 | 345 octave_idx_type i = compute_index (ra_idx); |
4513 | 346 |
347 if (i < 0) | |
348 return range_error ("T& Array<T>::checkelem", ra_idx); | |
349 else | |
350 return elem (i); | |
351 } | |
352 | |
5275 | 353 T& elem (octave_idx_type n) |
2108 | 354 { |
355 make_unique (); | |
2109 | 356 return xelem (n); |
2108 | 357 } |
2306 | 358 |
5275 | 359 T& elem (octave_idx_type i, octave_idx_type j) { return elem (dim1()*j+i); } |
4513 | 360 |
5275 | 361 T& elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, dim2()*k+j); } |
4513 | 362 |
6867 | 363 T& elem (const Array<octave_idx_type>& ra_idx) |
4513 | 364 { return Array<T>::elem (compute_index (ra_idx)); } |
365 | |
2306 | 366 #if defined (BOUNDS_CHECKING) |
5275 | 367 T& operator () (octave_idx_type n) { return checkelem (n); } |
368 T& operator () (octave_idx_type i, octave_idx_type j) { return checkelem (i, j); } | |
369 T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return checkelem (i, j, k); } | |
6867 | 370 T& operator () (const Array<octave_idx_type>& ra_idx) { return checkelem (ra_idx); } |
2306 | 371 #else |
5275 | 372 T& operator () (octave_idx_type n) { return elem (n); } |
373 T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); } | |
374 T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, j, k); } | |
6867 | 375 T& operator () (const Array<octave_idx_type>& ra_idx) { return elem (ra_idx); } |
2006 | 376 #endif |
377 | |
5275 | 378 T checkelem (octave_idx_type n) const |
2006 | 379 { |
380 if (n < 0 || n >= rep->length ()) | |
2109 | 381 return range_error ("T Array<T>::checkelem", n); |
2049 | 382 else |
2108 | 383 return xelem (n); |
2006 | 384 } |
1989 | 385 |
5275 | 386 T checkelem (octave_idx_type i, octave_idx_type j) const |
4513 | 387 { |
388 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
389 return range_error ("T Array<T>::checkelem", i, j); | |
390 else | |
391 return elem (dim1()*j+i); | |
392 } | |
393 | |
5275 | 394 T checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const |
4513 | 395 { |
396 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ()) | |
397 return range_error ("T Array<T>::checkelem", i, j, k); | |
398 else | |
399 return Array<T>::elem (i, Array<T>::dim1()*k+j); | |
400 } | |
401 | |
6867 | 402 T checkelem (const Array<octave_idx_type>& ra_idx) const |
4513 | 403 { |
5275 | 404 octave_idx_type i = compute_index (ra_idx); |
4513 | 405 |
406 if (i < 0) | |
407 return range_error ("T Array<T>::checkelem", ra_idx); | |
408 else | |
409 return Array<T>::elem (i); | |
410 } | |
411 | |
5275 | 412 T elem (octave_idx_type n) const { return xelem (n); } |
2306 | 413 |
5275 | 414 T elem (octave_idx_type i, octave_idx_type j) const { return elem (dim1()*j+i); } |
4513 | 415 |
5275 | 416 T elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, dim2()*k+j); } |
4513 | 417 |
6867 | 418 T elem (const Array<octave_idx_type>& ra_idx) const |
4513 | 419 { return Array<T>::elem (compute_index (ra_idx)); } |
420 | |
2108 | 421 #if defined (BOUNDS_CHECKING) |
5275 | 422 T operator () (octave_idx_type n) const { return checkelem (n); } |
423 T operator () (octave_idx_type i, octave_idx_type j) const { return checkelem (i, j); } | |
424 T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return checkelem (i, j, k); } | |
6867 | 425 T operator () (const Array<octave_idx_type>& ra_idx) const { return checkelem (ra_idx); } |
2006 | 426 #else |
5275 | 427 T operator () (octave_idx_type n) const { return elem (n); } |
428 T operator () (octave_idx_type i, octave_idx_type j) const { return elem (i, j); } | |
429 T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, j, k); } | |
6867 | 430 T operator () (const Array<octave_idx_type>& ra_idx) const { return elem (ra_idx); } |
2006 | 431 #endif |
432 | |
4567 | 433 Array<T> reshape (const dim_vector& new_dims) const; |
434 | |
5275 | 435 Array<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const; |
436 Array<T> ipermute (const Array<octave_idx_type>& vec) const | |
4593 | 437 { return permute (vec, true); } |
438 | |
5275 | 439 void resize_no_fill (octave_idx_type n); |
440 void resize_and_fill (octave_idx_type n, const T& val); | |
4548 | 441 |
4518 | 442 // !!! WARNING !!! -- the following resize_no_fill and |
443 // resize_and_fill functions are public because template friends | |
444 // don't work properly with versions of gcc earlier than 3.3. You | |
445 // should use these functions only in classes that are derived | |
446 // from Array<T>. | |
447 | |
448 // protected: | |
4513 | 449 |
5275 | 450 void resize_no_fill (octave_idx_type r, octave_idx_type c); |
451 void resize_and_fill (octave_idx_type r, octave_idx_type c, const T& val); | |
4513 | 452 |
5275 | 453 void resize_no_fill (octave_idx_type r, octave_idx_type c, octave_idx_type p); |
454 void resize_and_fill (octave_idx_type r, octave_idx_type c, octave_idx_type p, const T& val); | |
4513 | 455 |
4587 | 456 void resize_no_fill (const dim_vector& dv); |
457 void resize_and_fill (const dim_vector& dv, const T& val); | |
4513 | 458 |
459 public: | |
460 | |
5392 | 461 void resize (octave_idx_type n) { resize_no_fill (n); } |
4513 | 462 |
5392 | 463 void resize (octave_idx_type n, const T& val) { resize_and_fill (n, val); } |
4513 | 464 |
4587 | 465 void resize (const dim_vector& dv) { resize_no_fill (dv); } |
4513 | 466 |
4587 | 467 void resize (const dim_vector& dv, const T& val) |
468 { resize_and_fill (dv, val); } | |
4513 | 469 |
5275 | 470 Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c); |
471 Array<T>& insert2 (const Array<T>& a, octave_idx_type r, octave_idx_type c); | |
472 Array<T>& insertN (const Array<T>& a, octave_idx_type r, octave_idx_type c); | |
4513 | 473 |
5275 | 474 Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx); |
4513 | 475 |
476 bool is_square (void) const { return (dim1 () == dim2 ()); } | |
477 | |
4559 | 478 bool is_empty (void) const { return numel () == 0; } |
479 | |
4513 | 480 Array<T> transpose (void) const; |
238 | 481 |
1550 | 482 const T *data (void) const { return rep->data; } |
228 | 483 |
3952 | 484 const T *fortran_vec (void) const { return data (); } |
485 | |
238 | 486 T *fortran_vec (void); |
1560 | 487 |
1781 | 488 Array<T>& qsort (int (*compare) (const void *, const void *)) |
1756 | 489 { |
2347 | 490 make_unique (); |
1756 | 491 |
492 rep->qsort (compare); | |
1781 | 493 |
494 return *this; | |
1756 | 495 } |
496 | |
4513 | 497 int ndims (void) const { return dimensions.length (); } |
1560 | 498 |
4517 | 499 void maybe_delete_dims (void); |
500 | |
6881 | 501 void clear_index (void) const; |
1560 | 502 |
6881 | 503 void set_index (const idx_vector& i) const; |
1560 | 504 |
1619 | 505 int index_count (void) const { return idx_count; } |
1560 | 506 |
1619 | 507 idx_vector *get_idx (void) const { return idx; } |
1560 | 508 |
509 void maybe_delete_elements (idx_vector& i); | |
510 | |
4513 | 511 void maybe_delete_elements_1 (idx_vector& i); |
512 | |
513 void maybe_delete_elements_2 (idx_vector& i); | |
514 | |
515 void maybe_delete_elements (idx_vector& i, idx_vector& j); | |
516 | |
517 void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k); | |
518 | |
519 void maybe_delete_elements (Array<idx_vector>& ra_idx, const T& rfv); | |
520 | |
6881 | 521 Array<T> value (void) const; |
2382 | 522 |
3933 | 523 Array<T> index (idx_vector& i, int resize_ok = 0, |
4459 | 524 const T& rfv = resize_fill_value (T ())) const; |
3933 | 525 |
4513 | 526 Array<T> index1 (idx_vector& i, int resize_ok = 0, |
527 const T& rfv = resize_fill_value (T ())) const; | |
528 | |
529 Array<T> index2 (idx_vector& i, int resize_ok = 0, | |
530 const T& rfv = resize_fill_value (T ())) const; | |
531 | |
4530 | 532 Array<T> indexN (idx_vector& i, int resize_ok = 0, |
533 const T& rfv = resize_fill_value (T ())) const; | |
534 | |
4513 | 535 Array<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0, |
536 const T& rfv = resize_fill_value (T ())) const; | |
537 | |
538 Array<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0, | |
539 const T& rfv = resize_fill_value (T ())) const; | |
3928 | 540 |
4459 | 541 // static T resize_fill_value (void) { return T (); } |
3933 | 542 |
4517 | 543 void print_info (std::ostream& os, const std::string& prefix) const; |
5900 | 544 |
545 // Unsafe. This function exists to support the MEX interface. | |
546 // You should not use it anywhere else. | |
547 void *mex_get_data (void) const { return const_cast<T *> (data ()); } | |
7433 | 548 |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
549 Array<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const; |
7433 | 550 Array<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0, |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
551 sortmode mode = ASCENDING) const; |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
552 |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
553 Array<T> diag (octave_idx_type k = 0) const; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
554 |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
555 template <class U, class F> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
556 Array<U> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
557 map (F fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
558 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
559 octave_idx_type len = length (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
560 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
561 const T *m = data (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
562 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
563 Array<U> result (dims ()); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
564 U *p = result.fortran_vec (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
565 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
566 for (octave_idx_type i = 0; i < len; i++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
567 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
568 OCTAVE_QUIT; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
569 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
570 p[i] = fcn (m[i]); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
571 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
572 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
573 return result; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
574 } |
4513 | 575 }; |
4459 | 576 |
4518 | 577 // NOTE: these functions should be friends of the Array<T> class and |
578 // Array<T>::dimensions should be protected, not public, but we can't | |
579 // do that because of bugs in gcc prior to 3.3. | |
580 | |
581 template <class LT, class RT> | |
582 /* friend */ int | |
583 assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
584 | |
585 template <class LT, class RT> | |
586 /* friend */ int | |
587 assign1 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
588 | |
589 template <class LT, class RT> | |
590 /* friend */ int | |
591 assign2 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
592 | |
593 template <class LT, class RT> | |
594 /* friend */ int | |
595 assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
596 | |
3836 | 597 template <class LT, class RT> |
598 int | |
599 assign (Array<LT>& lhs, const Array<RT>& rhs) | |
600 { | |
4459 | 601 return assign (lhs, rhs, resize_fill_value (LT ())); |
3836 | 602 } |
1560 | 603 |
6708 | 604 #define INSTANTIATE_ARRAY_ASSIGN(LT, RT, API) \ |
605 template API int assign (Array<LT>&, const Array<RT>&, const LT&); \ | |
606 template API int assign1 (Array<LT>&, const Array<RT>&, const LT&); \ | |
607 template API int assign2 (Array<LT>&, const Array<RT>&, const LT&); \ | |
608 template API int assignN (Array<LT>&, const Array<RT>&, const LT&); \ | |
609 template API int assign (Array<LT>&, const Array<RT>&) | |
4594 | 610 |
4762 | 611 |
6708 | 612 #define INSTANTIATE_ARRAY(T, API) \ |
613 template class API Array<T>; \ | |
614 template API T resize_fill_value (const T&); \ | |
4762 | 615 |
6708 | 616 #define INSTANTIATE_ARRAY_AND_ASSIGN(T, API) \ |
617 INSTANTIATE_ARRAY (T, API); \ | |
618 INSTANTIATE_ARRAY_ASSIGN (T, T, API) | |
4594 | 619 |
7433 | 620 #define INSTANTIATE_ARRAY_SORT(T) \ |
621 template class octave_sort<T>; \ | |
622 template class vec_index<T>; \ | |
623 template class octave_sort<vec_index<T> *>; | |
624 | |
625 #define NO_INSTANTIATE_ARRAY_SORT(T) \ | |
626 template class vec_index<T>; \ | |
627 template <> bool ascending_compare (T, T) { return true; } \ | |
628 template <> bool ascending_compare (vec_index<T> *, vec_index<T> *) \ | |
629 { return true; } \ | |
630 template <> bool descending_compare (T, T) { return true; } \ | |
631 template <> bool descending_compare (vec_index<T> *, vec_index<T> *) \ | |
632 { return true; } \ | |
633 template <> Array<T> Array<T>::sort \ | |
634 (octave_idx_type, sortmode) const { return *this; } \ | |
635 template <> Array<T> Array<T>::sort (Array<octave_idx_type> &sidx, \ | |
636 octave_idx_type, sortmode) const \ | |
637 { sidx = Array<octave_idx_type> (); return *this; } | |
638 | |
228 | 639 #endif |
640 | |
641 /* | |
642 ;;; Local Variables: *** | |
643 ;;; mode: C++ *** | |
644 ;;; End: *** | |
645 */ |