00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if !defined (octave_idx_vector_h)
00026 #define octave_idx_vector_h 1
00027
00028 #include <cassert>
00029
00030 #include <algorithm>
00031 #include <iosfwd>
00032
00033 #include "dim-vector.h"
00034 #include "oct-inttypes.h"
00035 #include "oct-alloc.h"
00036 #include "oct-mem.h"
00037 #include "oct-refcount.h"
00038
00039 template<class T> class Array;
00040 template<class T> class Sparse;
00041 class Range;
00042
00043
00044
00045
00046
00047
00048
00049
00050 class
00051 OCTAVE_API
00052 idx_vector
00053 {
00054 public:
00055
00056 enum idx_class_type
00057 {
00058 class_invalid = -1,
00059 class_colon = 0,
00060 class_range,
00061 class_scalar,
00062 class_vector,
00063 class_mask
00064 };
00065
00066 private:
00067
00068 class OCTAVE_API idx_base_rep
00069 {
00070 public:
00071 idx_base_rep (void) : count (1), err (false) { }
00072
00073 virtual ~idx_base_rep (void) { }
00074
00075
00076 virtual octave_idx_type xelem (octave_idx_type i) const = 0;
00077
00078
00079 virtual octave_idx_type checkelem (octave_idx_type i) const = 0;
00080
00081
00082 virtual octave_idx_type length (octave_idx_type n) const = 0;
00083
00084
00085 virtual octave_idx_type extent (octave_idx_type n) const = 0;
00086
00087
00088 virtual idx_class_type idx_class (void) const { return class_invalid; }
00089
00090
00091 virtual idx_base_rep *sort_uniq_clone (bool uniq = false) = 0;
00092
00093 virtual idx_base_rep *sort_idx (Array<octave_idx_type>&) = 0;
00094
00095
00096 virtual bool is_colon_equiv (octave_idx_type) const { return false; }
00097
00098
00099 virtual dim_vector orig_dimensions (void) const { return dim_vector (); }
00100
00101
00102 virtual std::ostream& print (std::ostream& os) const = 0;
00103
00104 virtual Array<octave_idx_type> as_array (void);
00105
00106 octave_refcount<int> count;
00107
00108 bool err;
00109
00110 private:
00111
00112
00113 idx_base_rep (const idx_base_rep&);
00114 idx_base_rep& operator = (const idx_base_rep&);
00115 };
00116
00117
00118 class OCTAVE_API idx_colon_rep : public idx_base_rep
00119 {
00120 public:
00121 idx_colon_rep (void) { }
00122
00123 idx_colon_rep (char c);
00124
00125 octave_idx_type xelem (octave_idx_type i) const { return i; }
00126
00127 octave_idx_type checkelem (octave_idx_type i) const;
00128
00129 octave_idx_type length (octave_idx_type n) const { return n; }
00130
00131 octave_idx_type extent (octave_idx_type n) const { return n; }
00132
00133 idx_class_type idx_class (void) const { return class_colon; }
00134
00135 idx_base_rep *sort_uniq_clone (bool = false)
00136 { count++; return this; }
00137
00138 idx_base_rep *sort_idx (Array<octave_idx_type>&);
00139
00140 bool is_colon_equiv (octave_idx_type) const { return true; }
00141
00142 std::ostream& print (std::ostream& os) const;
00143
00144 private:
00145
00146 DECLARE_OCTAVE_ALLOCATOR
00147
00148
00149 idx_colon_rep (const idx_colon_rep& idx);
00150 idx_colon_rep& operator = (const idx_colon_rep& idx);
00151 };
00152
00153
00154 enum direct { DIRECT };
00155
00156
00157 class OCTAVE_API idx_range_rep : public idx_base_rep
00158 {
00159 public:
00160 idx_range_rep (octave_idx_type _start, octave_idx_type _len,
00161 octave_idx_type _step, direct)
00162 : idx_base_rep (), start(_start), len(_len), step(_step) { }
00163
00164 idx_range_rep (void)
00165 : start(0), len(0), step(1) { }
00166
00167
00168 idx_range_rep (octave_idx_type _start, octave_idx_type _limit,
00169 octave_idx_type _step);
00170
00171 idx_range_rep (const Range&);
00172
00173 octave_idx_type xelem (octave_idx_type i) const
00174 { return start + i * step; }
00175
00176 octave_idx_type checkelem (octave_idx_type i) const;
00177
00178 octave_idx_type length (octave_idx_type) const { return len; }
00179
00180 octave_idx_type extent (octave_idx_type n) const
00181 { return len ? std::max (n, (start + 1 + (step < 0 ? 0 : step * (len - 1)))) : n; }
00182
00183 idx_class_type idx_class (void) const { return class_range; }
00184
00185 idx_base_rep *sort_uniq_clone (bool uniq = false);
00186
00187 idx_base_rep *sort_idx (Array<octave_idx_type>&);
00188
00189 bool is_colon_equiv (octave_idx_type n) const
00190 { return start == 0 && step == 1 && len == n; }
00191
00192 dim_vector orig_dimensions (void) const
00193 { return dim_vector (1, len); }
00194
00195 octave_idx_type get_start (void) const { return start; }
00196
00197 octave_idx_type get_step (void) const { return step; }
00198
00199 std::ostream& print (std::ostream& os) const;
00200
00201 Range unconvert (void) const;
00202
00203 Array<octave_idx_type> as_array (void);
00204
00205 private:
00206
00207 DECLARE_OCTAVE_ALLOCATOR
00208
00209
00210 idx_range_rep (const idx_range_rep& idx);
00211 idx_range_rep& operator = (const idx_range_rep& idx);
00212
00213 octave_idx_type start, len, step;
00214
00215 };
00216
00217
00218 class OCTAVE_API idx_scalar_rep : public idx_base_rep
00219 {
00220 public:
00221 idx_scalar_rep (octave_idx_type i, direct)
00222 : data (i) { }
00223
00224 idx_scalar_rep (void)
00225 : data (0) { }
00226
00227
00228 idx_scalar_rep (octave_idx_type i);
00229
00230 template <class T>
00231 idx_scalar_rep (T x);
00232
00233 octave_idx_type xelem (octave_idx_type) const { return data; }
00234
00235 octave_idx_type checkelem (octave_idx_type i) const;
00236
00237 octave_idx_type length (octave_idx_type) const { return 1; }
00238
00239 octave_idx_type extent (octave_idx_type n) const
00240 { return std::max (n, data + 1); }
00241
00242 idx_class_type idx_class (void) const { return class_scalar; }
00243
00244 idx_base_rep *sort_uniq_clone (bool = false)
00245 { count++; return this; }
00246
00247 idx_base_rep *sort_idx (Array<octave_idx_type>&);
00248
00249 bool is_colon_equiv (octave_idx_type n) const
00250 { return n == 1 && data == 0; }
00251
00252 dim_vector orig_dimensions (void) const { return dim_vector (1, 1); }
00253
00254 octave_idx_type get_data (void) const { return data; }
00255
00256 std::ostream& print (std::ostream& os) const;
00257
00258 double unconvert (void) const;
00259
00260 Array<octave_idx_type> as_array (void);
00261
00262 private:
00263
00264 DECLARE_OCTAVE_ALLOCATOR
00265
00266
00267 idx_scalar_rep (const idx_scalar_rep& idx);
00268 idx_scalar_rep& operator = (const idx_scalar_rep& idx);
00269
00270 octave_idx_type data;
00271
00272 };
00273
00274
00275 class OCTAVE_API idx_vector_rep : public idx_base_rep
00276 {
00277 public:
00278
00279 idx_vector_rep (octave_idx_type *_data, octave_idx_type _len,
00280 octave_idx_type _ext, const dim_vector& od, direct)
00281 : data (_data), len (_len), ext (_ext), aowner (0), orig_dims (od) { }
00282
00283 idx_vector_rep (void)
00284 : data (0), len (0), ext (0), aowner (0), orig_dims ()
00285 { }
00286
00287
00288 idx_vector_rep (const Array<octave_idx_type>& inda);
00289
00290 idx_vector_rep (const Array<octave_idx_type>& inda,
00291 octave_idx_type _ext, direct);
00292
00293 template <class T>
00294 idx_vector_rep (const Array<T>&);
00295
00296 idx_vector_rep (bool);
00297
00298 idx_vector_rep (const Array<bool>&, octave_idx_type = -1);
00299
00300 idx_vector_rep (const Sparse<bool>&);
00301
00302 ~idx_vector_rep (void);
00303
00304 octave_idx_type xelem (octave_idx_type i) const { return data[i]; }
00305
00306 octave_idx_type checkelem (octave_idx_type i) const;
00307
00308 octave_idx_type length (octave_idx_type) const { return len; }
00309
00310 octave_idx_type extent (octave_idx_type n) const
00311 { return std::max (n, ext); }
00312
00313 idx_class_type idx_class (void) const { return class_vector; }
00314
00315 idx_base_rep *sort_uniq_clone (bool uniq = false);
00316
00317 idx_base_rep *sort_idx (Array<octave_idx_type>&);
00318
00319 dim_vector orig_dimensions (void) const { return orig_dims; }
00320
00321 const octave_idx_type *get_data (void) const { return data; }
00322
00323 std::ostream& print (std::ostream& os) const;
00324
00325 Array<double> unconvert (void) const;
00326
00327 Array<octave_idx_type> as_array (void);
00328
00329 private:
00330
00331 DECLARE_OCTAVE_ALLOCATOR
00332
00333
00334 idx_vector_rep (const idx_vector_rep& idx);
00335 idx_vector_rep& operator = (const idx_vector_rep& idx);
00336
00337 const octave_idx_type *data;
00338 octave_idx_type len;
00339 octave_idx_type ext;
00340
00341
00342
00343
00344
00345
00346
00347
00348 Array<octave_idx_type> *aowner;
00349
00350 dim_vector orig_dims;
00351 };
00352
00353
00354 class OCTAVE_API idx_mask_rep : public idx_base_rep
00355 {
00356 public:
00357
00358 idx_mask_rep (bool *_data, octave_idx_type _len,
00359 octave_idx_type _ext, const dim_vector& od, direct)
00360 : data (_data), len (_len), ext (_ext), lsti (-1), lste (-1),
00361 aowner (0), orig_dims (od) { }
00362
00363 idx_mask_rep (void)
00364 : data (0), len (0), ext (0), lsti (-1), lste (-1), aowner (0),
00365 orig_dims ()
00366 { }
00367
00368 idx_mask_rep (bool);
00369
00370 idx_mask_rep (const Array<bool>&, octave_idx_type = -1);
00371
00372 ~idx_mask_rep (void);
00373
00374 octave_idx_type xelem (octave_idx_type i) const;
00375
00376 octave_idx_type checkelem (octave_idx_type i) const;
00377
00378 octave_idx_type length (octave_idx_type) const { return len; }
00379
00380 octave_idx_type extent (octave_idx_type n) const
00381 { return std::max (n, ext); }
00382
00383 idx_class_type idx_class (void) const { return class_mask; }
00384
00385 idx_base_rep *sort_uniq_clone (bool = false)
00386 { count++; return this; }
00387
00388 idx_base_rep *sort_idx (Array<octave_idx_type>&);
00389
00390 dim_vector orig_dimensions (void) const { return orig_dims; }
00391
00392 bool is_colon_equiv (octave_idx_type n) const
00393 { return len == n && ext == n; }
00394
00395 const bool *get_data (void) const { return data; }
00396
00397 std::ostream& print (std::ostream& os) const;
00398
00399 Array<bool> unconvert (void) const;
00400
00401 Array<octave_idx_type> as_array (void);
00402
00403 private:
00404
00405 DECLARE_OCTAVE_ALLOCATOR
00406
00407
00408 idx_mask_rep (const idx_mask_rep& idx);
00409 idx_mask_rep& operator = (const idx_mask_rep& idx);
00410
00411 const bool *data;
00412 octave_idx_type len;
00413 octave_idx_type ext;
00414
00415
00416
00417 mutable octave_idx_type lsti;
00418 mutable octave_idx_type lste;
00419
00420
00421
00422
00423
00424
00425
00426
00427 Array<bool> *aowner;
00428
00429 dim_vector orig_dims;
00430 };
00431
00432 idx_vector (idx_base_rep *r) : rep (r) { }
00433
00434
00435
00436 static idx_vector_rep *nil_rep (void)
00437 {
00438 static idx_vector_rep ivr;
00439 return &ivr;
00440 }
00441
00442
00443 static idx_vector_rep *err_rep (void)
00444 {
00445 static idx_vector_rep ivr;
00446 ivr.err = true;
00447 return &ivr;
00448 }
00449
00450
00451
00452 void chkerr (void)
00453 {
00454 if (rep->err)
00455 {
00456 if (--rep->count == 0)
00457 delete rep;
00458 rep = err_rep ();
00459 rep->count++;
00460 }
00461 }
00462
00463 public:
00464
00465
00466 idx_vector (void) : rep (nil_rep ()) { rep->count++; }
00467
00468
00469 idx_vector (octave_idx_type i) : rep (new idx_scalar_rep (i))
00470 { chkerr (); }
00471
00472 idx_vector (octave_idx_type start, octave_idx_type limit,
00473 octave_idx_type step = 1)
00474 : rep (new idx_range_rep (start, limit, step))
00475 { chkerr (); }
00476
00477 static idx_vector
00478 make_range (octave_idx_type start, octave_idx_type step,
00479 octave_idx_type len)
00480 {
00481 return idx_vector (new idx_range_rep (start, len, step, DIRECT));
00482 }
00483
00484 idx_vector (const Array<octave_idx_type>& inda)
00485 : rep (new idx_vector_rep (inda))
00486 { chkerr (); }
00487
00488
00489 idx_vector (const Array<octave_idx_type>& inda, octave_idx_type ext)
00490 : rep (new idx_vector_rep (inda, ext, DIRECT))
00491 { }
00492
00493
00494 static const idx_vector colon;
00495
00496
00497 idx_vector (char c) : rep (new idx_colon_rep (c)) { chkerr (); }
00498
00499
00500
00501 template <class T>
00502 idx_vector (octave_int<T> x) : rep (new idx_scalar_rep (x)) { chkerr (); }
00503
00504 idx_vector (double x) : rep (new idx_scalar_rep (x)) { chkerr (); }
00505
00506 idx_vector (float x) : rep (new idx_scalar_rep (x)) { chkerr (); }
00507
00508
00509 idx_vector (bool x) : rep (new idx_mask_rep (x)) { chkerr (); }
00510
00511 template <class T>
00512 idx_vector (const Array<octave_int<T> >& nda) : rep (new idx_vector_rep (nda))
00513 { chkerr (); }
00514
00515 idx_vector (const Array<double>& nda) : rep (new idx_vector_rep (nda))
00516 { chkerr (); }
00517
00518 idx_vector (const Array<float>& nda) : rep (new idx_vector_rep (nda))
00519 { chkerr (); }
00520
00521 idx_vector (const Array<bool>& nda);
00522
00523 idx_vector (const Range& r)
00524 : rep (new idx_range_rep (r))
00525 { chkerr (); }
00526
00527 idx_vector (const Sparse<bool>& nda) : rep (new idx_vector_rep (nda))
00528 { chkerr (); }
00529
00530 idx_vector (const idx_vector& a) : rep (a.rep) { rep->count++; }
00531
00532 ~idx_vector (void)
00533 {
00534 if (--rep->count == 0)
00535 delete rep;
00536 }
00537
00538 idx_vector& operator = (const idx_vector& a)
00539 {
00540 if (this != &a)
00541 {
00542 if (--rep->count == 0)
00543 delete rep;
00544
00545 rep = a.rep;
00546 rep->count++;
00547 }
00548 return *this;
00549 }
00550
00551 idx_class_type idx_class (void) const { return rep->idx_class (); }
00552
00553 octave_idx_type length (octave_idx_type n = 0) const
00554 { return rep->length (n); }
00555
00556 octave_idx_type extent (octave_idx_type n) const
00557 { return rep->extent (n); }
00558
00559 octave_idx_type xelem (octave_idx_type n) const
00560 { return rep->xelem (n); }
00561
00562 octave_idx_type checkelem (octave_idx_type n) const
00563 { return rep->checkelem (n); }
00564
00565 octave_idx_type operator () (octave_idx_type n) const
00566 {
00567 #if defined (BOUNDS_CHECKING)
00568 return rep->checkelem (n);
00569 #else
00570 return rep->xelem (n);
00571 #endif
00572 }
00573
00574 operator bool (void) const
00575 { return ! rep->err; }
00576
00577 bool is_colon (void) const
00578 { return rep->idx_class () == class_colon; }
00579
00580 bool is_scalar (void) const
00581 { return rep->idx_class () == class_scalar; }
00582
00583 bool is_range (void) const
00584 { return rep->idx_class () == class_range; }
00585
00586 bool is_colon_equiv (octave_idx_type n) const
00587 { return rep->is_colon_equiv (n); }
00588
00589 idx_vector sorted (bool uniq = false) const
00590 { return idx_vector (rep->sort_uniq_clone (uniq)); }
00591
00592 idx_vector sorted (Array<octave_idx_type>& sidx) const
00593 { return idx_vector (rep->sort_idx (sidx)); }
00594
00595 dim_vector orig_dimensions (void) const { return rep->orig_dimensions (); }
00596
00597 octave_idx_type orig_rows (void) const
00598 { return orig_dimensions () (0); }
00599
00600 octave_idx_type orig_columns (void) const
00601 { return orig_dimensions () (1); }
00602
00603 int orig_empty (void) const
00604 { return (! is_colon () && orig_dimensions().any_zero ()); }
00605
00606
00607
00608 std::ostream& print (std::ostream& os) const { return rep->print (os); }
00609
00610 friend std::ostream& operator << (std::ostream& os, const idx_vector& a)
00611 { return a.print (os); }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 template <class T>
00622 octave_idx_type
00623 index (const T *src, octave_idx_type n, T *dest) const
00624 {
00625 octave_idx_type len = rep->length (n);
00626
00627 switch (rep->idx_class ())
00628 {
00629 case class_colon:
00630 copy_or_memcpy (len, src, dest);
00631 break;
00632
00633 case class_range:
00634 {
00635 idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
00636 octave_idx_type start = r->get_start (), step = r->get_step ();
00637 const T *ssrc = src + start;
00638 if (step == 1)
00639 copy_or_memcpy (len, ssrc, dest);
00640 else if (step == -1)
00641 std::reverse_copy (ssrc - len + 1, ssrc + 1, dest);
00642 else if (step == 0)
00643 std::fill_n (dest, len, *ssrc);
00644 else
00645 {
00646 for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
00647 dest[i] = ssrc[j];
00648 }
00649 }
00650 break;
00651
00652 case class_scalar:
00653 {
00654 idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
00655 dest[0] = src[r->get_data ()];
00656 }
00657 break;
00658
00659 case class_vector:
00660 {
00661 idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
00662 const octave_idx_type *data = r->get_data ();
00663 for (octave_idx_type i = 0; i < len; i++)
00664 dest[i] = src[data[i]];
00665 }
00666 break;
00667
00668 case class_mask:
00669 {
00670 idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
00671 const bool *data = r->get_data ();
00672 octave_idx_type ext = r->extent (0);
00673 for (octave_idx_type i = 0; i < ext; i++)
00674 if (data[i]) *dest++ = src[i];
00675 }
00676 break;
00677
00678 default:
00679 assert (false);
00680 break;
00681 }
00682
00683 return len;
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 template <class T>
00695 octave_idx_type
00696 assign (const T *src, octave_idx_type n, T *dest) const
00697 {
00698 octave_idx_type len = rep->length (n);
00699
00700 switch (rep->idx_class ())
00701 {
00702 case class_colon:
00703 copy_or_memcpy (len, src, dest);
00704 break;
00705
00706 case class_range:
00707 {
00708 idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
00709 octave_idx_type start = r->get_start (), step = r->get_step ();
00710 T *sdest = dest + start;
00711 if (step == 1)
00712 copy_or_memcpy (len, src, sdest);
00713 else if (step == -1)
00714 std::reverse_copy (src, src + len, sdest - len + 1);
00715 else
00716 {
00717 for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
00718 sdest[j] = src[i];
00719 }
00720 }
00721 break;
00722
00723 case class_scalar:
00724 {
00725 idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
00726 dest[r->get_data ()] = src[0];
00727 }
00728 break;
00729
00730 case class_vector:
00731 {
00732 idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
00733 const octave_idx_type *data = r->get_data ();
00734 for (octave_idx_type i = 0; i < len; i++)
00735 dest[data[i]] = src[i];
00736 }
00737 break;
00738
00739 case class_mask:
00740 {
00741 idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
00742 const bool *data = r->get_data ();
00743 octave_idx_type ext = r->extent (0);
00744 for (octave_idx_type i = 0; i < ext; i++)
00745 if (data[i]) dest[i] = *src++;
00746 }
00747 break;
00748
00749 default:
00750 assert (false);
00751 break;
00752 }
00753
00754 return len;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 template <class T>
00766 octave_idx_type
00767 fill (const T& val, octave_idx_type n, T *dest) const
00768 {
00769 octave_idx_type len = rep->length (n);
00770
00771 switch (rep->idx_class ())
00772 {
00773 case class_colon:
00774 std::fill (dest, dest + len, val);
00775 break;
00776
00777 case class_range:
00778 {
00779 idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
00780 octave_idx_type start = r->get_start (), step = r->get_step ();
00781 T *sdest = dest + start;
00782 if (step == 1)
00783 std::fill (sdest, sdest + len, val);
00784 else if (step == -1)
00785 std::fill (sdest - len + 1, sdest + 1, val);
00786 else
00787 {
00788 for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
00789 sdest[j] = val;
00790 }
00791 }
00792 break;
00793
00794 case class_scalar:
00795 {
00796 idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
00797 dest[r->get_data ()] = val;
00798 }
00799 break;
00800
00801 case class_vector:
00802 {
00803 idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
00804 const octave_idx_type *data = r->get_data ();
00805 for (octave_idx_type i = 0; i < len; i++)
00806 dest[data[i]] = val;
00807 }
00808 break;
00809
00810 case class_mask:
00811 {
00812 idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
00813 const bool *data = r->get_data ();
00814 octave_idx_type ext = r->extent (0);
00815 for (octave_idx_type i = 0; i < ext; i++)
00816 if (data[i]) dest[i] = val;
00817 }
00818 break;
00819
00820 default:
00821 assert (false);
00822 break;
00823 }
00824
00825 return len;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 template <class Functor>
00835 void
00836 loop (octave_idx_type n, Functor body) const
00837 {
00838 octave_idx_type len = rep->length (n);
00839
00840 switch (rep->idx_class ())
00841 {
00842 case class_colon:
00843 for (octave_idx_type i = 0; i < len; i++) body (i);
00844 break;
00845
00846 case class_range:
00847 {
00848 idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
00849 octave_idx_type start = r->get_start (), step = r->get_step ();
00850 octave_idx_type i, j;
00851 if (step == 1)
00852 for (i = start, j = start + len; i < j; i++) body (i);
00853 else if (step == -1)
00854 for (i = start, j = start - len; i > j; i--) body (i);
00855 else
00856 for (i = 0, j = start; i < len; i++, j += step) body (j);
00857 }
00858 break;
00859
00860 case class_scalar:
00861 {
00862 idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
00863 body (r->get_data ());
00864 }
00865 break;
00866
00867 case class_vector:
00868 {
00869 idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
00870 const octave_idx_type *data = r->get_data ();
00871 for (octave_idx_type i = 0; i < len; i++) body (data[i]);
00872 }
00873 break;
00874
00875 case class_mask:
00876 {
00877 idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
00878 const bool *data = r->get_data ();
00879 octave_idx_type ext = r->extent (0);
00880 for (octave_idx_type i = 0; i < ext; i++)
00881 if (data[i]) body (i);
00882 }
00883 break;
00884
00885 default:
00886 assert (false);
00887 break;
00888 }
00889
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 template <class Functor>
00902 octave_idx_type
00903 bloop (octave_idx_type n, Functor body) const
00904 {
00905 octave_idx_type len = rep->length (n), ret;
00906
00907 switch (rep->idx_class ())
00908 {
00909 case class_colon:
00910 {
00911 octave_idx_type i;
00912 for (i = 0; i < len && body (i); i++) ;
00913 ret = i;
00914 }
00915 break;
00916
00917 case class_range:
00918 {
00919 idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
00920 octave_idx_type start = r->get_start (), step = r->get_step ();
00921 octave_idx_type i, j;
00922 if (step == 1)
00923 for (i = start, j = start + len; i < j && body (i); i++) ;
00924 else if (step == -1)
00925 for (i = start, j = start - len; i > j && body (i); i--) ;
00926 else
00927 for (i = 0, j = start; i < len && body (j); i++, j += step) ;
00928 ret = i;
00929 }
00930 break;
00931
00932 case class_scalar:
00933 {
00934 idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
00935 ret = body (r->get_data ()) ? 1 : 0;
00936 }
00937 break;
00938
00939 case class_vector:
00940 {
00941 idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
00942 const octave_idx_type *data = r->get_data ();
00943 octave_idx_type i;
00944 for (i = 0; i < len && body (data[i]); i++) ;
00945 ret = i;
00946 }
00947 break;
00948
00949 case class_mask:
00950 {
00951 idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
00952 const bool *data = r->get_data ();
00953 octave_idx_type ext = r->extent (0), j = 0;
00954 for (octave_idx_type i = 0; i < ext; i++)
00955 {
00956 if (data[i])
00957 {
00958 if (body (i))
00959 break;
00960 else
00961 j++;
00962 }
00963 }
00964
00965 ret = j;
00966 }
00967 break;
00968
00969 default:
00970 assert (false);
00971 break;
00972 }
00973
00974 return ret;
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984 bool maybe_reduce (octave_idx_type n, const idx_vector& j,
00985 octave_idx_type nj);
00986
00987 bool is_cont_range (octave_idx_type n,
00988 octave_idx_type& l, octave_idx_type& u) const;
00989
00990
00991
00992 octave_idx_type increment (void) const;
00993
00994 idx_vector
00995 complement (octave_idx_type n) const;
00996
00997 bool is_permutation (octave_idx_type n) const;
00998
00999
01000
01001 idx_vector inverse_permutation (octave_idx_type n) const;
01002
01003
01004 void copy_data (octave_idx_type *data) const;
01005
01006
01007 idx_vector unmask (void) const;
01008
01009
01010 void unconvert (idx_class_type& iclass,
01011 double& scalar, Range& range,
01012 Array<double>& array, Array<bool>& mask) const;
01013
01014 Array<octave_idx_type> as_array (void) const;
01015
01016
01017
01018 const octave_idx_type *raw (void);
01019
01020 bool is_vector (void) const;
01021
01022
01023
01024
01025 octave_idx_type elem (octave_idx_type n) const
01026 { return (*this) (n); }
01027
01028 bool is_colon_equiv (octave_idx_type n, int) const
01029 { return is_colon_equiv (n); }
01030
01031 octave_idx_type
01032 freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false);
01033
01034 void sort (bool uniq = false)
01035 { *this = sorted (uniq); }
01036
01037 octave_idx_type ones_count (void) const;
01038
01039 octave_idx_type max (void) const { return extent (1) - 1; }
01040
01041 private:
01042
01043 idx_base_rep *rep;
01044
01045 };
01046
01047 #endif