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