71 template <
typename T,
typename D>
friend class std::unique_ptr;
79 idx_base_rep () : m_count (1) { }
81 OCTAVE_DISABLE_COPY_MOVE (idx_base_rep)
83 virtual ~idx_base_rep () =
default;
98 virtual idx_class_type idx_class ()
const {
return class_invalid; }
101 virtual idx_base_rep * sort_uniq_clone (
bool uniq =
false) = 0;
112 virtual std::ostream& print (std::ostream& os)
const = 0;
120 class OCTAVE_API idx_colon_rep :
public idx_base_rep
124 idx_colon_rep () =
default;
128 OCTAVE_DISABLE_COPY_MOVE (idx_colon_rep)
130 ~idx_colon_rep () =
default;
140 idx_class_type idx_class ()
const {
return class_colon; }
142 idx_base_rep * sort_uniq_clone (
bool =
false)
143 { m_count++;
return this; }
149 OCTAVE_API std::ostream& print (std::ostream& os)
const;
153 enum direct { DIRECT };
156 class OCTAVE_API idx_range_rep :
public idx_base_rep
160 idx_range_rep () =
delete;
164 : idx_base_rep (), m_start (start), m_len (
len), m_step (step) { }
173 OCTAVE_DISABLE_COPY_MOVE (idx_range_rep)
175 ~idx_range_rep () =
default;
178 {
return m_start + i * m_step; }
186 return m_len ? std::max (n, m_start + 1 + (m_step < 0 ? 0 : m_step * (m_len - 1))) : n;
189 idx_class_type idx_class ()
const {
return class_range; }
191 OCTAVE_API idx_base_rep * sort_uniq_clone (
bool uniq =
false);
196 {
return m_start == 0 && m_step == 1 && m_len == n; }
205 OCTAVE_API std::ostream& print (std::ostream& os)
const;
217 class OCTAVE_API idx_scalar_rep :
public idx_base_rep
221 idx_scalar_rep () =
delete;
223 idx_scalar_rep (
octave_idx_type i, direct) : idx_base_rep (), m_data (i) { }
225 OCTAVE_DISABLE_COPY_MOVE (idx_scalar_rep)
227 ~idx_scalar_rep () =
default;
232 template <
typename T>
233 idx_scalar_rep (T
x);
242 {
return std::max (n, m_data + 1); }
244 idx_class_type idx_class ()
const {
return class_scalar; }
246 idx_base_rep * sort_uniq_clone (
bool =
false)
247 { m_count++;
return this; }
252 {
return n == 1 && m_data == 0; }
258 OCTAVE_API std::ostream& print (std::ostream& os)
const;
270 class OCTAVE_API idx_vector_rep :
public idx_base_rep
275 : m_data (nullptr), m_len (0), m_ext (0), m_aowner (nullptr), m_orig_dims () { }
280 : idx_base_rep (), m_data (data), m_len (
len), m_ext (ext),
281 m_aowner (nullptr), m_orig_dims (od)
290 template <
typename T>
299 OCTAVE_DISABLE_COPY_MOVE (idx_vector_rep)
310 {
return std::max (n, m_ext); }
312 idx_class_type idx_class ()
const {
return class_vector; }
314 idx_base_rep * sort_uniq_clone (
bool uniq =
false);
318 dim_vector orig_dimensions ()
const {
return m_orig_dims; }
322 OCTAVE_API std::ostream& print (std::ostream& os)
const;
347 class OCTAVE_API idx_mask_rep :
public idx_base_rep
351 idx_mask_rep () =
delete;
356 : idx_base_rep (), m_data (data), m_len (
len), m_ext (ext),
357 m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (od)
364 OCTAVE_DISABLE_COPY_MOVE (idx_mask_rep)
375 {
return std::max (n, m_ext); }
377 idx_class_type idx_class ()
const {
return class_mask; }
379 idx_base_rep * sort_uniq_clone (
bool =
false)
380 { m_count++;
return this; }
384 dim_vector orig_dimensions ()
const {
return m_orig_dims; }
387 {
return m_len == n && m_ext == n; }
389 const bool * get_data ()
const {
return m_data; }
391 OCTAVE_API std::ostream& print (std::ostream& os)
const;
424 static OCTAVE_API idx_vector_rep * nil_rep ();
434#if OCTAVE_SIZEOF_INT != OCTAVE_SIZEOF_IDX_TYPE
439#if (OCTAVE_SIZEOF_F77_INT_TYPE != OCTAVE_SIZEOF_IDX_TYPE \
440 && OCTAVE_SIZEOF_F77_INT_TYPE != OCTAVE_SIZEOF_INT)
447 : m_rep (new idx_range_rep (start, limit, step)) { }
453 return idx_vector (
new idx_range_rep (start,
len, step, DIRECT));
457 : m_rep (new idx_vector_rep (inda)) { }
461 : m_rep (new idx_vector_rep (inda, ext, DIRECT)) { }
471 template <
typename T>
481 template <
typename T>
483 : m_rep (new idx_vector_rep (nda)) { }
499 if (--m_rep->m_count == 0 && m_rep != nil_rep ())
507 if (--m_rep->m_count == 0 && m_rep != nil_rep ())
519 {
return m_rep->length (n); }
522 {
return m_rep->extent (n); }
525 {
return m_rep->xelem (n); }
528 {
return m_rep->xelem (n); }
531 {
return m_rep->xelem (n); }
535 OCTAVE_DEPRECATED (9,
"idx_vector::bool () is obsolete and always returns true")
536 operator
bool ()
const {
return true; }
539 {
return m_rep->idx_class () == class_colon; }
542 {
return m_rep->idx_class () == class_scalar; }
545 {
return m_rep->idx_class () == class_range; }
548 {
return m_rep->is_colon_equiv (n); }
551 {
return idx_vector (m_rep->sort_uniq_clone (uniq)); }
554 {
return idx_vector (m_rep->sort_idx (sidx)); }
559 {
return orig_dimensions () (0); }
562 {
return orig_dimensions () (1); }
565 {
return (! is_colon () && orig_dimensions ().any_zero ()); }
569 std::ostream&
print (std::ostream& os)
const {
return m_rep->print (os); }
572 {
return a.
print (os); }
582 template <
typename T>
588 switch (m_rep->idx_class ())
591 (*current_liboctave_error_handler) (
"unexpected: invalid index");
595 std::copy_n (src,
len, dest);
600 idx_range_rep *r =
dynamic_cast<idx_range_rep *
> (m_rep);
603 const T *ssrc = src + start;
605 std::copy_n (ssrc,
len, dest);
607 std::reverse_copy (ssrc -
len + 1, ssrc + 1, dest);
609 std::fill_n (dest,
len, *ssrc);
620 idx_scalar_rep *r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
621 dest[0] = src[r->get_data ()];
627 idx_vector_rep *r =
dynamic_cast<idx_vector_rep *
> (m_rep);
630 dest[i] = src[data[i]];
636 idx_mask_rep *r =
dynamic_cast<idx_mask_rep *
> (m_rep);
637 const bool *data = r->get_data ();
640 if (data[i]) *dest++ = src[i];
661 template <
typename T>
667 switch (m_rep->idx_class ())
670 (*current_liboctave_error_handler) (
"unexpected: invalid index");
674 std::copy_n (src,
len, dest);
679 idx_range_rep *r =
dynamic_cast<idx_range_rep *
> (m_rep);
682 T *sdest = dest + start;
684 std::copy_n (src,
len, sdest);
686 std::reverse_copy (src, src +
len, sdest -
len + 1);
697 idx_scalar_rep *r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
698 dest[r->get_data ()] = src[0];
704 idx_vector_rep *r =
dynamic_cast<idx_vector_rep *
> (m_rep);
707 dest[data[i]] = src[i];
713 idx_mask_rep *r =
dynamic_cast<idx_mask_rep *
> (m_rep);
714 const bool *data = r->get_data ();
717 if (data[i]) dest[i] = *src++;
738 template <
typename T>
744 switch (m_rep->idx_class ())
747 (*current_liboctave_error_handler) (
"unexpected: invalid index");
751 std::fill_n (dest,
len, val);
756 idx_range_rep *r =
dynamic_cast<idx_range_rep *
> (m_rep);
759 T *sdest = dest + start;
761 std::fill_n (sdest,
len, val);
763 std::fill (sdest -
len + 1, sdest + 1, val);
774 idx_scalar_rep *r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
775 dest[r->get_data ()] = val;
781 idx_vector_rep *r =
dynamic_cast<idx_vector_rep *
> (m_rep);
790 idx_mask_rep *r =
dynamic_cast<idx_mask_rep *
> (m_rep);
791 const bool *data = r->get_data ();
794 if (data[i]) dest[i] = val;
813 template <
typename Functor>
819 switch (m_rep->idx_class ())
822 (*current_liboctave_error_handler) (
"unexpected: invalid index");
831 idx_range_rep *r =
dynamic_cast<idx_range_rep *
> (m_rep);
836 for (i = start, j = start +
len; i < j; i++) body (i);
838 for (i = start, j = start -
len; i > j; i--) body (i);
840 for (i = 0, j = start; i <
len; i++, j += step) body (j);
846 idx_scalar_rep *r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
847 body (r->get_data ());
853 idx_vector_rep *r =
dynamic_cast<idx_vector_rep *
> (m_rep);
861 idx_mask_rep *r =
dynamic_cast<idx_mask_rep *
> (m_rep);
862 const bool *data = r->get_data ();
865 if (data[i]) body (i);
886 template <
typename Functor>
892 switch (m_rep->idx_class ())
895 (*current_liboctave_error_handler) (
"unexpected: invalid index");
901 for (i = 0; i <
len && body (i); i++) ;
908 idx_range_rep *r =
dynamic_cast<idx_range_rep *
> (m_rep);
913 for (i = start, j = start +
len; i < j && body (i); i++) ;
915 for (i = start, j = start -
len; i > j && body (i); i--) ;
917 for (i = 0, j = start; i <
len && body (j); i++, j += step) ;
924 idx_scalar_rep *r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
925 ret = (body (r->get_data ()) ? 1 : 0);
931 idx_vector_rep *r =
dynamic_cast<idx_vector_rep *
> (m_rep);
934 for (i = 0; i <
len && body (data[i]); i++) ;
941 idx_mask_rep *r =
dynamic_cast<idx_mask_rep *
> (m_rep);
942 const bool *data = r->get_data ();
1019 {
return (*
this) (n); }
1022 {
return is_colon_equiv (n); }
1028 { *
this = sorted (uniq); }
1036 idx_base_rep *m_rep;